La precisión en JavaScript

El siguiente problema no es sólo de JavaScript, afecta a todos los lenguajes de programación, pero es muy fácil de comprobar en JavaScript.

Abre una consola de JavaScript en un navegador y escribe:

console.log(0.1*0.2);

La respuesta debería ser 0.02, pero aparece 0.020000000000000004.

 

Escribe:

console.log(0.1+0.2);

La respuesta debería ser 0.3, pero aparece 0.30000000000000004.

 

Con el resultado anterior, si escribes:

console.log((0.1+0.2) == 0.3);

Lo normal sería esperar que apareciese true, pero aparece false.

 

Escribe:

console.log(23*1.40);

La respuesta debería ser 32.2, pero aparece 32.199999999999996.

 

¿Divertido? Pues no, porque si no se controla, se puede convertir en un verdadero problema.

La razón es bien sencilla: el problema está en el formato IEEE 754 que se emplea para representar los números en “coma flotante”, los números reales, los números con decimales.

Un ejemplo para que se entienda bien: el número 0.1 se escribe así porque usamos base 10. En forma de fracción, ese número se representa como 1/10. Como el denominado coincide con la base, la representación es directa: 10 elevado a -1, es decir, 0.1.

¿Cómo se representa el número 1/3 en base 10? No se puede, es una secuencia de infinitos números: 0.3333333333…

Sin embargo, 1/3 en base 3 se representa como 0.1, es decir, 3 elevado a -1.

Los ordenadores emplean la base 2: algunos números se puede representar con toda precisión, sin embargo otros necesitan infinitos decimales.

La solución a este problema está en emplear algún tipo de dato alternativo a través de alguna librería, como por ejemplo BigDecimal.js. Pero cuidado, esto hará que los cálculos sean mucho más lentos.

Y el que quiera aprender más, la guía definitiva: What Every Computer Scientist Should Know About Floating-Point Arithmetic.

Profesor del Departamento de Lenguajes y Sistemas Informáticos de la Universidad de Alicante (España). Interesado en el desarrollo y la accesibilidad web.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.