Un error de uno por uno o un error de uno por uno (conocido por las siglas OBOE , OBO , OB1 y OBOB ) es un error lógico que involucra el equivalente discreto de una condición de límite . A menudo ocurre en la programación de computadoras cuando un ciclo iterativo itera una vez demasiadas o muy pocas. Este problema podría surgir cuando un programador comete errores tales como usar "es menor o igual que" donde "es menor que" debería haberse usado en una comparación, o no toma en cuenta que una secuencia comienza en cero en lugar de uno ( como con los índices de matriz en muchos idiomas). Esto también puede ocurrir en uncontexto matemático .
Bucle sobre matrices
Considere una matriz de elementos, y los elementos m hasta n (inclusive) deben procesarse. ¿Cuántos artículos hay? Una respuesta intuitiva puede ser n - m , pero está desviada en uno, mostrando un error en el poste de la cerca ; la respuesta correcta es ( n - m ) + 1.
Por esta razón, los rangos en computación a menudo se representan mediante intervalos semiabiertos ; el rango de m a n (inclusive) está representado por el rango de m (inclusive) a n + 1 (exclusivo) para evitar errores en los postes de la cerca. 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 en primer lugar con un índice igual a 0; el índice luego se convierte en 1, 2, 3 y finalmente 4 en iteraciones sucesivas. En ese punto, el índice se convierte en 5, por lo que index <5 es falso y el ciclo termina. Sin embargo, si la comparación utilizada fuera < or = (menor o igual a), el bucle se realizaría seis veces: El índice toma los valores 0, 1, 2, 3, 4 y 5. Del mismo modo, si index se inicializaran a 1 en lugar de 0, solo habría cuatro iteraciones: El índice toma los valores 1, 2, 3 y 4. Ambas alternativas pueden causar errores uno por uno.
Otro error de este tipo puede ocurrir si se usa 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 en los lenguajes de programación. La numeración desde 0 es 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 hace posible modelar los índices de la matriz después del dominio del problema.
Error de poste de valla
Un error de poste de cerca (ocasionalmente llamado error de poste de telégrafo, poste de luz o cerca de estacas ) es un tipo específico de error de uno por uno. Una descripción temprana de este error aparece en las obras de Vitruvio . [1] El siguiente problema ilustra el error:
Si construye una cerca recta de 30 metros de largo con postes separados por 3 metros, ¿cuántos postes necesita?
La ingenua respuesta 10 es incorrecta. La cerca tiene 10 secciones, pero 11 postes.
El error inverso ocurre cuando se conoce el número de publicaciones y se supone que el número de secciones es el mismo. El número real de secciones es uno menos que el número de publicaciones.
De manera más general, el problema se puede plantear de la siguiente manera:
Si tiene n publicaciones, ¿cuántas secciones hay entre ellas?
La respuesta correcta puede ser n - 1 si la línea de postes es abierta, n si forman un bucle, o n + 1 si los postes no se encuentran al final de la cerca (por ejemplo, si la cerca pasa entre dos paredes). La definición precisa del problema debe considerarse cuidadosamente, ya que la configuración para una situación puede dar una respuesta incorrecta para otras situaciones. Los errores de los postes de valla provienen de contar cosas en lugar de los espacios entre ellas, o viceversa, o de no considerar si uno debe 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 en intervalos de 10 años entre bloques, está programado para construir 1,190 años (no 1,200), desde la instalación del primer bloque hasta el último bloque. Uno de los primeros errores en los postes de la cerca involucró el tiempo, donde el calendario juliano originalmente calculó los años bisiestos de manera incorrecta , debido a que contaba de manera inclusiva en lugar de exclusivamente, lo que arroja un año bisiesto cada tres años en lugar de cada cuatro.
El "error de poste de valla" puede, en raras ocasiones, referirse a un error inducido por regularidades inesperadas en los valores de entrada, [2] que pueden (por ejemplo) frustrar completamente una implementación de función hash o árbol binario teóricamente eficiente . Este error implica la diferencia entre el comportamiento esperado y el peor de los casos de un algoritmo .
En grandes cantidades, el hecho de estar fuera de uno a menudo no es un problema importante. Sin embargo, en cantidades más pequeñas y en casos específicos donde la precisión es primordial, cometer un error de uno en uno puede ser desastroso. A veces, un problema de este tipo también se repetirá y, por lo tanto, se agravará si alguien pasa un cálculo incorrecto si la siguiente persona comete el mismo tipo de error nuevamente (por supuesto, el error también podría revertirse).
Un ejemplo de este error puede ocurrir en el lenguaje computacional MATLAB con la función de linspace()
interpolación lineal , cuyos parámetros son y no . Un programador que malinterprete el tercer parámetro como el número de incrementos, podría esperar que logre una secuencia, pero en su lugar 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 uno en uno que da como resultado un error relacionado con la seguridad es causado por el mal uso de la rutina de la biblioteca estándar de C. strncat
Un error común strncat
es 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:
void foo ( char * s ) { char buf [ 15 ]; memset ( buf , 0 , tamaño de ( buf )); strncat ( buf , s , tamaño de ( buf )); // El parámetro final debe ser: sizeof (buf) -1 }
Los errores uno por uno son comunes en el uso de la biblioteca C porque no es consistente con respecto a si uno necesita restar 1 byte: funciones como fgets()
y strncpy
nunca escribirán más allá de la longitud dada ( fgets()
resta 1 y solo recupera (longitud - 1) bytes), mientras que otros, como strncat
escribirán más allá de la longitud dada. Entonces, el programador debe recordar para qué funciones necesita restar 1.
En algunos sistemas ( arquitecturas little endian en particular), esto puede resultar en la sobrescritura del byte menos significativo del puntero de la trama . Esto puede causar una condición de explotación 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 del número máximo de caracteres a escribir. Estas funciones incluyen strlcat
y strlcpy
, y a menudo se consideran "más seguras" porque facilitan la escritura accidental más allá del final de un búfer. (En el ejemplo de código anterior, llamar en su strlcat(buf, s, sizeof(buf))
lugar eliminaría el error).
Ver también
Otras lecturas
- Matt Parker (2021). Humble Pi: Cuando las matemáticas van mal en el mundo real . Libros de Riverhead. ISBN 978-0593084694.
Referencias
- ^ 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.
- ^ Raymond, Eric. "El archivo de jerga" . Consultado el 17 de mayo de 2021 .
- Una versión anterior de este artículo se basó en un error de poste de cerca en FOLDOC , usado con permiso .
- Dijkstra, Edsger Wybe (2 de mayo de 2008). "Por qué la numeración debe comenzar 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 uno en uno