文章目录
前言
在学习JavaScript的时候,会遇到这样的问题,0.1+0.2的值大于0.3?
因为在JS中,浮点数是使用64位固定长度来表示的,其中的1位表示符号位,11位用来表示指数位,剩下的52位尾数位,由于只有52位表示尾数位。
1.小数中的十进制转二进制
十进制的小数转换为二进制,主要是小数部分乘以2,取整数部分依次从左往右放在小数点后,直至小数点后为0。例如十进制的0.125,要转换为二进制的小数。
2. 0.1+ 0.2 =0.3?
这是JS初学时,碰到的一个出乎意料的结果,0.1
+0.2
的值大于0.3
,在生活中几乎每个人都知道0.1
+0.2
=0.3
,但为什么JS中的0.1
+0.2
的值大于0.3
,通过上面介绍的方法我们将小数转换成二进制一探究竟。0.1
转换成二进制是一个无限循环的数,即0.0001100110011001100......
(1100循环),由于只能存储52位尾数位,所以就出现了精度缺失,将0.1
存储在内存中的十进制再转换为二进制的结果就与之前的0.1
不相等。
// 0.1 和 0.2 都转化成二进制后再进行运算
0.00011001100110011001100110011001100110011001100110011010 +
0.0011001100110011001100110011001100110011001100110011010 =
0.0100110011001100110011001100110011001100110011001100111
// 转成十进制正好是 0.30000000000000004
3.0.2+0.3=0.5
同样的会出现精度缺失,但为什么0.2
+0.3
=0.5
,而不会向0.1
+0.2
一样呢?
0.2 转换为二进制即0.0100110011001100110011001100110011001100110011001101
0.3 转换为二进制即0.001100110011001100110011001100110011001100110011001101
进行相加后0.10000000000000000000000000000000000000000000000000001
因为相加后的尾数超过了52位,所以就变成了
0.1000000000000000000000000000000000000000000000000000
它的值刚好为0.5
4. 为什么在console.log(0.1)的时候还是0.1呢?
通过上面的介绍0.1
在转换时候会有精度缺失的问题,所得到的值大于0.1
本身,console.log(0.1)
时,它的值为什么有变成了0.1
?这是因为,在转换的过程中发生了取近似值,所以打印出来的是一个近似值的字符串。