JavaScript 为什么改变求和的顺序会得到不同的结果

为什么改变求和的顺序会得到不同的结果

在数学中,加法具有结合性质。结合律指出,无论加数的顺序如何,求和的结果都保持不变。当加数为整数时,所有的编程语言都遵循这个规则。然而,当加数为浮点数时,行为会稍有不同。

今天大多数使用的CPU都采用IEEE 754二进制浮点标准,该标准在将十进制数存储为二进制值时引入了一些不准确性。当我们改变顺序时,观察到求和结果的变化是因为存储在内存中的中间值也会发生变化,从而导致最终结果也发生变化。让我们来看下面的示例,展示了在改变顺序时如何获得不同的输出。

示例:

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

输出:

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

解决方案: 解决这个问题的方法是使用 BigDecimal 类。这个JavaScript类表示任意精度的浮点数。在数学运算中,BigDecimal类会将浮点数四舍五入,以确保改变顺序不会改变结果。需要使用 required 函数将这个包导入到程序中。

这个包可以使用以下 npm 命令来安装。

npm install js-big-decimal

方法1

该包含有内建的 add() 方法,它接受两个字符串参数,将它们相加并返回结果的四舍五入值。这可以用于正确地相加多个数字。

示例: 这个示例展示了上述方法。

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数字的字符串值。观察到,所有三种数字排列的相加结果都是相同的。

示例: 该示例展示了上述方法。

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

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程