js浮点数精度问题(js计算中遇到的坑)

来源:互联网 发布:迅龙数据恢复软件 免费 编辑:程序博客网 时间:2024/06/05 07:51

转自:http://talentluke.iteye.com/blog/1767138

大多数语言在处理浮点数的时候都会遇到精度问题,但是在JS里似乎特别严重,来看一个例子

alert(45.6*13);

结果居然是592.800000000001,当然加法之类的也会有这个问题

那这是js的错误吗?

当然不是,你的电脑做着正确的二进制浮点运算,但问题是你输入的是十进制的数,电脑以二进制运算,这两者并不是总是转化那么好的,有时候会得到正确的结果,但有时候就不那么幸运了

alert(0.7+0.1);//输出0.7999999999999999alert(0.6+0.2);//输出0.8

你输入两个十进制数,转化为二进制运算过后再转化回来,在转化过程中自然会有损失了

但一般的损失往往在乘除运算中比较多,而JS在简单的加减法里也会出现这类问题,你也看到了,这个误差也是非常小的,但是却是不该出现的

那该怎么解决呢,ECMA4似乎给了解决方法,但是现在倒不是那么实用的

一种方法,比如0.7+0.1,先把0.1和0.7都乘10,加完之后再除10

另外可以自己写点函数来解决这个问题,自己百度谷歌一下应该有很多,但是最好还是不要用JS做一些复杂的浮点运算,毕竟JS更多的作用不在于此

<script type="text/javascript">    // 两个浮点数求和    function accAdd(num1,num2){       var r1,r2,m;       try{           r1 = num1.toString().split('.')[1].length;       }catch(e){           r1 = 0;       }       try{           r2=num2.toString().split(".")[1].length;       }catch(e){           r2=0;       }       m=Math.pow(10,Math.max(r1,r2));       // return (num1*m+num2*m)/m;       return Math.round(num1*m+num2*m)/m;    }        // 两个浮点数相减    function accSub(num1,num2){       var r1,r2,m;       try{           r1 = num1.toString().split('.')[1].length;       }catch(e){           r1 = 0;       }       try{           r2=num2.toString().split(".")[1].length;       }catch(e){           r2=0;       }       m=Math.pow(10,Math.max(r1,r2));       n=(r1>=r2)?r1:r2;       return (Math.round(num1*m-num2*m)/m).toFixed(n);    }    // 两数相除    function accDiv(num1,num2){       var t1,t2,r1,r2;       try{           t1 = num1.toString().split('.')[1].length;       }catch(e){           t1 = 0;       }       try{           t2=num2.toString().split(".")[1].length;       }catch(e){           t2=0;       }       r1=Number(num1.toString().replace(".",""));       r2=Number(num2.toString().replace(".",""));       return (r1/r2)*Math.pow(10,t2-t1);    }        function accMul(num1,num2){       var m=0,s1=num1.toString(),s2=num2.toString();     try{m+=s1.split(".")[1].length}catch(e){};    try{m+=s2.split(".")[1].length}catch(e){};    return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m);    }      </script>      <script>    document.write("使用js原生态方法");    document.write("<br/> 1.01 + 1.02 ="+(1.01 + 1.02));    document.write("<br/> 1.01 - 1.02 ="+(1.01 - 1.02));    document.write("<br/> 0.000001 / 0.0001 ="+(0.000001 / 0.0001));    document.write("<br/> 0.012345 * 0.000001 ="+(0.012345 * 0.000001));    document.write("<br/><hr/>");    document.write("<br/>使用自定义方法");    document.write("<br/> 1.01 + 1.02 ="+accAdd(1.01,1.02));    document.write("<br/> 1.01 - 1.02 ="+accSub(1.01,1.02));    document.write("<br/> 0.000001 / 0.0001 ="+accDiv(0.000001,0.0001));    document.write("<br/> 0.012345 * 0.000001 ="+accMul(0.012345,0.000001));    </script>


2 0