经常有同学面对这样一个面试题:JavaScript 中 0.1 + 0.2 === 0.3 吗?答案是 false。很多同学第一次面对这种问题,完全不知道什么问题,然后试了一下 0.3 + 0.4 === 0.7 竟然是正确的,这到底是怎么回事呢?
实际上,不光是 JavaScript,只要是基于IEEE 754标准的语言,都会有这个问题。IEEE 754是在 1985年建立的浮点数计算标准,它定义了浮点数的算术格式、交换格式、舍入规则、操作和异常处理。如果用二进制表示浮点数的0.1和0.2,如下所示:
0.1 === 0.00011001100...
0.2 === 0.00110011001...
复制代码
无论是0.1还是0.2,这两个数字都不是整数,我们没办法准确地表示它们,只能通过无限循环小数尝试接近他的真实值,所以可以得出:
0.3 === 0.010011001100...
复制代码
而 0.1 和 0.2 使用单精度浮点数表示实际值为
0.1 === 0.100000001490116119384765625
0.2 === 0.200000002980232238769531257
复制代码
所以
0.1 + 0.2 约为 0.300000004
复制代码
如果我们需要去完成 0.1 + 0.2 与 0.3 的比较,我们正确的姿势是什么呢?实际上,正确的姿势是使用JavaScript 提供的最小精度值:
Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON // true
复制代码
检查等式左右两边差的绝对值是否小于最小精度,才是正确的比较浮点数的方法,这样比较就是正确的了。