较小的数值
二进制浮点数最大的问题(不仅 JavaScript,所有遵循 IEEE 754 规范的语言都是如此),是 会出现如下情况:
0.1 + 0.2 === 0.3; // false
从数学角度来说,上面的条件判断应该为 true,可结果为什么是 false 呢?
简单来说,二进制浮点数中的 0.1 和 0.2 并不是十分精确,它们相加的结果并非刚好等于 0.3,而是一个比较接近的数字 0.30000000000000004,所以条件判断结果为 false。
有人认为,JavaScript 应该采用一种可以精确呈现数字的实现方式。一直以 来出现过很多替代方案,只是都没能成为标准,以后大概也不会。这个问题 看似简单,实则不然,否则早就解决了。
问题是,如果一些数字无法做到完全精确,是否意味着数字类型毫无用处呢?答案当然是 否定的。
在处理带有小数的数字时需要特别注意。很多(也许是绝大多数)程序只需要处理整数, 最大不超过百万或者万亿,此时使用 JavaScript 的数字类型是绝对安全的。
那么应该怎样来判断 0.1 + 0.2 和 0.3 是否相等呢?
最常见的方法是设置一个误差范围值,通常称为“机器精度”(machine epsilon),对 JavaScript 的数字来说,这个值通常是 2^-52 (2.220446049250313e-16)。
从 ES6 开始,该值定义在 Number.EPSILON 中,我们可以直接拿来用,也可以为 ES6 之前 的版本写 polyfill:
if (!Number.EPSILON) {
Number.EPSILON = Math.pow(2,-52);
}
可以使用 Number.EPSILON 来比较两个数字是否相等(在指定的误差范围内):
能够呈现的最大浮点数大约是 1.798e+308(这是一个相当大的数字),它定义在 Number. MAX_VALUE 中。最小浮点数定义在 Number.MIN_VALUE 中,大约是 5e-324,它不是负数,但 无限接近于 0 !