¿Por qué cambiar el orden de la suma devuelve un resultado diferente?

En matemáticas, la suma es de naturaleza asociativa. La ley asociativa establece que el resultado de la suma sigue siendo el mismo independientemente del orden de los sumandos. Esto es cierto para todos los lenguajes de programación cuando los sumandos son números enteros. Sin embargo, existe una ligera diferencia en el comportamiento cuando los sumandos son números de coma flotante.

La mayoría de las CPU en uso hoy en día utilizan el estándar binario de coma flotante IEEE 754, que introduce imprecisiones cuando los números decimales se almacenan como valores binarios. El cambio en el resultado de la suma se observa porque cuando cambiamos el orden, el valor intermedio almacenado en la memoria también cambia y, por lo tanto, el resultado final también cambia. Consideremos el siguiente ejemplo que muestra cómo se obtienen diferentes salidas cada vez que se cambia el orden.

Ejemplo:

Javascript

var a = 10.54;
var b = 9.99;
var c = 1.01;
  
console.log("a+b+c", a+b+c);
console.log("b+c+a", b+c+a);
console.log("b+a+c", b+a+c);

Producción:

a+b+c 21.540000000000003
b+c+a 21.54
b+a+c 21.540000000000003

Solución: una solución a este problema es usar la clase BigDecimal . Esta clase en JavaScript representa números de punto flotante de precisión arbitraria. BigDecimal hace que sea un punto para redondear los números de coma flotante en operaciones matemáticas donde cambiar el orden puede cambiar el resultado. Este paquete necesita ser importado al programa usando la función require

El paquete se puede instalar usando el siguiente comando npm .

npm install js-big-decimal

Enfoque 1: el paquete contiene un método add() incorporado que toma dos argumentos de string, los agrega y devuelve el resultado redondeado. Esto se puede usar para sumar correctamente varios números.

Ejemplo:

Javascript

var bigDecimal = require('js-big-decimal');
  
var a = "10.54";
var b = "9.99";
var c = "1.01";
  
console.log("a = ", a);
console.log("b = ", b);
console.log("c = ", c);
  
var ab = "" + bigDecimal.add(a, b);
var abc = bigDecimal.add(ab, c);
console.log("a+b+c = ", abc);
  
var bc = "" + bigDecimal.add(b, c);
var bca = bigDecimal.add(bc, a);
console.log("b+c+a = ", bca);
  
var ba = "" + bigDecimal.add(b, a);
var bac = bigDecimal.add(ba, c);
console.log("b+a+c = ", bac);

Producción:

a =  10.54
b =  9.99
c =  1.01
a+b+c =  21.54
b+c+a =  21.54
b+a+c =  21.54

Enfoque 2: Otro enfoque es usar la propiedad de instancia de la clase BigDecimal. El operador new se usa para crear instancias de los números BigDecimal. El método add() invoca una instancia y toma otra instancia como parámetro. El segundo método add() es invocado por el resultado devuelto por el primer método add(). Finalmente, el método getValue() se usa para obtener el valor de string del número BigDecimal. Como se observa, el resultado de la suma para los tres arreglos de números es el mismo.

Ejemplo:

Javascript

var bigDecimal = require('js-big-decimal');
  
var a = new bigDecimal("10.54");
var b = new bigDecimal("9.99");
var c = new bigDecimal("1.01");
  
var abc = (a.add(b).add(c)).getValue();
var bca = (b.add(c).add(a)).getValue();
var bac = (b.add(a).add(c)).getValue();
  
console.log("a+b+c = ", abc);
console.log("b+c+a = ", bca);
console.log("b+a+c = ", bac);

Producción:

a+b+c =  21.54
b+c+a =  21.54
b+a+c =  21.54

Publicación traducida automáticamente

Artículo escrito por Shreyasi_Chakraborty y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

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