Volver a la lista

Punto flotante: por qué 0.1 + 1.1 no es igual a 1.2

Se explica por qué las computadoras no pueden representar los números decimales con exactitud y cómo abordar este problema en la práctica.

Intermedio
|
5min
|
Verificado (2026-07)
Progreso0/48 (0%)

Números de punto flotante — Por qué 0.1 + 1.1 no es 1.2

Al finalizar este tema

Podrá responder técnicamente a la pregunta: "¿Por qué 0.1 + 0.2 es 0.30000000000000004?".


Este código le sorprenderá

python
print(0.1 + 0.2)
# 0.30000000000000004
javascript
console.log(0.1 + 0.2);
// 0.30000000000000004

En Python, JavaScript, Java o C, se obtiene el mismo resultado en todos los lenguajes de programación. No es un error; es una limitación fundamental de la forma en que las computadoras almacenan los números decimales.


¿Por qué ocurre esto?

Las computadoras almacenan todo en binario (0 y 1). Los números enteros se convierten con precisión:

text
13 = 1101₂  (exacto)

Sin embargo, los números decimales son distintos. Al convertir 0.1 a binario:

text
0.1 = 0.0001100110011001100110011... ₂  (repetición infinita)

Al igual que en el sistema decimal 1/3 = 0.33333... es un decimal periódico, en el sistema binario 0.1 también es un decimal periódico. Dado que las computadoras no pueden almacenar números infinitos, deben truncarlos en algún punto. Este "truncamiento" genera errores.


Casos en los que el problema surge realmente en la práctica.

python
# Cálculo del precio
price = 0.1 + 0.1 + 0.1
print(price == 0.3) # False!
# Acumulación repetida
total = 0.0
for _ in range(10):
total += 0.1
print(total) # 0.9999999999999999 (¡no es 1.0!)

Si en una tienda en línea la suma de diez artículos de 100 wones da como resultado 999 wones, el cliente presentará una queja. En los sistemas financieros, cualquier discrepancia, incluso de 1 won, provoca una auditoría.


Algunos números son exactos

No todos los números presentan errores:

python
print(0.5 + 0.25) # 0.75 (¡exacto!)
print(0.125 + 0.0625) # 0.1875 (¡exacto!)

0.5 = 1/2, 0.25 = 1/4, 0.125 = 1/8: estos valores pueden expresarse como sumas de potencias de 2 y, por lo tanto, se convierten con precisión a binario. Por el contrario, 0.1 = 1/10 no puede representarse mediante potencias de 2, lo que genera un error de precisión.


Solución

1. Convertir a enteros para calcular — la opción más práctica

python
# Calcular en centavos en lugar de unidades monetarias
price_in_cents = 10 + 10 + 10 # 30 centavos
total = price_in_cents / 100 # 0.3 unidades monetarias (exacto)

2. Tolerancia de error al comparar

python
# ❌ Nunca comparar de esta forma
if a == 0.3:
# ✅ Comparar dentro de un margen de error
if abs(a - 0.3) < 1e-9:
print("Se consideran iguales")
# Python 3.5+
import math
if math.isclose(a, 0.3):
print("Se consideran iguales")

3. Módulo Decimal — cuando la precisión es absolutamente crítica.

python
from decimal import Decimal
a = Decimal("0.1") + Decimal("0.2")
print(a) # 0.3 (¡exacto!)
print(a == Decimal("0.3")) # True

Debe crearse como la cadena "0.1". No tiene sentido asignar a Decimal(0.1) un valor que ya contiene un error de punto flotante.


IEEE 754 — El estándar para almacenar números decimales

La razón por la que todos los lenguajes de programación producen el mismo error es que siguen el estándar internacional IEEE 754. Este estándar divide los 64 bits (doble precisión) en tres partes:

text
[1 bit de signo] [11 bits de exponente] [52 bits de mantisa]

Un mantisa de 52 bits puede representar aproximadamente entre 15 y 17 dígitos significativos. Dado que la representación binaria de 0,1 es un número periódico infinito, al truncarse a 52 bits, el resultado es aproximadamente 0.1000000000000000055511151231257827021181583404541015625.


Lo mismo ocurre en otros lenguajes

java
// Java
System.out.println(0.1 + 0.2);  // 0.30000000000000004

// C
printf("%.17f\n", 0.1 + 0.2);   // 0.30000000000000004

// Go
fmt.Println(0.1 + 0.2 == 0.3)   // false

En JavaScript, todos los números son IEEE 754 de doble precisión, por lo que los enteros también se ven afectados:

javascript
console.log(9007199254740992 + 1);  // 9007199254740992 (¡sin cambios!)
console.log(Number.MAX_SAFE_INTEGER);  // 9007199254740991

Para superar esta limitación, se utiliza BigInt.


Lista de verificación práctica

SituaciónSolución
Comparación de decimalesmath.isclose() o abs(a-b) < 1e-9
Cálculos monetariosDecimal o unidades enteras (céntimos, etc.)
Cálculos numéricos de gran volumenfloat tal cual (el error es despreciable)
Serialización JSONround(value, 10) antes de guardar
Base de datosUtilizar el tipo DECIMAL

Punto clave: Que una computadora cometa errores en cálculos decimales no es un error de software, sino una limitación fundamental del sistema binario. Para cálculos monetarios, use Decimal o unidades enteras; para comparaciones, use math.isclose(). Solo necesita recordar estos dos puntos.

💬 Preguntas y comentarios

0 comentarios

Puedes publicar sin iniciar sesión. Los comentarios de invitados no pueden editarse ni eliminarse después.

0/2000

Cargando...