Resolver la pérdida de precisión numérica JS

¡Acostúmbrate a escribir juntos! Este es el día 19 de mi participación en el "Nuevo plan diario de Nuggets · Desafío de actualización de abril", haga clic para ver los detalles del evento .

Calcular la suma de dos números decimales en JavaScript a veces produce resultados sorprendentes, ¡creo que todos lo saben!

pérdida de precisión

Por ejemplo, el resultado que 0.1 + 0.1obtenemos en el cálculo es 0.2, pero 0.1 + 0.2el resultado del cálculo no es 0.3, sino 0.30000000000000004

Este fenómeno no solo ocurre en la suma, sino también en la resta con resultados similares.

Por ejemplo 1.2 - 1el resultado es 0.19999999999999996

Sin embargo, esto no es exclusivo de JavaScript, otros lenguajes de programación tienen el mismo problema.

Por ejemplo, salida en el entorno de Python.

print(.1 + .2) 
复制代码

El resultado obtenido también es: 0.30000000000000004

razón

La razón principal de este problema es que las computadoras almacenan datos como archivos binarios .

Cómo convertir enteros de decimal a binario

Un entero decimal se puede convertir a binario dividiéndolo por 2. Toma el cociente y sigue dividiendo por 2 hasta llegar a cero.

Cada vez que realices esta división, anota el resto . Ahora invierta la lista restante para obtener el número en forma binaria.

Por ejemplo, quiero convertir 29 a binario:

29÷2=14 exceso1

14÷2=7 exceso0

7÷2=3 exceso1

3÷2=1 exceso1

1÷2=más de 01

El número binario que representa el decimal 29 es 11101.

P.ej:

  • 1 es 1

  • 10 es 1010

Convertir decimal de decimal a binario

Los decimales decimales se convierten en decimales binarios utilizando el método de "redondeo multiplicado por 2, disposición ordenada". El método específico es: multiplicar la fracción decimal por 2 para obtener el producto, sacar la parte entera del producto, luego multiplicar la parte fraccionaria restante por 2 para obtener un producto, y luego sacar la parte entera del producto, y así sucesivamente, hasta que la parte fraccionaria sea cero y 0 o 1 sea el último dígito en binario. o hasta que se logre la precisión requerida.

Por ejemplo: quiero convertir 0.375 a binario:

0.375*2=0.75 obtener 0

0.75*2=1.5 obtiene 1

0.5*2=1 obtiene 1, el decimal desaparece y el final. La conversión final a binario es 0.011

P.ej:

  • 0.1 es 0.0001100110011001100110011001100110011001100110011001101
  • 0.2 es 0.001100110011001100110011001100110011001100110011001101

No todos los números decimales se pueden representar perfectamente en este formato binario, ya que algunos números se pueden convertir a

Cuando JavaScript está calculando, primero convertirá el decimal a binario y realizará el cálculo.

0.00011001100110011001100110011001100110011001100110011010 +
0.0011001100110011001100110011001100110011001100110011010 =
0.0100110011001100110011001100110011001100110011001100111
复制代码

El resultado obtenido aquí se 0.0100110011001100110011001100110011001100110011001100111convierte a decimal y es 0.300000000000000004

solución

biblioteca de terceros

Decimal

x = new Decimal(0.1)
y = x.plus(0.2) 
复制代码

Número grande

x = new BigNumber(0.1)
y = x.plus(0.2)    
复制代码

convertirse en un entero

La idea principal es: primero convierta el decimal para dividir dos cadenas, luego calcule la longitud de la cadena de la parte fraccionaria y luego use esta longitud para convertir el decimal en un entero.

function add(num1, num2) {
  const num1Len = (num1.toString().split('.')[1] ).length;
  const num2Len = (num2.toString().split('.')[1] ).length;
  const maxLen = Math.pow(10, Math.max(num1Len, num2Len));
  return (num1 * maxLen + num2 * maxLen) / maxLen;
}
复制代码

aFijo

Supongo que te gusta

Origin juejin.im/post/7090940938184294407
Recomendado
Clasificación