Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Regla 0x1018h: No uses variables de punto flotante como control de lazo

Estructuras de control y flujo (0x10XX)

Universidad Nacional de Río Negro

0x1018h: No uses variables de punto flotante como control de lazo

Enunciado normativo

NO DEBE usarse una variable float o double como contador ni como variable de control de un lazo.

Síntoma en el código del estudiante

El contador de un for se declara float o double y avanza con incrementos fraccionarios:

for (float x = 0.0f; x < 1.0f; x += 0.1f)
{
    procesar(x);
}

Diagnóstico

Mecanismo del defecto

Los tipos float y double representan los reales con precisión finita (IEEE-754). El valor 0.1f no es exactamente un décimo en binario: cada suma acumula un error de redondeo. La comparación x < 1.0f puede volverse verdadera un número inesperado de veces, o nunca alcanzar el valor de corte exacto.

Consecuencia observable

El lazo puede ejecutarse una vez de más o de menos, o quedar infinito si el incremento es tan pequeño que el redondeo lo absorbe. Los conteos “deberían” dar 10 pero dan 9 u 11 según la plataforma y la optimización. El error no se reproduce de forma estable entre compiladores.

Fundamento en el estándar C11

ISO/IEC 9899:2011 §6.2.5 y §5.2.4.2.2 describen la representación de los tipos de punto flotante y sus límites de precisión. La aritmética con estos tipos no es exacta; usar una variable flotante como índice o contador es una fuente conocida de errores. La regla 0x301Bh prohíbe los casts y usos innecesarios de tipos flotantes en contextos enteros.

Corrección idiomática

❌ Código con el antipatrón

for (float x = 0.0f; x < 1.0f; x += 0.1f)
{
    procesar(x);
}

✅ Código refactorizado

for (int i = 0; i < 10; i++)
{
    float x = i * 0.1f;
    procesar(x);
}

El contador es entero y exacto; el valor flotante se deriva dentro del cuerpo con una multiplicación, sin acumular error. La cantidad de iteraciones queda determinada por la cota entera.

Errores típicos al compilar o ejecutar

No hay error de compilación. En ejecución, el lazo puede dar 9, 10 u 11
iteraciones según la plataforma; con -O2 el compilador puede reordenar la
comparación. Ver el error acumulado con:
printf("%.20f\n", x);  // muestra 0.9999999... en la última iteración

Checklist de verificación

Reglas relacionadas