为什么更改总和顺序会返回不同的结果?
在数学中,加法本质上是关联的。结合律规定,无论加法的顺序如何,求和的结果都保持不变。当加数是整数时,所有编程语言都是如此。但是,当加数是浮点数时,行为会略有不同。
当今使用的大多数 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