Errores de coma flotante en JavaScript
Cuando haces con javascript
0.1 + 0.2 === 0.3y el resultado es false, no es un bug. Es la naturaleza misma de cómo los ordenadores representan los números.
Qué es coma flotante
JavaScript (como la mayoría de lenguajes) usa el formato IEEE-754 de 64 bits para representar números.
Este formato almacena el signo, el exponente y la parte de la fracción en binario.
El problema es que muchos números decimales no tienen representación exacta en binario.
Por ejemplo, 0.1 se convierte internamente en algo como:
0.00011001100110011001100110011001100110011001100110011...Un número infinito que debe truncarse. Por ejllo 0.1 + 0.2 da 0.30000000000000004
Algunos ejemplos:
0.1 + 0.2 // 0.30000000000000004
0.3 - 0.2 // 0.09999999999999998
0.1 * 3 // 0.30000000000000004
0.3 / 0.1 // 2.9999999999999996Comparar correctamente con EPSILON
En lugar de buscar igualdad exacta, usa una tolerancia con el número EPSILON
const casiIguales = (a, b) => Math.abs(a - b) < Number.EPSILON;
casiIguales(0.1 + 0.2, 0.3); // trueNumber.EPSILON representa la mínima diferencia reconocible entre dos números distintos en coma flotante.
Redondeando resultados
También podemos usar toFixed si lo que queremos es representar el valor final
+(0.1 + 0.2).toFixed(2); // 0.3O incluso podemos usar una funcón auxiliar
function redondear(valor, decimales = 2) {
const factor = 10 ** decimales;
return Math.round(valor * factor) / factor;
}Aun así, lo aconsejable es que evites redondear dentro de cada paso de un cálculo largo.
Cada redondeo introduce un pequeño error que se acumula. Lo ideal es redondear solo al final, justo antes de mostrar o guardar el resultado.
Trabajando con enteros
Quizás la práctica más común cuando trabajamos con precios o contabilidad es multiplicar por 100 y trabajar con enteros para evitarnos errores.
let a = 10; // representa 0.10 €
let b = 20; // representa 0.20 €
(a + b) / 100; // 0.3Así evitas errores acumulados y mantienes control total sobre los decimales.
Uso de librerías
Cuando la precisión es crítica (finanzas, cálculos científicos...), puedes usar librerías de precisión arbitraria que está ideadas para evitarnos errores de coma flotante.
Una de las más utilizadas es decimal.js
npm install decimal.jsimport { Decimal } from 'decimal.js';
new Decimal(0.1).plus(0.2).equals(0.3); // trueOtras opciones son big.js, bignumbers.js o dinero.js
Donde podemos encontrarnos errores
- Cálculos de IVA o impuestos
- Sumas de totales o descuentos
- Comparaciones de precios exactos
- Medias o porcentajes acumulativos
En todos estos casos, una pequeña desviación puede tener impacto real.
Un céntimo fuera de lugar es suficiente para romper una conciliación.
