解决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 相关文章推荐
javascript下对于事件、事件流、事件触发的顺序随便说说
Jul 17 Javascript
使用jQuery实现dropdownlist的联动效果(sharepoint 2007)
Mar 30 Javascript
ASP.NET MVC中EasyUI的datagrid跨域调用实现代码
Mar 14 Javascript
刷新页面的几种方法小结(JS,ASP.NET)
Jan 07 Javascript
使用基于Node.js的构建工具Grunt来发布ASP.NET MVC项目
Feb 15 Javascript
javascript深拷贝(deepClone)详解
Aug 24 Javascript
AngularJS轻松实现双击排序的功能
Aug 30 Javascript
js实现时间轴自动排列效果
Mar 09 Javascript
vue导出html、word和pdf的实现代码
Jul 31 Javascript
element-ui表格数据转换的示例代码
Aug 24 Javascript
JS如何判断对象是否包含某个属性
Aug 29 Javascript
vue打开新窗口并实现传参的图文实例
Mar 04 Vue.js
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实现自动获取生成文章主题关键词功能的深入分析
2013/06/03 PHP
ThinkPHP结合ajax、Mysql实现的客户端通信功能代码示例
2014/06/23 PHP
php操作(删除,提取,增加)zip文件方法详解
2015/03/12 PHP
WordPress开发中用于标题显示的相关函数使用解析
2016/01/07 PHP
PHP工厂模式简单实现方法示例
2018/05/23 PHP
PHP面向对象程序设计模拟一般面向对象语言中的方法重载(overload)示例
2019/06/13 PHP
Aptana调试javascript图解教程
2009/11/30 Javascript
jquery1.4后 jqDrag 拖动 不可用
2010/02/06 Javascript
jQuery对象与DOM对象之间的转换方法
2010/04/15 Javascript
jQuery源码中的chunker 正则过滤符分析
2012/07/31 Javascript
css配合jquery美化 select
2013/11/29 Javascript
浅析XMLHttpRequest的缓存问题
2013/12/13 Javascript
JavaScript显示当前文档最后修改日期的方法
2015/03/19 Javascript
JQuery实现鼠标移动图片显示描述层的方法
2015/06/25 Javascript
深入浅析同源策略和跨域访问
2015/11/26 Javascript
JS实现旋转木马式图片轮播效果
2017/01/18 Javascript
TypeScript入门-接口
2017/03/30 Javascript
angularjs结合html5实现拖拽功能
2018/06/25 Javascript
基于iview的router常用控制方式
2019/05/30 Javascript
小程序中的箭头函数的具体使用
2020/06/19 Javascript
python实现SOM算法
2018/02/23 Python
在NumPy中创建空数组/矩阵的方法
2018/06/15 Python
Python二元赋值实用技巧解析
2019/10/25 Python
python创建学生管理系统
2019/11/22 Python
Python趣味实例,实现一个简单的抽奖刮刮卡
2020/07/18 Python
澳大利亚家具和家居用品在线:BROSA
2017/11/02 全球购物
英国100%防污和防水的靴子:Muck Boot Company
2020/09/08 全球购物
最经典的大学生职业生涯规划范文
2014/03/05 职场文书
《夹竹桃》教学反思
2014/04/20 职场文书
心理健康活动总结
2014/04/30 职场文书
小区推广策划方案
2014/06/06 职场文书
自查自纠工作情况报告
2014/10/29 职场文书
个人学习群众路线心得体会
2014/11/05 职场文书
学生会个人总结范文
2015/02/15 职场文书
简短的36句中秋节祝福信息语句
2019/09/09 职场文书
提取视频中的音频 Python只需要三行代码!
2021/05/10 Python