1.产生原因
- JS 采用的是
双精度版本
, 即IEEE 754 双精度版本(64位)
,这个版本就存在精度问题,就导致了上边这种情况。 - 在计算机中,数字无论是定点数还是浮点数都是以
多位二进制
的方式进行存储的。
2.内部原理
- 我们计算机的信息全部转化为
二进制进行
存储的,那么0.1的二进制表示的是一个无限循环小数,该版本的 JS 采用的是浮点数标准需要对这种无限循环的二进制进行截取,从而导致了精度丢失
,造成了0.1不再是0.1,截取之后0.1变成了 0.100…001,0.2变成了0.200…002。所以两者相加的数大于
0.3。 - 在0.1 + 0.2这个式子中,0.1和0.2都是近似表示的,在他们相加的时候,两个近似值进行了计算,导致最后得到的值是0.30000000000000004,此时对于JS来说,其不够近似于0.3,于是就出现了 0.1 + 0.2 != 0.3 $这个现象。 当然,也并非所有的近似值相加都得不到正确的结果。
-
有时两个近似值进行计算的时候,得到的值是在JS的近似范围内的,于是就可以得到正确答案。至于哪些值计算后能得到正确结果,哪些不能,我们也不需要去记。
-
最好的方法就是我们想办法规避掉这类小数计算时的精度问题就好了,那么最常用的方法就是将浮点数转化成整数计算。因为整数都是可以精确表示的。
扩展
-
那好,既然0.1不等于0.1了,那为什么我在控制台上输出console.log(0.1)还等于0.1呢?
-
因为在输入内容进行转换的时候,
二进制
转换成十进制
,然后十进制转换成字符串,在这个转换的过程中发生了取近似值
,所以打印出来的是一个近似值。