En muchos lenguajes de programación, encontramos un fenómeno extraño: al calcular 0.1 + 0.2, el resultado no es 0.3. Por ejemplo, en C, C++, JavaScript, Python, Java, Ruby, etc., todos tienen este problema.

Para ello, alguien incluso creó unhttps://0.30000000000000004.com/sitio web en el que podemos encontrar qué lenguajes de programación, al calcular 0.1 + 0.2, no obtienen como resultado 0.3, sino 0.30000000000000004.




Podemos usar JavaScript como demostración: al calcular 0.1 + 0.2, el resultado no es 0.3, sino 0.30000000000000004.

Por supuesto, si lo usas como una declaración de condición, también devuelve false:

También hay otros ejemplos:
6 * 0.1 = 0.6 但计算机显示为 0.6000000000000001 0.11 + 0.12 = 0.23 但计算机显示为 0.22999999999999998 0.1 + 0.7 = 0.8 但计算机显示为 0.7999999999999999 0.3+0.6 = 0.9 但计算机显示为0.8999999999999999

Pero las siguientes expresiones pueden obtener el resultado que queremos:

¿Por qué ocurre esto?
En pocas palabras, las computadoras usan números de punto flotante basados en binario, mientras que los humanos usamos números de punto flotante basados en decimal.
En binario, los números de punto flotante generalmente se representan de acuerdo con el estándar IEEE 754. No se pueden representar con precisión decimales como 0.1, 0.2 o 0.3, porque se utiliza el formato de punto flotante binario.
El estándar IEEE 754 se puede consultar en:https://zh.wikipedia.org/wiki/IEEE_754
El principio subyacente
En el sistema decimal, si una fracción se representa utilizando los factores primos de la base (10), entonces puede representarse con precisión.
Los factores primos de 10 son 2 y 5.
Por lo tanto, 1/2, 1/4, 1/5 (0.2), 1/8 y 1/10 (0.1) pueden representarse con precisión, porque el denominador utiliza los factores primos de 10.
Mientras que 1/3, 1/6 y 1/7 son decimales periódicos infinitos, porque el denominador utiliza los factores primos de 3 o 7.
En binario (el sistema que usan las computadoras), si una fracción se representa utilizando los factores primos de la base (2), entonces puede representarse con precisión.
2 es el único factor primo de 2.
Por lo tanto, 1/2, 1/4 y 1/8 pueden representarse con precisión, porque el denominador utiliza los factores primos de 2.
Mientras que 1/5 (0.2) o 1/10 (0.1) son decimales periódicos infinitos, porque el denominador utiliza los factores primos de 5 o 10.
Entonces, cuando intentamos representar un número decimal como 0.1, la computadora utiliza un valor aproximado. Esta aproximación se logra convirtiendo el binario periódico infinito en una representación de punto flotante con un número finito de dígitos.
Por lo tanto, cuando realizamos operaciones de punto flotante en una computadora, el resultado puede tener pequeños errores.
Por ejemplo, la representación aproximada de 0.1 en binario puede ser 0.000110011001100..., pero en la representación de punto flotante de la computadora, puede truncarse o redondearse a 0.00011001100110, lo que hace que 0.1 + 0.2 en la computadora no sea igual a 0.3, sino que se desvíe ligeramente.
0.1 es un décimo (1/10). Para obtener la representación binaria de 0.1 (es decir, su forma binaria), necesitamos usar la división larga binaria, que consiste en dividir el número binario 1 entre el binario 1010 (es decir, 1/1010), como se muestra a continuación:

Por lo tanto, la representación binaria de 0.1 es 0.0001100110011001100110011... (periódico infinito).
Este patrón periódico infinito 0011 se repetirá indefinidamente, porque el sistema binario solo puede aproximar el 0.1 decimal de esta manera.
En los sistemas informáticos reales, este decimal periódico infinito se trunca a un número finito de dígitos para poder almacenarlo y calcularlo. Esto provoca que, al realizar operaciones de punto flotante binario en la computadora, pueda haber pérdida de precisión, haciendo que la suma de 0.1 y 0.2 no sea exactamente igual a 0.3.
Convertir decimales de base 10 a binario
También existe un método más fácil de entender (el método de multiplicar por 2 y tomar la parte entera). Por ejemplo, para convertir el decimal 0.875 a binario, solo hay que multiplicar la parte fraccionaria del número decimal por 2 y extraer la parte entera, hasta que la parte fraccionaria se convierta en 0.

El resultado de ordenar las partes enteras extraídas anteriormente, 111, se convierte en la representación binaria..875。
El número binario 1101.111, con parte entera 1101 y parte fraccionaria 111, es el resultado de convertir el número decimal 13.875 a binario.
Siguiendo el método anterior, convertir el decimal 0.1 a binario nos da:
0.1 = 0.0001100110011001100110011001100110011001100110011001101...

El decimal 0.2 convertido a binario es:
0.2 = 0.001100110011001100110011001100110011001100110011001101...

Soluciones
1. Convertir el decimal a entero primero
Primero puedes convertir los decimales a enteros, sumarlos y luego volver a convertirlos a decimales, como en el siguiente ejemplo:
(0.1*10 + 0.2*10)/10

2. Usar el método toFixed()
El método toFixed() puede convertir un número en una representación de cadena con un número específico de decimales.
A continuación se muestra un ejemplo del uso del método toFixed() para resolver el problema de precisión de los números de punto flotante:
let sum = 0.1 + 0.2; console.log(sum.toFixed(2)); // 输出: 0.30
Cabe señalar que, aunque el método toFixed() resuelve el problema en la visualización, no cambia el valor real del número, solo cambia su forma de representación.
Si necesitas realizar operaciones matemáticas precisas, es posible que debas usar otros métodos, como introducir un tipo de dato numérico con mayor precisión o usar una biblioteca matemática de terceros para manejar operaciones de punto flotante.
3. Usar la biblioteca decimal.js
Al manejar problemas de precisión de números de punto flotante en JavaScript, usar la biblioteca decimal.js es una solución más precisa y confiable.
decimal.js es una biblioteca matemática decimal de precisión arbitraria que puede evitar la imprecisión de las operaciones de punto flotante en JavaScript nativo.
Dirección de Github:https://github.com/MikeMcl/decimal.js
Primero, debes introducir la biblioteca decimal.js en tu proyecto.Instalarlo con npm:
npm install decimal.js
Introducirlo en HTML:
<script src="../cdnjs.cloudflare.com/ajax/libs/decimal.js/10.2.0/decimal.min.js"></script>
A continuación, puedes usar decimal.js para manejar operaciones de punto flotante. Aquí tienes un ejemplo:
Ejemplo
const Decimal = decimal. Decimal;
// Crear dos objetos Decimal
let a = new Decimal('0.1');
let b = new Decimal('0.2');
// Realizar una operación de suma
let sum = a.plus(b);
// Mostrar el resultado
console.log(sum.toString()); // Salida: 0.3
El resultado obtenido con la biblioteca decimal.js es exactamente 0.3, no un valor aproximado como en JavaScript nativo.