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 0x301Fh: No compares numeros de punto flotante con igualdad exacta

Memoria, punteros y tipos (0x30XX)

Universidad Nacional de Río Negro

0x301Fh: No compares numeros de punto flotante con igualdad exacta

Enunciado normativo

NO DEBE compararse igualdad exacta (== o !=) entre valores de punto flotante; usá una tolerancia.

Síntoma en el código del estudiante

Se compara un float o double contra un literal con ==, confiando en que el valor calculado coincidirá exactamente:

if (f == 0.0f)
{
    reportar_cero();
}

Diagnóstico

Mecanismo del defecto

Los valores de punto flotante se representan con precisión finita IEEE-754 (ISO/IEC 9899:2011 §6.2.5). Operaciones como sumas, multiplicaciones o divisiones introducen errores de redondeo que se acumulan. Un valor que matemáticamente debería ser 0.0 puede valer 0.0000001 o -0.0, y entonces la igualdad estricta falla.

Consecuencia observable

La rama de igualdad no se ejecuta aunque “debería”. El error es intermitente y depende del compilador, las banderas de optimización y la plataforma (x86 vs ARM, -O0 vs -O2). Es la causa clásica de comparaciones que “funcionan en mi máquina”.

Fundamento en el estándar C11

ISO/IEC 9899:2011 §5.2.4.2.2 especifica las características de los tipos de punto flotante y §6.3.1.8 las conversiones usuales. La aritmética no es exacta; la igualdad estricta solo es fiable para valores representables con exactitud (enteros pequeños, potencias de dos). La cátedra exige comparar con tolerancia.

Corrección idiomática

❌ Código con el antipatrón

if (f == 0.0f)
{
    reportar_cero();
}

✅ Código refactorizado

#include <math.h>

if (fabs(f) < 1e-6)
{
    reportar_cero();
}

La comparación contra una tolerancia epsilon captura los valores “matemáticamente cero” con error de redondeo. Para comparar dos valores a y b, usar fabs(a - b) < epsilon.

Errores típicos al compilar o ejecutar

Con -Wfloat-equal (no incluida en -Wall):
warning: comparing floating point with == or != is unsafe [-Wfloat-equal]

Sin advertencias, la rama no se ejecuta cuando f vale 0.0000001,
aunque el resultado matemático sea 0. El bug es intermitente.

Checklist de verificación

Reglas relacionadas