免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1556 | 回复: 1
打印 上一主题 下一主题

JavaScript浮点數运算的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-12 21:33 |只看该作者 |倒序浏览
JavaScript浮点數运算的问题












遇到個js浮點數運算,結果的精確位數過長的問題,下面是在網上查找的解決方法,供大家一起學習和參考。

问题:

  37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数)
  我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.08499999999998
  怎么会这样,两个只有一位小数的数字相乘,怎么可能多出这么小数点出来。
  我Google了一下,发现原来这是JavaScript浮点运算的一个bug。
  比如:7*0.8 JavaScript算出来就是:5.6000000000000005

解决方法:网上找到了一些解决办法,就是重新写了一些浮点运算的函数。
  下面就把这些方法摘录下来,以供遇到同样问题的朋友参考:
程序代码
//除法函数,用来得到精确的除法结果
//说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
//调用:accDiv(arg1,arg2)
//返回值:arg1除以arg2的精确结果
  1. function accDiv(arg1,arg2){
  2.   var t1=0,t2=0,r1,r2;
  3.   try{t1=arg1.toString().split(".")[1].length}catch(e){}
  4.   try{t2=arg2.toString().split(".")[1].length}catch(e){}
  5.   with(Math){
  6.   r1=Number(arg1.toString().replace(".",""))
  7.   r2=Number(arg2.toString().replace(".",""))
  8.   return (r1/r2)*pow(10,t2-t1);
  9.   }
  10. }

  11. //给Number类型增加一个div方法,调用起来更加方便。
  12. Number.prototype.div = function (arg){
  13.   return accDiv(this, arg);
  14. }
复制代码
//乘法函数,用来得到精确的乘法结果
//说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
//调用:accMul(arg1,arg2)
//返回值:arg1乘以arg2的精确结果
  1. function accMul(arg1,arg2)
  2. {
  3.   var m=0,s1=arg1.toString(),s2=arg2.toString();
  4.   try{m+=s1.split(".")[1].length}catch(e){}
  5.   try{m+=s2.split(".")[1].length}catch(e){}
  6.   return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)
  7. }

  8. //给Number类型增加一个mul方法,调用起来更加方便。
  9. Number.prototype.mul = function (arg){
  10.   return accMul(arg, this);
  11. }
复制代码
//加法函数,用来得到精确的加法结果
//说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
//调用:accAdd(arg1,arg2)
//返回值:arg1加上arg2的精确结果
  1. function accAdd(arg1,arg2){
  2.   var r1,r2,m;
  3.   try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
  4.   try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
  5.   m=Math.pow(10,Math.max(r1,r2))
  6.   return (arg1*m+arg2*m)/m
  7. }

  8. //给Number类型增加一个add方法,调用起来更加方便。
  9. Number.prototype.add = function (arg){
  10.   return accAdd(arg,this);
  11. }
复制代码
//减法函数,用来得到精确的减法结果
//说明:javascript的减法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的减法结果。
//调用:accSubtr(arg1,arg2)
//返回值:arg1减去arg2的精确结果
  1. function accSubtr(arg1,arg2){
  2. var r1,r2,m,n;
  3. try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
  4. try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
  5. m=Math.pow(10,Math.max(r1,r2));
  6. //动态控制精度长度
  7. n=(r1>=r2)?r1:r2;
  8. return ((arg1*m-arg2*m)/m).toFixed(n);
  9. }
  10. //给Number类型增加一个subtr 方法,调用起来更加方便。
  11. Number.prototype.subtr = function (arg){
  12. return accSubtr(arg,this);
  13. }
复制代码
  在你要用的地方包含这些函数,然后调用它来计算就可以了。
  比如你要计算:7*0.8 ,则改成 (7).mul(  
  其它运算类似,就可以得到比较精确的结果。

论坛徽章:
0
2 [报告]
发表于 2011-12-24 20:04 |只看该作者
谢谢分享  希望于楼主多多交流
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP