Por qué 0,1 + 0,2 no da 0,3

El estándar IEEE 754 escribe un número como signo, exponente y mantisa, en base dos: valor = (−1)^signo × 1,mantisa × 2^(exponente − sesgo). En precisión simple hay 8 bits de exponente y 23 de mantisa; en doble, 11 y 52. Es el formato de casi todos los procesadores y de todos los lenguajes de programación.

En base dos solo las fracciones cuyo denominador es potencia de 2 tienen una escritura finita. 0,5 y 0,25 sí; 0,1 no: en binario es 0,000110011001100… periódico y hay que cortarlo. El valor guardado es el más cercano disponible, que para un float es 0,100000001490116…, y al sumar valores ya aproximados los errores se acumulan.

Por eso los decimales en coma flotante no se comparan con ==, sino comprobando que la diferencia sea pequeña, y el dinero se cuenta en céntimos enteros o con tipos decimales. Los valores especiales completan el formato: cero con signo, infinitos, NaN y los subnormales, que llenan el hueco junto al cero.

Errores frecuentes

  • Comparar dos floats con ==: 0.1 + 0.2 == 0.3 es falso en casi todos los lenguajes.
  • Usar floats para importes de dinero: los redondeos se suman. Mejor céntimos enteros o un tipo decimal.
  • Creer que un float de 32 bits tiene 32 bits de precisión: la mantisa tiene 24, unas 7 cifras decimales; un double tiene unas 16.

Preguntas frecuentes

¿Cuántas cifras decimales tienen un float y un double?

Un float de 32 bits garantiza unas 7 cifras decimales significativas, un double de 64 bits unas 15 o 16. Más allá, las cifras que ves reflejan la aproximación binaria.

¿Qué son los números subnormales?

Son los valores menores que el mínimo normal: el exponente es todo ceros y la mantisa pierde el 1 implícito. Permiten acercarse al cero de forma gradual, a costa de precisión.

¿Por qué existen +0 y −0?

Porque el signo es un bit aparte. Los dos ceros son iguales al compararlos, pero 1/+0 da +∞ y 1/−0 da −∞: conservan el lado desde el que se llegó al cero.

Cómo funciona este cálculo

Valor = (−1)^s × 1,f × 2^(e − sesgo) para los números normales, con sesgo 127 en precisión simple y 1023 en doble; para los subnormales (e = 0) el valor es (−1)^s × 0,f × 2^(1 − sesgo). Un exponente todo a 1 con mantisa nula es ±∞, con mantisa no nula es NaN. El valor exacto se calcula en decimal sin redondeos: cada float es m × 2^k, y para k negativo equivale a m × 5^(−k) ÷ 10^(−k).