解决JS浮点数运算出现Bug的方法


Posted in Javascript onMarch 12, 2013

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的精确结果 
function accDiv(arg1,arg2){ 
var t1=0,t2=0,r1,r2; 
try{t1=arg1.toString().split(".")[1].length}catch(e){} 
try{t2=arg2.toString().split(".")[1].length}catch(e){} 
with(Math){ 
r1=Number(arg1.toString().replace(".","")) 
r2=Number(arg2.toString().replace(".","")) 
return (r1/r2)*pow(10,t2-t1); 
} 
} 
//给Number类型增加一个div方法,调用起来更加方便。 
Number.prototype.div = function (arg){ 
return accDiv(this, arg); 
} 
//乘法函数,用来得到精确的乘法结果 
//说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。 
//调用:accMul(arg1,arg2) 
//返回值:arg1乘以arg2的精确结果 
function accMul(arg1,arg2) 
{ 
var m=0,s1=arg1.toString(),s2=arg2.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) 
} 
//给Number类型增加一个mul方法,调用起来更加方便。 
Number.prototype.mul = function (arg){ 
return accMul(arg, this); 
} 
//加法函数,用来得到精确的加法结果 
//说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。 
//调用:accAdd(arg1,arg2) 
//返回值:arg1加上arg2的精确结果 
function accAdd(arg1,arg2){ 
var r1,r2,m; 
try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0} 
try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0} 
m=Math.pow(10,Math.max(r1,r2)) 
return (arg1*m+arg2*m)/m 
} 
//给Number类型增加一个add方法,调用起来更加方便。 
Number.prototype.add = function (arg){ 
return accAdd(arg,this); 
} 
//减法函数,用来得到精确的减法结果 
//说明:javascript的减法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的减法结果。 
//调用:accSubtr(arg1,arg2) 
//返回值:arg1减去arg2的精确结果 
function accSubtr(arg1,arg2){
var r1,r2,m,n;
try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
m=Math.pow(10,Math.max(r1,r2));
//动态控制精度长度
n=(r1>=r2)?r1:r2;
return ((arg1*m-arg2*m)/m).toFixed(n);
} 
//给Number类型增加一个subtr 方法,调用起来更加方便。 
Number.prototype.subtr = function (arg){ 
return accSubtr(arg,this); 
}

在你要用的地方包含这些函数,然后调用它来计算就可以了。

/如果在知道小数位个数的前提下,可以考虑通过将浮点数放大倍数到整型(最后再除以相应倍数),再进行运算操作,这样就能得到正确的结果了

<script> 
alert(11*(22.9*10)/10);
</script>
Javascript 相关文章推荐
限制复选框的最大可选数
Jul 01 Javascript
自己的js工具 Event封装
Aug 21 Javascript
jquery 多行文本框(textarea)高度变化
Jul 03 Javascript
Jquery each方法跳出循环,并获取返回值(实例讲解)
Dec 12 Javascript
Javascript数组与字典用法分析
Dec 13 Javascript
JS实现网页上随机产生超链接地址的方法
Nov 09 Javascript
js关于getImageData跨域问题的解决方法
Oct 14 Javascript
微信开发 消息推送实现代码
Oct 21 Javascript
Angular.js项目中使用gulp实现自动化构建以及压缩打包详解
Jul 19 Javascript
JavaScript canvas实现围绕旋转动画
Nov 18 Javascript
JavaScript使用ul中li标签实现删除效果
Apr 15 Javascript
JavaScript数组去重实现方法小结
Jan 17 Javascript
JS实现悬浮移动窗口(悬浮广告)的特效
Mar 12 #Javascript
js弹出模式对话框,并接收回传值的方法
Mar 12 #Javascript
js 获取class的元素的方法 以及创建方法getElementsByClassName
Mar 11 #Javascript
.net,js捕捉文本框回车键事件的小例子(兼容多浏览器)
Mar 11 #Javascript
JS中Iframe之间传值的方法
Mar 11 #Javascript
JS中Iframe之间传值及子页面与父页面应用
Mar 11 #Javascript
js将iframe中控件的值传到主页面控件中的实现方法
Mar 11 #Javascript
You might like
基于PHP输出缓存(output_buffering)的深入理解
2013/06/13 PHP
PHP实现的简单mock json脚本分享
2015/02/10 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
2017/07/21 PHP
Expandable &quot;Detail&quot; Table Rows
2007/08/29 Javascript
jquery text,radio,checkbox,select操作实现代码
2009/07/09 Javascript
Javascript 自定义类型方法小结
2010/03/02 Javascript
jquery下动态显示jqGrid以及jqGrid的属性设置容易出现问题的解决方法
2010/10/22 Javascript
jQuery对象数据缓存Cache原理及jQuery.data方法区别介绍
2013/04/07 Javascript
jquery自定义函数的多种方法
2014/01/09 Javascript
jQuery获取当前对象标签名称的方法
2014/02/07 Javascript
jQuery插件简单实现方法
2015/07/18 Javascript
jQuery实现定位滚动条位置
2016/08/05 Javascript
通过bootstrap全面学习less
2016/11/09 Javascript
如何使用Bootstrap创建表单
2017/03/29 Javascript
nodejs multer实现文件上传与下载
2017/05/10 NodeJs
vue-router 路由基础的详解
2017/10/17 Javascript
jQuery+PHP实现上传裁剪图片
2020/06/29 jQuery
Element实现表格分页数据选择+全选所有完善批量操作
2019/06/07 Javascript
Nuxt默认模板、默认布局和自定义错误页面的实现
2020/05/11 Javascript
基于js实现的图片拖拽排序源码实例
2020/11/04 Javascript
Python 自动刷博客浏览量实例代码
2017/06/14 Python
django 信号调度机制详解
2019/07/19 Python
python二维图制作的实例代码
2020/12/03 Python
python集合的新增元素方法整理
2020/12/07 Python
美国渔具店:FishUSA
2019/08/07 全球购物
瑞士网球商店:Tennis-Point
2020/03/12 全球购物
会计应聘求职信范文
2013/12/17 职场文书
学生喝酒检讨书
2014/02/06 职场文书
岗位廉政承诺书
2014/03/27 职场文书
护理工作个人总结
2015/03/03 职场文书
2015年学校食堂工作总结
2015/04/22 职场文书
2015年学校政教处工作总结
2015/05/26 职场文书
人事任命书范本
2015/09/21 职场文书
如何撰写出一份完美的商业计划书?
2019/07/12 职场文书
MySQL下使用Inplace和Online方式创建索引的教程
2021/05/26 MySQL
Java 语言中Object 类和System 类详解
2021/07/07 Java/Android