Conversor IEEE 754 — Decimal a Bits de Punto Flotante (32/64 bits)

Convierte en ambas direcciones entre números decimales y patrones de bits IEEE 754 (simple precisión de 32 bits o doble de 64 bits). El signo, el exponente y la mantisa se muestran con colores diferenciados, para detectar NaN, infinito y subnormales al instante.

El ejemplo clásico: por qué 0.1 + 0.2 no da 0.3

En JavaScript, `0.1 + 0.2` da como resultado `0.30000000000000004`, no `0.3`. Observar los patrones de bits en precisión doble explica por qué.

Valor Hexadecimal en precisión doble (64 bits) Binario en precisión doble (64 bits)
0.1 0x3FB999999999999A 0011111110111001100110011001100110011001100110011001100110011010
0.2 0x3FC999999999999A 0011111111001001100110011001100110011001100110011001100110011010
0.3 0x3FD3333333333333 0011111111010011001100110011001100110011001100110011001100110011
0.1 + 0.2 0x3FD3333333333334 0011111111010011001100110011001100110011001100110011001100110100

0.1, 0.2 y 0.3 son todas fracciones infinitamente periódicas en binario, así que ninguna cabe exactamente en la mantisa de 52 bits y cada una se redondea. Como los errores de redondeo de 0.1 y 0.2 no llegan a cancelarse entre sí, su suma termina siendo apenas un bit distinta del patrón exacto de 0.3 (0x3FD3333333333334). Prueba a introducir estos valores en el conversor de arriba y compara tú mismo los últimos bits.

¿Qué es IEEE 754? Ver los números de punto flotante como bits

Cuando una computadora almacena un número decimal, no conserva las cifras que escribiste: empaqueta el valor en una cantidad fija de bits siguiendo el estándar IEEE 754, dividiéndolos en signo, exponente y mantisa. Esta herramienta te muestra exactamente qué bits se almacenan para cualquier valor que introduzcas, tanto en precisión simple (32 bits) como en precisión doble (64 bits), y también funciona al revés: pega un patrón hexadecimal o binario en bruto y descubre a qué valor decimal corresponde.

La mayor parte de la programación cotidiana nunca requiere pensar en esta capa, pero es la razón por la que `0.1 + 0.2` no da `0.3`, por la que los enteros muy grandes pierden precisión al guardarse como flotantes, y por la que NaN e infinito se comportan como lo hacen en las comparaciones. Ver el signo, el exponente y la mantisa desglosados para un valor real convierte esas reglas abstractas en algo que puedes señalar con el dedo.

Cómo usar esta herramienta

  1. Elige una dirección y una precisión Selecciona "Decimal → Patrón de bits" o "Patrón de bits → Decimal", y luego precisión simple (32 bits) o doble (64 bits).
  2. Introduce un valor Para la entrada decimal, escribe cualquier número o "NaN"/"Infinity"/"-Infinity". Para la entrada en bits, usa una cadena hexadecimal con prefijo `0x` o una cadena binaria con el número de dígitos que corresponda a la precisión elegida.
  3. Lee el desglose de signo, exponente y mantisa La cadena de bits con colores y una tabla de detalle muestran el exponente sin procesar, el exponente tras eliminar el sesgo y la representación hexadecimal completa.
  4. Consulta la etiqueta de clasificación La herramienta clasifica automáticamente el resultado como cero, subnormal, normal, infinito o NaN, junto con una breve explicación de qué significa esa clasificación.
  5. Prueba los valores predefinidos y los casos límite Usa los botones de 0,1/0,2/0,3, ±0, ±Infinity y NaN, o prueba valores negativos y números extremadamente grandes o pequeños para ver cómo se codifican.

