一.0.1+0.2的结果
console.log(0.1+0.2); //0.30000000000000004
为什么0.1+0.2不等于0.3而是0.30000000000000004呢?
原因:
因为浮点数运算的精度问题。在计算机运行过程中,需要将数据转化成二进制,然后再进行计算。
IEEE二进制浮点数算术标准(ANSI/IEEE Std 754-1985)
js中的Number类型遵循IEEE 754标准,在IEEE 754标准的64位浮点数相加,因为浮点数自身小数位数的限制而截断的二进制在转化为十进制,就变成0.30000000000000004,所以在计算时会产生误差。
二、0.1+0.2的运算过程
算法:
0.1*2=0.2 ----------- 取出整数部分0
0.2*2=0.4 ----------- 取出整数部分0
0.4*2=0.8 ----------- 取出整数部分0
0.8*2=1.6 ----------- 取出整数部分1
0.6*2=1.2 ----------- 取出整数部分1
0.2*2=0.4 ----------- 取出整数部分0
0.4*2=0.8 ----------- 取出整数部分0
0.8*2=1.6 ----------- 取出整数部分1
0.6*2=1.2 ----------- 取出整数部分1
我们可以发现在无限循环
0.1的二进制结果 0.0 0011 0011 0011 ..... "0011的无限循环"
0.2的二进制结果 0.0011 0011 0011 0011 .... "0011的无限循环"
取52位进行计算
0.1 = 0.0001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001
0.2 = 0.0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011
计算的结果是: 0.0100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 ...也是无限循环
将二进制转换为十进制:
浮点型数据存储转换为十进制的话 只会取前17位
0.300000000000000044408920958 .... = 0.30000000000000004(四舍五入)
所以0.1+0.2的结果是等于0.30000000000000004
三、解决方法
方法一、将浮点数转化成整数计算
var v = (0.1*10+0.2*10)/10;
//这样计算把小数转整数再变为小数
console.log(v); //0.3
方法二、js的Number对象有一个保留小数位数的方法:toFixed();传入一个需要保留的位数
var v = parseFloat((0.1+0.2).toFixed(1))
console.log(v); //0.3