Error de un punto

Error lógico que a menudo se puede encontrar en la programación.

Un error de uno o error de uno (conocido por las siglas OBOE , OBO , OB1 y OBOB ) es un error lógico que involucra un número que difiere de su valor deseado en +1 o −1. Un error de uno puede aparecer a veces en un contexto matemático . Suele ocurrir en la programación informática cuando un bucle se repite una vez de más o de menos, generalmente causado por el uso de una desigualdad no estricta (≤) como condición de terminación donde se debería haber usado una desigualdad estricta (<), o viceversa. Los errores de uno también surgen de la confusión sobre la numeración basada en cero .

Casos

Recorriendo arreglos en bucle

Considere una matriz de elementos y se deben procesar elementos m a n (incluidos). ¿Cuántos elementos hay? Una respuesta intuitiva puede ser nm , pero está desfasada por un valor de uno, lo que muestra un error de tipo poste de cerca; la respuesta correcta es nm + 1 .

Por esta razón, los rangos en computación se representan a menudo mediante intervalos semiabiertos ; el rango de m a n (inclusive) se representa mediante el rango de m (inclusive) a n + 1 (exclusivo) para evitar errores de vallado. Por ejemplo, un bucle que se repite cinco veces (de 0 a 4 inclusive) se puede escribir como un intervalo semiabierto de 0 a 5:

for ( index = 0 ; index < 5 ; index ++ ) { /* Cuerpo del bucle */ }         

El cuerpo del bucle se ejecuta primero con índice igual a 0; luego, índice se convierte en 1, 2, 3 y, finalmente, 4 en iteraciones sucesivas. En ese punto, índice se convierte en 5, por lo que índice < 5 es falso y el bucle termina. Sin embargo, si la comparación utilizada fuera <= (menor o igual a), el bucle se llevaría a cabo seis veces: índice toma los valores 0, 1, 2, 3, 4 y 5. Del mismo modo, si índice se inicializara en 1 en lugar de 0, solo habría cuatro iteraciones: índice toma los valores 1, 2, 3 y 4. Ambas alternativas pueden causar errores de desfase de uno.

Otro error de este tipo puede ocurrir si se utiliza un bucle do-while en lugar de un bucle while (o viceversa). Se garantiza que un bucle do-while se ejecutará al menos una vez.

La confusión relacionada con las matrices también puede deberse a diferencias entre los lenguajes de programación. La numeración a partir de 0 es la más común, pero algunos lenguajes comienzan la numeración de matrices con 1. Pascal tiene matrices con índices definidos por el usuario. Esto permite modelar los índices de la matriz según el dominio del problema.

Error en el poste de cerca

Un error de poste de cerca (a veces llamado error de poste de telégrafo, poste de luz o error de cerca de estacas ) es un tipo específico de error de un punto. Una descripción temprana de este error aparece en las obras de Vitruvio . [1] El siguiente problema ilustra el error:

Si construyes una cerca recta de 30 pies de largo con postes espaciados a 3 pies de distancia, ¿cuántos postes necesitas?

Una cerca recta con 10 secciones requiere 11 postes. En términos más generales, n secciones requerirían n + 1 postes.

La respuesta habitual de 10 postes es incorrecta. Esta respuesta se obtiene dividiendo la longitud de la cerca por la distancia entre cada poste, y el cociente se clasifica erróneamente como el número de postes. En realidad, la cerca tiene 10 secciones y 11 postes.

En este escenario, una cerca con n secciones tendrá n + 1 postes. Por el contrario, si la cerca contiene n postes, contendrá n − 1 secciones. Es importante tener en cuenta esta relación cuando se trata del error inverso. El error inverso ocurre cuando se conoce el número de postes y se supone que el número de secciones es el mismo. Dependiendo del diseño de la cerca, esta suposición puede ser correcta o incorrecta.

El siguiente problema demuestra el error inverso:

Si tienes n publicaciones, ¿cuántas secciones hay entre ellas?

La interpretación del diseño de la cerca cambia la respuesta a este problema. El número correcto de secciones para una cerca es n − 1 si la cerca es un segmento lineal independiente delimitado por un poste en cada uno de sus extremos (por ejemplo, una cerca entre dos huecos de paso), n si la cerca forma un bucle completo e independiente (por ejemplo, un recinto accesible por encima, como un cuadrilátero de boxeo), o n + 1 si no hay postes en los extremos de una cerca similar a un segmento lineal (por ejemplo, una cerca entre dos edificios anclados a una pared). La definición precisa del problema debe considerarse cuidadosamente, ya que la configuración para una situación puede dar la respuesta incorrecta para otras situaciones. Los errores de postes de cerca se producen al contar cosas en lugar de los espacios entre ellas, o viceversa, o al descuidar la consideración de si se deben contar uno o ambos extremos de una fila.