Consejos para aprovecharla mejor

  • Convierte 0.1, 0.2 y 0.3 a bits en precisión doble y compáralos con el resultado de 0.1+0.2 (0.30000000000000004): podrás ver a simple vista que solo difiere el último bit.
  • Introducir "-0" en el campo decimal produce un patrón de bits con solo el bit de signo activado (distinto de "+0"). Como números, 0 === -0, pero las representaciones en bits son distintas.
  • Cuando el campo del exponente es todo cero, una mantisa igual a cero significa cero, y una mantisa distinta de cero significa un número subnormal, una representación especial usada para alcanzar valores extremadamente cercanos a cero a costa de la precisión.
  • Alternar entre precisión simple (32 bits) y doble (64 bits) para un mismo valor como 0.1 muestra cómo el error de redondeo es mayor en precisión simple.
  • Para decodificar un patrón de bits de vuelta a un valor decimal, introduce una cadena hexadecimal con el prefijo `0x`, o una cadena binaria con exactamente tantos dígitos como la precisión seleccionada (el prefijo `0b` es opcional).

Dónde te puede servir esta herramienta

Estudios de informática

Los libros de texto describen la estructura del punto flotante de forma abstracta; aquí puedes comprobarla con números reales mientras estudias o preparas un informe de prácticas.

Depurar errores de precisión numérica

Averigua por qué un cálculo concreto queda ligeramente desviado introduciendo el valor sospechoso y examinando su patrón de bits exacto, sin escribir código.

Programación embebida y de bajo nivel

Decodifica un valor flotante en hexadecimal visto en un volcado de memoria o un registro y conviértelo de nuevo en un número decimal legible.

Preparación de entrevistas técnicas

Practica respuestas a preguntas como "¿en qué se diferencian la precisión simple y la doble a nivel de bits?" usando un ejemplo concreto en vez de datos memorizados.

Explicar a alguien por qué "0.1 + 0.2 ≠ 0.3"

Muestra los patrones de bits reales uno junto al otro en lugar de limitarte a afirmar que la causa es el redondeo del punto flotante.

Glosario

IEEE 754
El estándar internacional que define cómo representan las computadoras los números en punto flotante. Publicado en 1985, lo siguen los tipos float/double de prácticamente todos los lenguajes de programación.
Bit de signo
El único bit que indica si un valor es positivo (0) o negativo (1). Es independiente del exponente y la mantisa, por lo que "+0" y "-0" existen como patrones de bits distintos.
Exponente
Los bits que codifican la escala (magnitud) del valor: 8 bits en precisión simple, 11 en doble, almacenados con un sesgo sumado.
Mantisa (significando)
Los bits que codifican las cifras significativas del valor: 23 bits en precisión simple, 52 en doble, interpretados normalmente con un 1 implícito al principio.
Sesgo
Un desplazamiento fijo (127 en precisión simple, 1023 en doble) que se suma al exponente para que pueda almacenarse y compararse como un simple entero sin signo.
Número subnormal
Un patrón de bits con el exponente completamente a cero y la mantisa distinta de cero. Al omitir el 1 implícito, permite representar valores más cercanos a cero que un número normal, a costa de la precisión.
NaN (no es un número)
Un patrón de bits con el exponente completamente a uno y la mantisa distinta de cero, producido por operaciones indefinidas como 0/0 o ∞-∞.
Infinito
Un patrón de bits con el exponente completamente a uno y la mantisa completamente a cero, que suele aparecer cuando un cálculo desborda el rango representable.

Preguntas frecuentes

0.1, 0.2 y 0.3 son todas fracciones infinitamente periódicas en binario, así que una computadora tiene que redondear cada una para que quepa en la mantisa finita (52 bits en precisión doble). Como los errores de redondeo de 0.1 y 0.2 no llegan a cancelarse entre sí, su suma termina siendo ligeramente distinta del patrón de bits exacto de 0.3 (0.30000000000000004). No es un error de ningún lenguaje en particular: ocurre en todos los lenguajes que cumplen con IEEE 754.

La precisión simple (float, 32 bits) usa 1 bit de signo, 8 bits de exponente y 23 bits de mantisa. La precisión doble (double, 64 bits) usa 1 bit de signo, 11 bits de exponente y 52 bits de mantisa. Más bits de mantisa dan más cifras significativas (precisión), y más bits de exponente dan un rango representable más amplio. La mayoría de los lenguajes de programación usan precisión doble de forma predeterminada para su tipo de punto flotante.

