Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/459.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么具有精确值的浮点数之和仍然取决于顺序?_Javascript_Floating Point_Floating Accuracy - Fatal编程技术网

Javascript 为什么具有精确值的浮点数之和仍然取决于顺序?

Javascript 为什么具有精确值的浮点数之和仍然取决于顺序?,javascript,floating-point,floating-accuracy,Javascript,Floating Point,Floating Accuracy,假设我有3个浮点数,可以用浮点数精确表示: var a=0.1000000000000000055511151231257827021181583404541015625; var b=0.200000000000000011102230246251565404236316680908203125; var c=0.299999999999999988897769753748434595763683319091796875; 它们是存储在float中的0.1、0.2和0.3的实际值。我认为a+

假设我有3个浮点数,可以用浮点数精确表示:

var a=0.1000000000000000055511151231257827021181583404541015625;
var b=0.200000000000000011102230246251565404236316680908203125;
var c=0.299999999999999988897769753748434595763683319091796875;
它们是存储在float中的0.1、0.2和0.3的实际值。我认为a+b+c应该等于c+b+a,因为a、b和c都已经四舍五入,并且都是精确的值,它们的总和不应该取决于顺序,但现在我测试了它不是:

var a=0.10000000000000055115123125782702118158340454015625;
var b=0.2000000000011102230246256540423631668090908203125;
变量c=0.29999999999988897769753748434595763683319091796875;
console.log(a+b+c==c+b+a)总和不精确
你认为精确值之和是精确的假设是错误的

浮点运算使用固定格式的某些位数(例如24位二进制数字表示
浮点
)。两个24位数字的数学和可能有25位,因此需要舍入以表示24位以内(和指数)

此外,当两个指数不同的数字相加时,其中一个数字相对于另一个数字偏移。由于偏移,总和可能有额外的数字,因此必须再次四舍五入

按不同顺序添加数字时,结果舍入可能不同

不精确和的例子 这些示例使用三位二进制有效位

在本例中,加法将带入一个新列:

1.10 • 23 1.01 • 23 ―――――――――― 10.11 • 23 Exact sum, too many digits, must be rounded. 11.0 • 23 Sum rounded to three digits. 1.10 • 24 Rounded sum, exponent adjusted to normalize significand. 1.10 • 23 1.01 • 23 ―――――――――― 10.11•23精确和(位数过多)必须四舍五入。 11.0•23和四舍五入为三位数字。 1.10•24四舍五入和,调整指数以规范化有效位。 在此示例中,数字具有不同的指数,为此进行调整会将数字移动到新列中:

1.11 • 23 1.01 • 25 Different exponent requires adjustment. 0.0111 • 25 Adjusted to match exponent. 1.01 • 25 ―――――――――――― 1.1011 • 25 Exact sum, too many digits, must be rounded. 1.11 • 25 Rounded sum. 1.11 • 23 1.01•25不同的指数需要调整。 调整0.0111•25以匹配指数。 1.01 • 25 ―――――――――――― 1.1011•25精确和,数字太多,必须四舍五入。 1.11•25四舍五入和。 非结合和的例子 现在,我们可以用不同的方法把三个数字相加,并看到不同的和被产生

我们将比较(1.10•20+1.10•20)+1.00•24)和1.10•20+(1.10•20+1.00•24)

对于第一个表达式,我们添加第一个和第二个操作数,然后添加第三个操作数:

Add first and second operands: 1.10 • 20 First operand. 1.10 • 20 Second operand. ―――――――――― 11.00 • 20 Exact sum, too many digits, must be rounded. 11.0 • 20 Rounded sum, must be normalized. 1.10 • 21 Normalized, rounded sum. Add previous result and third operand: 1.10 • 21 Previous result. 1.00 • 24 Third operand. Exponents do not match, so adjust and then add: 0.00110 • 24 Previous result adjusted to match exponent. 1.00 • 24 Third operand. ―――――――――――― 1.00110 • 24 Exact sum, too many digits, must be rounded. 1.01 • 24 Rounded sum. 添加第一个和第二个操作数: 1.10•20第一个操作数。 1.10•20秒操作数。 ―――――――――― 11.00•20精确和,数字太多,必须四舍五入。 11.0•20四舍五入和,必须标准化。 1.10•21标准化、四舍五入和。 将上一个结果和第三个操作数相加: 1.10•21先前的结果。 1.00•24第三个操作数。 指数不匹配,请调整,然后添加: 0.00110•24之前的结果调整为匹配指数。 1.00•24第三个操作数。 ―――――――――――― 1.00110•24精确和,数字太多,必须四舍五入。 1.01•24四舍五入和。 对于第二个表达式,我们添加第二个和第三个操作数,然后添加第一个操作数:

Add second and third: 1.10 • 20 Second operand. 1.00 • 24 Third operand. Exponents do not match, so adjust, then add: 0.000110 • 24 Second operand adjusted to match exponent. 1.00 • 24 Third operand. ―――――――――――――― 1.000110 • 24 Exact sum, too many digits, must be rounded. 1.00 • 24 Rounded sum. Add first operand and previous result: 1.10 • 20 First operand. 1.00 • 24 Previous result. Exponents do not match, so adjust and then add: 0.000110 • 24 First operand adjusted to match exponent. 1.00 • 24 Previous result. ――――――――――――― 1.000110 • 24 Exact sum, too many digits, must be rounded. 1.00 • 24 Rounded sum. 添加第二个和第三个: 1.10•20秒操作数。 1.00•24第三个操作数。 指数不匹配,请调整,然后添加: 调整0.000110•24秒操作数以匹配指数。 1.00•24第三个操作数。 ―――――――――――――― 1.000110•24精确和,数字太多,必须四舍五入。 1.00•24四舍五入和。 将第一个操作数和上一个结果相加: 1.10•20第一个操作数。 1.00•24之前的结果。 指数不匹配,请调整,然后添加: 0.000110•24调整第一个操作数以匹配指数。 1.00•24之前的结果。 ――――――――――――― 1.000110•24精确和,数字太多,必须四舍五入。 1.00•24四舍五入和。
第一个表达式产生1.01•24,而第二个表达式产生1.00•24。因此,操作数的加法顺序会影响结果。

我的假设是加法的中间值可能有不同的舍入点错误。例如,
a+b
可能导致舍入错误。而
b+c
可能不会,或者结果值与最终值相加时可能会导致不同类型的浮点错误。添加括号可以使操作顺序和中间值更加清晰:

(a+b)+c


(c+b)+a

可能的重复实际上,总和可能高达48位,这取决于尾数(有效位)必须如何移位才能获得相同的指数。但事实上,结果往往必须四舍五入+1.