Los errores de los postes de cerca también pueden ocurrir en unidades distintas de la longitud. Por ejemplo, la Pirámide del Tiempo , que consta de 120 bloques colocados a intervalos de 10 años entre bloques, está programada para tardar 1.190 años en construirse (no 1.200), desde la instalación del primer bloque hasta el último bloque. Uno de los primeros errores de los postes de cerca estaba relacionado con el tiempo, ya que el calendario juliano originalmente calculaba incorrectamente los años bisiestos , debido a que contaba de manera inclusiva en lugar de exclusiva, lo que daba como resultado un año bisiesto cada tres años en lugar de cada cuatro.

"Fencepost error" can, in rare occasions, refer to an error induced by unexpected regularities in input values,[2] which can (for instance) completely thwart a theoretically efficient binary tree or hash function implementation. This error involves the difference between expected and worst case behaviours of an algorithm.

En números grandes, equivocarse en un punto no suele ser un problema importante. Sin embargo, en números más pequeños y en casos específicos en los que la precisión es primordial, cometer un error de un punto puede ser desastroso. A veces, este problema también se repetirá y, por lo tanto, se agravará si alguien pasa un cálculo incorrecto y la siguiente persona vuelve a cometer el mismo tipo de error (por supuesto, el error también puede revertirse).

Un ejemplo de este error puede ocurrir en el lenguaje computacional MATLAB con la función linspace() de interpolación lineal , cuyos parámetros son y no . Un programador que malinterprete que el tercer parámetro es el número de incrementos podría esperar lograr una secuencia pero en cambio obtendría .(lower value, upper value, number of values)(lower value, upper value, number of increments)linspace(0,10,5)[0, 2, 4, 6, 8, 10][0, 2.5, 5, 7.5, 10]

Implicaciones de seguridad

Un error común de un byte que da como resultado un error relacionado con la seguridad es causado por el uso incorrecto de la rutina de la biblioteca estándar de C. Un error común es creer que la terminación nula garantizada no escribirá más allá de la longitud máxima. En realidad, escribirá un carácter nulo de terminación un byte más allá de la longitud máxima especificada. El siguiente código contiene un error de este tipo:strncatstrncat

void foo ( char * s ) { char buf [ 15 ]; memset ( buf , 0 , sizeof ( buf )); strncat ( buf , s , sizeof ( buf )); // El parámetro final debe ser: sizeof(buf)-1 }             

Los errores de desfase de un byte son comunes al usar la biblioteca C porque no es consistente con respecto a si uno necesita restar 1 byte: funciones como fgets()y strncpynunca escribirán más allá de la longitud que se les da ( fgets()resta 1 y solo recupera (longitud − 1) bytes), mientras que otras, como strncatescribirán más allá de la longitud que se les da. Por lo tanto, el programador tiene que recordar para qué funciones necesita restar 1.

En algunos sistemas ( en particular, arquitecturas little endian ), esto puede provocar la sobrescritura del byte menos significativo del puntero de trama . Esto puede provocar una condición explotable en la que un atacante puede secuestrar las variables locales para la rutina de llamada.

Un enfoque que a menudo ayuda a evitar estos problemas es utilizar variantes de estas funciones que calculan cuánto escribir en función de la longitud total del búfer, en lugar de la cantidad máxima de caracteres a escribir. Estas funciones incluyen strlcaty strlcpy, y a menudo se consideran "más seguras" porque facilitan evitar escribir accidentalmente más allá del final de un búfer. (En el ejemplo de código anterior, llamar a strlcat(buf, s, sizeof(buf))en su lugar eliminaría el error).

Véase también

Referencias

Citas

  1. ^ Moniot, Robert K., ¿Quién describió por primera vez el "error del poste de la cerca?", Fordham University , archivado desde el original el 5 de marzo de 2016 , consultado el 7 de julio de 2016.
  2. ^ Raymond, Eric. "The Jargon File" (El archivo de la jerga) . Consultado el 17 de mayo de 2021 .

Fuentes

  • Una versión anterior de este artículo se basó en un error de poste de cerca en FOLDOC, utilizado con permiso .
  • Dijkstra, Edsger Wybe (2 de mayo de 2008). "Por qué la numeración debería empezar en cero (EWD 831)". Archivo EW Dijkstra . Universidad de Texas en Austin . Consultado el 16 de marzo de 2011 .
  • En el sistema de enumeración de debilidades comunes, este problema aparece como CWE-193: Error de un dígito desfasado

Lectura adicional

  • Parker, Matt (2021). Humble Pi: Cuando las matemáticas salen mal en el mundo real . Riverhead Books. ISBN 978-0593084694.
Retrieved from "https://en.wikipedia.org/w/index.php?title=Off-by-one_error&oldid=1251113876#Fencepost_error"