Es un patrón de bits en el que el campo del exponente es todo cero pero la mantisa no es cero. Un número de punto flotante normal tiene un 1 implícito al principio de su mantisa, pero un número subnormal lo omite y en su lugar fija el exponente en su valor mínimo, lo que permite representar valores incluso más cercanos a cero de lo que puede el número normal más pequeño, a costa de algo de precisión.

IEEE 754 tiene un bit de signo independiente, así que incluso cuando el exponente y la mantisa son todos cero, un bit de signo igual a 0 da "+0" y un bit de signo igual a 1 da "-0": dos patrones de bits distintos. Numéricamente, 0 === -0 es verdadero, pero algunas operaciones revelan la diferencia, como que 1/0 produzca +Infinity mientras que 1/-0 produzca -Infinity.

Ambos usan un patrón de bits en el que el campo del exponente es todo unos. Si la mantisa es todo ceros, representa infinito (con el bit de signo distinguiendo +Infinity de -Infinity); si la mantisa no es cero, representa NaN (Not a Number, no es un número). Surgen de operaciones matemáticamente indefinidas como la división entre cero o ∞ - ∞.
Tool-kun

A propósito — Cómo IEEE 754 se convirtió en un lenguaje común

Antes de 1985, cada fabricante de computadoras usaba su propia representación de punto flotante. IBM, DEC, Cray y otros podían calcular el mismo valor, digamos "0.1", y obtener un comportamiento de redondeo y rangos representables sutilmente distintos, por lo que portar un programa numérico de una máquina a otra a menudo producía resultados ligeramente diferentes. Para resolver este caos, un grupo de trabajo liderado por William Kahan, de UC Berkeley —quien también había participado en el diseño del coprocesador numérico Intel 8087—, impulsó la creación de un estándar a escala de toda la industria, publicado en 1985 como IEEE 754.

La idea central de IEEE 754 es dividir un número finito de bits (32 o 64) en tres roles —signo, exponente y mantisa— para aproximar el conjunto infinito de los números reales. El exponente se encarga de la escala (cuán grande o pequeño es un número), mientras que la mantisa se encarga de la precisión (cuántas cifras significativas tiene), lo que permite que un número fijo de bits cubra con flexibilidad tanto magnitudes muy pequeñas como muy grandes. El exponente se almacena sumándole un sesgo (127 en precisión simple, 1023 en precisión doble) para que comparar dos patrones de bits como simples enteros sin signo baste para determinar cuál valor es mayor, evitando la complejidad adicional de una representación con signo como el complemento a dos.

Solo las fracciones cuyo denominador es una potencia de dos (1/2, 1/4, 3/8, etc.) pueden representarse exactamente en binario. El valor decimal 0.1 es la fracción 1/10, y como 10 no es una potencia de dos, se convierte en la fracción binaria infinitamente periódica 0.0001100110011... Con solo un número finito de bits de mantisa disponibles, hay que truncarla y redondearla en algún punto: esta es la razón fundamental por la que una computadora no puede representar 0.1 exactamente. También es la razón por la que los sistemas contables que necesitan aritmética decimal exacta suelen evitar los números de punto flotante en favor de la aritmética con enteros o un tipo decimal dedicado (como BCD).

IEEE 754 se revisó más tarde en 2008 y 2019, añadiendo precisión media (16 bits), precisión cuádruple (128 bits) y formatos de punto flotante decimal, pero la división central en signo, exponente y mantisa, junto con sus modos de redondeo, no ha cambiado desde la edición original de 1985. Como prácticamente todos los tipos float/double de los lenguajes de programación se ajustan a este estándar, la pregunta "¿por qué 0.1 + 0.2 no es igual a 0.3?" aparece prácticamente en la misma forma sin importar el lenguaje que uses.