📜  为什么更改总和顺序会返回不同的结果?

📅  最后修改于: 2022-05-13 01:56:33.395000             🧑  作者: Mango

为什么更改总和顺序会返回不同的结果?

在数学中,加法本质上是关联的。结合律规定,无论加法的顺序如何,求和的结果都保持不变。当加数是整数时,所有编程语言都是如此。但是,当加数是浮点数时,行为会略有不同。

当今使用的大多数 CPU 都使用 IEEE 754 二进制浮点标准,当十进制数存储为二进制值时,该标准会导致不准确性。观察到总和结果的变化是因为当我们改变顺序时,存储在内存中的中间值也会发生变化,因此最终结果也会发生变化。让我们考虑以下示例,该示例显示了在更改顺序时如何获得不同的输出。

例子:

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);


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);


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);


输出:

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

解决方案:此问题的解决方案是使用BigDecimal类。 JavaScript 中的此类表示任意精度的浮点数。 BigDecimal使得在数学运算中对浮点数进行舍入很重要,其中更改顺序可能会更改结果。这个包需要使用require函数导入到程序中。

可以使用以下npm命令安装该软件包。

npm install js-big-decimal

方法 1:该包包含一个内置的add()方法,该方法接受两个字符串参数,将它们相加,然后返回四舍五入的结果。这可用于正确添加多个数字。

例子:

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);

输出:

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

方法 2:另一种方法是使用 BigDecimal 类的实例属性。 new运算符用于创建 BigDecimal 数字的实例。 add() 方法调用一个实例并将另一个实例作为参数。第二个 add() 方法由第一个 add() 方法返回的结果调用。最后,getValue() 方法用于获取 BigDecimal 数字的字符串值。正如所观察到的,所有三种数字排列的加法结果是相同的。

例子:

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);

输出:

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