Off-by-one error

Summary

Un error por uno o error por un paso (en inglés: Off-by-one error -OBOE) es un error de lógica que es el equivalente discreto de una condición de contorno. Ocurre a menudo en la programación de computadoras cuando un bucle iterativo se repite una vez más o una vez menos que lo necesario. Este problema puede presentarse por ejemplo, cuando un programador comete errores como el uso de la expresión "es menor que o igual a", cuando en realidad debería haber utilizado "es menor que" en una comparación o no toma en cuenta que una secuencia comienza en el cero en lugar de en uno (como por ejemplo con los índices de matriz en varios lenguajes). Esto también puede ocurrir en un contexto matemático.

Bucles en una matriz

editar

Considere una matriz de elementos, y los elementos desde m hasta n (inclusive) deben ser procesados. Cuantos elementos hay? La respuesta intuitiva es n - m, pero esta respuesta esta equivocada por un elemento, exhibiendo un error de poste. La respuesta correcta es n - m + 1.

Por este motivo, los rangos en cómputos se representan generalmente como intervalos entreabiertos; el rango desde m hasta n (inclusive) es representado por el rango desde m (inclusive) hasta n + 1 (exclusivamente) para evitar errores de poste. Por ejemplo, un bucle de programa que se repite cinco veces puede escribirse como un intervalo entreabierto desde 0 hasta 5:

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

El cuerpo del bucle es ejecutado por primera vez con i igual a 0; i se convierte en 1, 2, 3 y finalmente 4 en los siguientes ciclos. Entonces, i se convierte en 5, con lo cual i < 5 se vuelve falso y el ciclo termina. Si en cambio la comparación usada fuera <= (menor o igual que), el ciclo se repetiría seis veces: i toma los valores 0, 1, 2, 3, 4 y 5. De la misma manera, si i fuera inicializado a 1 en vez de 0, el ciclo se repetiría únicamente cuatro veces: i tendría los valores 1, 2, 3 y 4. Ambas alternativas causan errores por un paso.

El mismo error puede ocurrir si un ciclo do-while se usa en vez de un ciclo while o viceversa. Un ciclo do-while siempre se ejecuta al menos una vez.

Errores relacionados con matrices pueden resultar por diferencias entre lenguajes de programación. Contar desde 0 es lo más común, pero algunos lenguajes comienzan la numeración desde 1. Pascal tiene matrices con índices definidos por el usuario, lo que hace posible utilizar los índices de matriz más adecuados al problema.

Error de poste

editar
 
Un enrejado recto con n secciones contiene n+1 postes.

Un error de poste es un tipo específico de error por un paso. El siguiente problema ilustra el error:

Si se quiere construir un enrejado recta de 30 metros con postes colocados cada 3 metros, ¿cuántos postes son necesarios?

La respuesta intuitiva, 10, es incorrecta. El enrejado tiene 10 secciones, pero 11 postes.

El error inverso ocurre cuando se conoce el número de postes y se asume que el número de secciones es el mismo. El número de secciones es uno menos que el número de postes. Generalmente, el problema de fórmula de la siguiente manera:

Si se tienen n postes de alumbrado, ¿cuántos espacios hay entre ellos?

La respuesta correcta es n - 1 si la línea de postes es abierta, n si forma un circuito cerrado, o n + 1 si los espacios abiertos al inicio y final cuentan como secciones. La formulación del problema debe ser considerada cuidadosamente, ya que la solución para una situación puede ser incorrecta para otras. Los errores de poste ocurren por contar los elementos en vez de los espacios entre ellos, o viceversa; o por no considerar si se debe contar uno o ambos lados de un elemento como una sección.

Errores de poste pueden ocurrir en unidades otras que la longitud. Por ejemplo, la Pirámide del tiempo, una pirámide consistente de 120 bloques colocados cada 10 años, tardará 1190 (y no 1200) años en construirse, desde la colocación del primer bloque hasta el último. Uno de los errores de poste más antiguos ocurrió en el calendario juliano, que calculaba los años bisiestos de forma inclusiva en vez de exclusiva, resultando en un año bisiesto cada tres años en vez de cada cuatro.

Referencias

editar
  • An earlier version of this article was based on fencepost error (enlace roto disponible en Internet Archive; véase el historial, la primera versión y la última). at FOLDOC, used with permission.
  • Dijkstra, Edsger Wybe (2 de mayo de 2008). «Why numbering should start at zero (EWD 831)». E. W. Dijkstra Archive. University of Texas at Austin. Consultado el 16 de marzo de 2011. ,
  •   Datos: Q1439356