0.1 + 0.2 精度丢失深究
JavaScript 运算符分为许多种,以下就是我们的
JavaScript 运算符种类
算数运算符:+加,-减,*乘,/除,%取余,-(一元取反,也可以说是负),++自加,--自减。
等同全同运算符:==、===、!==、!===
比较运算符:>、<、>=、<=
字符串运算符:>,<,<=,>=,=,+
逻辑运算符:&&、 ||、 !
赋值运算符:=、+=、*=、-=、/=
位运算符:&(与运算)、|(或运算)、^(异或运算)、~(非运算)、>>(带符号的右位移)、>>>(无符号的(用 0 补足的)右位移)、<< (左位移)
今天我们要说的是 JavaScript 中一个比较奇怪的现象,我们直接看下面例子。
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.3); // 0.4
console.log(0.2 + 0.3); // 0.5
console.log(0.15 + 0.15); // 0.3我们发现一个非常奇怪的现象,0.1 + 0.2 != 0.3,而 0.15 + 0.15 却等于了 0.3,这是为什么呢? 这个问题我非常喜欢拿来当做面试题对前端面试者的考察。
0.1 + 0.2 不等于 0.3 的原因
首先让我们了解一下 JavaScript 中的 Number 类型。
在 JavaScript 中,整数和浮点数都属于 Number 数据类型,所有的数字都是以 64 位浮点数形式储存,也就是双精度浮点数,即便是整数也是如此。

十进制小数转换为二进制小数,用 2 乘 10 进制小数,可以得到积,将积的整数部分取出,再用 2 乘余下的小数部分,又得到一个积, 再讲积的整数部分取出,如此进行,知道积中的小数部分为零,此时 0 或 1 为二进制的最后一位。或者达到所要求的精度为止。
下面看两个例子:
由于尾数只有 52 位,所以对于 0.1 和 0.2 转换后的二进制如下:
我们看下这两个二进制相加
我们可以看到,当十进制小数的二进制表示的有限数字超过 52 位时,在 JavaScript 里是不能精确存储的,这时候就存在舍入误差(Round-off error)。
那么我们如何解决呢?
开源的库:bigInt
Number.toFixed 保留指定长度的小数,会四舍五入,不够准确,但可以解决 0.1+0.2 的问题。
各自乘以 10 的 N 次方后,再处于 10 的 N 次方。 N > 1。
Number.EPSILON
由浮点数精度衍生出来的还有 JAVA 的 long 类型,当超出一定范围后会精度丢失。 我们通过在请求接口的时候,对数据进行一次处理
参考文章及发现的有趣 coder:
最后更新于
这有帮助吗?