如何定义 JavaScript 数字
JavaScript 数字用IEEE754 表示,它是双精度二进制浮点 (binary64),它是科学计数法,以 2 为基数。一个数有64位,分为3部分(从高位到低位):
- 第一位是符号:0 - 正数; 1 - 否定
- 接下来的 11 位是指数部分
- 最后 52 位用于尾数/小数
因此,浮点数计算为:(-1) ^ sign * (2 ^ exponent) * significand
注意:由于科学计数法的指数部分可以是正数或负数,所以二进制64数的实际指数值应通过减去指数偏差(即 11 位指数值的中间值 1023)。
标准中还定义了有效数字值在[1, 2).之间,因为有效数字部分的第一个数字总是1,所以在上图中是隐含的,没有给出。所以,基本上有效数部分实际上是53位精度,上图中红色部分只是尾数或小数部分。
二进制64格式的0.1、0.2和0.3
根据标准,不难找到 binary64 格式的 0.1、0.2 和 0.3(您可以手动计算,也可以通过此工具计算 http://bartaz.github.io/ieee754-visualization/):
0.1
0 01111111011 1001100110011001100110011001100110011001100110011010
科学记数法是
1.1001100110011001100110011001100110011001100110011010 * 2e-4
注意:有效数字部分为二进制格式,以下数字格式相同
0.2
0 01111111100 1001100110011001100110011001100110011001100110011010
科学记数法是
1.1001100110011001100110011001100110011001100110011010 * 2e-3
0.3
0 01111111101 0011001100110011001100110011001100110011001100110011
科学记数法是
1.0011001100110011001100110011001100110011001100110011 * 2e-2
将 2 个 binary64 数字相加的步骤
第 1 步 - 对齐指数
- 移动具有较小指数的数字的有效数字
- 有效位右移
- 对于每个有效位数移位将指数增加 1,直到两个指数相同
- 移位后,有效数字应向上舍入。
第 2 步 - 将有效数字相加
0.1 + 0.2 + 0.3 == 0.6000000000000001
如上所述,0.1 有指数-4,0.2 有指数-3,所以需要先做指数对齐:
将0.1 移出
1.1001100110011001100110011001100110011001100110011010 * 2e-4
到
0.1100110011001100110011001100110011001100110011001101 * 2e-3
然后加上有效位
0.1100110011001100110011001100110011001100110011001101
与
1.1001100110011001100110011001100110011001100110011010
我们得到相加的有效值:
10.0110011001100110011001100110011001100110011001100111
但它不在[1,2) 范围内,因此需要将其右移(向上舍入)到:
1.0011001100110011001100110011001100110011001100110100 (* 2e-2)
然后添加到
0.3 (1.0011001100110011001100110011001100110011001100110011 * 2e-2)
我们得到:
10.0110011001100110011001100110011001100110011001100111 * 2e-2
再次,我们需要移位和四舍五入,最后得到值:
1.0011001100110011001100110011001100110011001100110100 * 2e-1
正是0.6000000000000001(十进制)的值
使用相同的工作流程,您得到计算 0.1 + (0.2 + 0.3)
工具
本网页http://bartaz.github.io/ieee754-visualization/帮助您快速将十进制数转换为binary64格式,您可以使用它来验证计算步骤。
如果您正在处理单精度二进制浮点数,您可以参考这个工具:http://www.h-schmidt.net/FloatConverter/IEEE754.html