同样的方式1/3
不能用十进制精确表示,0.1
不能用二进制精确表示,而Javascript数字是二进制浮点值。
在 Javascript中0.2 + 0.1
返回0.30000000000000004
.
在浏览器控制台中尝试。
实际上,53 位可用于将尾数存储在 Javascript 64 位浮点值0.1
中,二进制的十进制值四舍五入到 53 位的精度
0.00011001100110011001100110011001100110011001100110011010
,当转换回十进制时正好是
0.1000000000000000055511151231257827021181583404541015625
.
我们可以使用toFixed
Firefox 来展示这一点(其他浏览器将参数限制为 20):
(0.1).toFixed(55)
返回
0.1000000000000000055511151231257827021181583404541015625
。
同样,二进制的十进制值0.2
四舍五入到 53 位的精度,然后再转换回十进制就是
0.200000000000000011102230246251565404236316680908203125
.
0.1
如果我们将and的两个二进制表示相加0.2
,四舍五入到 53 位,然后再转换回十进制,我们就得到了
0.3000000000000000444089209850062616169452667236328125
.
所以 Javascript 中0.1
+的结果0.2
不是0.3
但是,小数点后 17 位是0.30000000000000004
.
事实上,0.3
无论如何都不能用二进制本身精确表示。
它实际上存储为十进制值的二进制等价物,
0.29999999999999993338661852249060757458209991455078125
这就是 Javascript 中
0.2 + 0.1 == 0.3
返回false
.
十进制到二进制
十进制数只能用二进制精确表示,如果2
它是用最低术语表示为简单分数时数字的分母的唯一质因数。
例如,
0.1
是1/10
, 并且10
有素因数2
和5
,所以没有精确的表示。
0.5
是1/2
,而唯一的素因子2
是2
,所以它可以被精确地表示。