解决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 相关文章推荐
jquery 元素相对定位代码
Oct 15 Javascript
Ext GridPanel加载完数据后进行操作示例代码
Jun 17 Javascript
基于jquery实现的可编辑下拉框实现代码
Aug 02 Javascript
javascript 事件处理示例分享
Dec 31 Javascript
用JavaScript实现对话框的教程
Jun 04 Javascript
聊一聊jQuery插件uploadify使用方法
Aug 24 Javascript
纯js实现悬浮按钮组件
Dec 17 Javascript
Bootstrap组合上、下拉框简单实现代码
Mar 06 Javascript
谈谈VUE种methods watch和compute的区别和联系
Aug 01 Javascript
微信小程序实现根据字母选择城市功能
Aug 16 Javascript
echarts实现词云自定义形状的示例代码
Feb 20 Javascript
vue实现简单跑马灯效果
May 25 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连接access数据库方法
2013/11/11 PHP
php实现文件编码批量转换
2014/03/10 PHP
PHP编译安装时常见错误解决办法
2015/05/28 PHP
php正则表达式获取内容所有链接
2015/07/24 PHP
ThinkPHP实现递归无级分类――代码少
2015/07/29 PHP
PHP基于Redis消息队列实现发布微博的方法
2017/05/03 PHP
URL编码转换,escape() encodeURI() encodeURIComponent()
2006/12/27 Javascript
JavaScript confirm选择判断
2008/10/18 Javascript
javascript 防止刷新,后退,关闭
2010/08/07 Javascript
纯JAVASCRIPT图表动画插件Highcharts Examples
2011/04/16 Javascript
css transform 3D幻灯片特效实现步骤解读
2013/03/27 Javascript
JS小游戏之极速快跑源码详解
2014/09/25 Javascript
js实现按钮加背景图片常用方法
2014/11/01 Javascript
jQuery中[attribute*=value]选择器用法实例
2014/12/31 Javascript
webpack 单独打包指定JS文件的方法
2018/02/22 Javascript
详解ES6 Symbol 的用途
2018/10/14 Javascript
vsCode安装使用教程和插件安装方法
2020/08/24 Javascript
优雅的处理vue项目异常实战记录
2019/06/05 Javascript
js利用递归与promise 按顺序请求数据的方法
2019/08/30 Javascript
[50:02]完美世界DOTA2联赛循环赛 Magma vs IO BO2第一场 11.01
2020/11/02 DOTA
python 保存float类型的小数的位数方法
2018/10/17 Python
python生成每日报表数据(Excel)并邮件发送的实例
2019/02/03 Python
对python3.4 字符串转16进制的实例详解
2019/06/12 Python
python随机生成库faker库api实例详解
2019/11/28 Python
学习Python需要哪些工具
2020/09/04 Python
python爬虫工具例举说明
2020/11/30 Python
美国学校校服,儿童和婴儿服装:Cookie’s Kids
2016/10/14 全球购物
大学生毕业求职简历的自我评价
2013/10/24 职场文书
教师自荐信
2013/12/10 职场文书
环保倡议书300字
2014/05/15 职场文书
中国在我心中演讲稿
2014/09/13 职场文书
2014年驻村干部工作总结
2014/11/17 职场文书
道德模范事迹材料
2014/12/20 职场文书
幼师辞职信范文大全
2015/05/12 职场文书
法院答辩状格式
2015/05/22 职场文书
几款流行的HTML5 UI框架比较(小结)
2021/04/08 HTML / CSS