js小数运算出现多位小数如何解决
和大家分享一个有趣的测试:
0.1+0.2==0.3//false
顿时郁闷,好吧!原来0.1+0.2变成:0.30000000000000004
再来一个2.4/0.8=>2.9999999999999996没办法换种方式,都转换成整数(2.4*100)/(0.8*100)
10.22现在要减去0.11结果值又出现了很多的小数10.110000000000001,然后我就用了toFixed方法来过滤小数,但是不知道跟前面那种转换成整数后再执行哪种效率高,好!还是试下再说吧!
vardate1=newDate(); for(vari=0;i<10000;i++){ varresult1=(10.22-0.11).toFixed(2); } alert(newDate()-date1);//效率低 vardate2=newDate(); for(varj=0;j<10000;j++){ varresult2=(10.22*1000-0.11*1000)/1000; } alert(newDate()-date2);//效率高 alert(0.1+0.2==0.3);//既然返回false alert(0.1+0.2);//既然返回0.30000000000000004 alert(parseFloat(0.1)+parseFloat(0.2));//还是返回0.30000000000000004
查了一些资料,一是JavaScript浮点数计算的Bug,另一个是和计算机最终转换成二进制计算有关系,但是为什么不是所有小数都会有这种现象,目前我也不清楚,有时间再去深入研究一下。
解决方法:
解决这种问题两种方法,第一种就是利用JavaScript的toFixed(n)方法,直接获取N位小数,不过,个人觉得这种方法在数据精度上会有一些问题。如果数据精度要求不高的话可以使用。
alert((0.1+0.2).toFixed(1));
第二种方法就是自己编写运算方法。以下是自定义加法函数,使用此方法进行相加会避免上面问题。
//自定义加法运算 functionaddNum(num1,num2){ varsq1,sq2,m; try{ sq1=num1.toString().split(".")[1].length; } catch(e){ sq1=0; } try{ sq2=num2.toString().split(".")[1].length; } catch(e){ sq2=0; } m=Math.pow(10,Math.max(sq1,sq2)); return(num1*m+num2*m)/m; } alert(addNum(0.1,0.2));
当然,简单一点也可以写成:alert((num*3+10*3)/3);这样也不会出现N多位小数。
alert((num*3+10*3)/3);与alert(num+10);这两种写法计算机在底层转换成二进制运算是有区别的,或许这就是出现上述问题的原因,还有待我们去深入研究,大家可以多多讨论。