Mik*_*eNQ 2 javascript rounding data-conversion
我遇到了一些混乱的手术。
var a = 0.1;
var b = 0.2;
var c = 0.3;
console.log(a); // 0.1
console.log(b); // 0.2
console.log(c); // 0.3
Run Code Online (Sandbox Code Playgroud)
但,
consolo.log(a+b+c) // 0.6000000000000001.
Run Code Online (Sandbox Code Playgroud)
而
console.log(a+(b+c)) // 0.6
Run Code Online (Sandbox Code Playgroud)
我知道Javascript使用二进制浮点数,因此无法准确表示0.1、0.2、0.3,但是(b + c)的括号是什么?这里有什么转换或四舍五入吗?
非常感谢,
JavaScript数字在IEEE754中表示为双精度二进制浮点(binary64),以科学计数法表示,并以2为基数。一个数字有64位,它们分为3部分(从高到低):

因此,浮点数计算如下: (-1) ^ sign * (2 ^ exponent) * significand
注意:由于科学计数法的指数部分可能为正也可能为负,因此应通过从11位指数值中减去指数偏差(中间值1023)来计算binary64数字的实际指数值。
该标准还将有效值定义为介于0 [1, 2).和1 之间。由于有效部分的第一个数字始终为1,因此在上图中暗含但未显示。因此,基本上有效部分实际上具有53位精度,而上图中的红色部分只是尾数或小数部分。
根据该标准,不难找到binary64格式的0.1、0.2和0.3(您可以手动或通过此工具http://bartaz.github.io/ieee754-visualization/进行计算):
0.1
0 01111111011 1001100110011001100110011001100110011001100110011010
Run Code Online (Sandbox Code Playgroud)
用科学的符号来说
1.1001100110011001100110011001100110011001100110011010 * 2e-4
Run Code Online (Sandbox Code Playgroud)
注意:有效数字部分为二进制格式,以下数字为相同格式
0.2
0 01111111100 1001100110011001100110011001100110011001100110011010
Run Code Online (Sandbox Code Playgroud)
用科学的符号来说
1.1001100110011001100110011001100110011001100110011010 * 2e-3
Run Code Online (Sandbox Code Playgroud)
0.3
0 01111111101 0011001100110011001100110011001100110011001100110011
Run Code Online (Sandbox Code Playgroud)
用科学的符号来说
1.0011001100110011001100110011001100110011001100110011 * 2e-2
Run Code Online (Sandbox Code Playgroud)
第1步 -对齐指数
第2步 -将有效位数相加
如果相加的有效位数不满足[1,2)要求,则将其移至该范围并更改指数
转移后,有效位数应四舍五入。
如上所述,0.1具有指数-4和0.2具有指数-3,因此需要首先进行指数对齐:
转变0.1从
1.1001100110011001100110011001100110011001100110011010 * 2e-4
Run Code Online (Sandbox Code Playgroud)
至
0.1100110011001100110011001100110011001100110011001101 * 2e-3
Run Code Online (Sandbox Code Playgroud)
然后添加有效位数
0.1100110011001100110011001100110011001100110011001101
Run Code Online (Sandbox Code Playgroud)
与
1.1001100110011001100110011001100110011001100110011010
Run Code Online (Sandbox Code Playgroud)
我们得到了重要的价值:
10.0110011001100110011001100110011001100110011001100111
Run Code Online (Sandbox Code Playgroud)
但它不在范围内,[1,2)因此需要将其(向上舍入)右移至:
1.0011001100110011001100110011001100110011001100110100 (* 2e-2)
Run Code Online (Sandbox Code Playgroud)
然后将其添加到
0.3 (1.0011001100110011001100110011001100110011001100110011 * 2e-2)
Run Code Online (Sandbox Code Playgroud)
我们得到:
10.0110011001100110011001100110011001100110011001100111 * 2e-2
Run Code Online (Sandbox Code Playgroud)
同样,我们需要平移并四舍五入,最后得到值:
1.0011001100110011001100110011001100110011001100110100 * 2e-1
Run Code Online (Sandbox Code Playgroud)
恰好是0.6000000000000001(十进制)的值
使用相同的工作流程,您可以计算出0.1 +(0.2 + 0.3)
该网页http://bartaz.github.io/ieee754-visualization/可以帮助您快速将十进制数转换为binary64格式,您可以使用它来验证计算步骤。
如果要处理单个精度二进制浮点数,请参考此工具:http : //www.h-schmidt.net/FloatConverter/IEEE754.html