Inicio · Parte 01 — Aritmética computacional y representación numérica
0.1₁₀ = 0.0001100110011...₂ (periódico infinito)
comparación correcta: math.isclose(a, b, rel_tol=...)
La clase 004 estableció que una fracción tiene desarrollo finito solo si su denominador reducido se factoriza en los primos de la base. En base 10 los primos son 2 y 5, y por eso 1/10 es finito. En base 2 el único primo es 2, así que 1/10 —cuyo denominador contiene un 5— tiene desarrollo binario periódico infinito.
Como la mantisa tiene 53 bits, ese desarrollo se trunca. El float más cercano a 0.1 es en realidad 0.1000000000000000055511151231257827021181583404541015625. Sumar dos aproximaciones y compararlas con la aproximación de 0.3 no tiene por qué dar igualdad, y de hecho no la da: la diferencia es de unos 5.5·10⁻¹⁷.
La conclusión correcta no es «los floats están rotos». Es que el operador == no es la comparación adecuada para resultados de cálculo en punto flotante. La comparación correcta declara una tolerancia: math.isclose(a, b, rel_tol=1e-12) pregunta si los dos números coinciden dentro de una precisión relativa declarada, que es la pregunta que realmente se quiere responder.
Hay una excepción importante: comparar con == sí es correcto cuando los valores son exactamente representables y no han pasado por operaciones inexactas —enteros pequeños, potencias de 2, resultados de asignaciones directas—. La regla práctica es preguntarse si el valor viene de un cálculo; si viene, hace falta tolerancia.
La desigualdad y su explicación.
0.1 + 0.2 = 0.30000000000000004
0.3 = 0.29999999999999998889776975374843...
¿iguales con ==? No
diferencia 5.55e−17
0.1 con 50 decimales:
0.10000000000000000555111512312578270211815834045410
Comparación correcta:
math.isclose(0.1 + 0.2, 0.3, rel_tol=1e-12) → True
El error es de 5.5·10⁻¹⁷ sobre 0.3: precisión relativa de 1.8·10⁻¹⁶, exactamente el epsilon de máquina. El resultado es tan bueno como el formato permite.
0.1 + 0.2 != 0.3 explicado con la fracción binaria real.
python classes/part-01-aritmetica-computacional-y-representacion-numerica/029-por-que-0-1-0-2-no-es-exactamente-0-3/lab.py
compmath run 029
0.1+0.20.3igualesdiferencia0.1_como_fraccion_exacta0.1_con_50_digitoscomparacion_correcta{
"0.1+0.2": 0.30000000000000004,
"0.3": 0.3,
"iguales": false,
"diferencia": 5.551115123125783e-17,
"0.1_como_fraccion_exacta": "3602879701896397/36028797018963968",
"0.1_con_50_digitos": "0.10000000000000000555111512312578270211815834045410"
}
Cualquier test numérico, criterio de convergencia o comparación de resultados. Los asserts de todo el programa usan tolerancia declarada precisamente por esto.
float32, bfloat16 y la cuantización a int8 son decisiones de representación. Los NaN en un entrenamiento casi siempre nacen aquí, no en la arquitectura.
math.isclose y PEP 485 — documentación de la herramienta que ejecuta el laboratorio · URL de la fuente primaria comprobada en Python Software Foundation (2026-08-19).10.1145/103162.103163 verificado en Crossref (2026-08-19).