Visualizador flotante IEEE-754
Vea exactamente cómo se almacena un número decimal como un flotante IEEE-754 (bit de signo, bits de exponente y bits de mantisa) y por qué números como 0,1 no se almacenan exactamente.
Resultado
Cada número de coma flotante que almacena una computadora (un número de JavaScript, un flotante de C, un flotante de Python) está codificado de la misma manera según IEEE 754: un bit de signo, un bloque de bits de exponente y un bloque de bits de mantisa (fracción). La precisión simple (32 bits) utiliza 1 bit de signo, 8 bits de exponente y 23 bits de mantisa; doble precisión (64 bits), el formato detrás del tipo de número predeterminado de casi todos los idiomas, utiliza 1 bit de signo, 11 bits de exponente y 52 bits de mantisa. Esta herramienta toma cualquier número decimal que escriba, lo codifica en cualquier ancho usando el codificador flotante DataView/ArrayBuffer del navegador (la misma maquinaria en la que realmente se ejecuta su código) y colorea cada bit según la región a la que pertenece.
La codificación en sí sigue tres pasos, y esta herramienta los recorre todos en lugar de solo mostrar los bits finales. Primero, normalización: el número se reescribe como 1.mantissa × 2^exponente, con exactamente un dígito distinto de cero antes del punto binario (los números demasiado pequeños para eso reciben el tratamiento subnormal, sin un 1 inicial implícito). En segundo lugar, sesgo de exponente: dado que el campo de exponente debe almacenar exponentes positivos y negativos como un número sin signo, se agrega un sesgo fijo (127 para precisión simple, 1023 para precisión doble) antes de que el campo se escriba en binario. En tercer lugar, la mantisa fraccionaria se expande poco a poco con el método clásico de “multiplicar por dos, tomar la parte entera como el siguiente bit, conservar el resto”, que se repite hasta que el campo de la mantisa esté lleno, momento en el que los bits sobrantes deciden si el resultado se redondea hacia arriba o hacia abajo (redondear de la mitad a par, el valor predeterminado de IEEE-754).
Esta es exactamente la razón por la que un número tan común como 0,1 no se almacena exactamente. En binario, 0,1 es una fracción que se repite (0,0001100110011…, para siempre), por lo que ninguna mantisa finita puede contenerla con precisión: tiene que redondearse en alguna parte. Codifique 0.1 como un flotante de 32 bits y lea los bits, y no recuperará 0.1: obtendrá exactamente 0.100000001490116119384765625. La precisión doble tiene 29 bits de mantisa más con los que trabajar, por lo que su error de redondeo es mucho menor, pero tampoco es cero: 0,1 como doble de 64 bits es exactamente 0,1000000000000000055511151231257827021181583404541015625. Esta herramienta calcula ese valor almacenado exacto con aritmética de enteros grandes (sin atajos de punto flotante), de modo que la brecha entre lo que usted escribió y lo que realmente guarda el hardware nunca se oculta ni se aproxima.
Los valores especiales obtienen patrones de bits reservados exactos en lugar de una codificación normal: cero y cero negativo tienen bits de exponente y mantisa completamente ceros (solo difiere el bit de signo), ±Infinity tiene bits exponentes completamente uno con una mantisa completamente cero, y NaN tiene bits exponentes completamente uno con al menos un bit de mantisa establecido. Aquí todo se ejecuta localmente en su navegador (nada de lo que escribe se carga en ninguna parte), lo que hace que este sea un lugar seguro para desarrollar una intuición real para errores de punto flotante: por qué `0.1 + 0.2 !== 0.3` en casi todos los lenguajes de programación, por qué las texturas float32 en el código de gráficos pierden precisión que float64 no, y por qué el código financiero generalmente debería evitar el punto flotante binario por completo.