解决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 相关文章推荐
学习ExtJS(一) 之基础前提
Oct 07 Javascript
JavaScript几种形式的树结构菜单
May 10 Javascript
firefox下frameset取不到值的解决方法
Sep 06 Javascript
JS判断文本框内容改变事件的简单实例
Mar 07 Javascript
vue实现列表的添加点击
Dec 29 Javascript
Bootstrap实现各种进度条样式详解
Apr 13 Javascript
VUE利用vuex模拟实现新闻点赞功能实例
Jun 28 Javascript
AngularJS中使用three.js的实例详解
Jul 21 Javascript
vue2里面ref的具体使用方法
Oct 27 Javascript
Angular整合zTree的示例代码
Jan 24 Javascript
js中怎么判断两个字符串相等的实例
Jan 17 Javascript
vue-cli脚手架引入弹出层layer插件的几种方法
Jun 24 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
如何冲泡挂耳包咖啡?技巧是什么
2021/03/04 冲泡冲煮
php实现计数器方法小结
2015/01/05 PHP
小型js框架veryide.librar源代码
2009/03/05 Javascript
Javascript中Event属性搜集整理
2013/09/17 Javascript
jQuery实现的一个自定义Placeholder属性插件
2014/08/11 Javascript
如何使用Bootstrap的modal组件自定义alert,confirm和modal对话框
2016/03/01 Javascript
AngularJS 过滤器的简单实例
2016/07/27 Javascript
微信小程序 SocketIO 实例讲解
2016/10/13 Javascript
jQuery实现两列等高并自适应高度
2016/12/22 Javascript
js实现二级导航功能
2017/03/03 Javascript
nodejs6下使用koa2框架实例
2017/05/18 NodeJs
Element-UI Table组件上添加列拖拽效果实现方法
2018/04/14 Javascript
每个 JavaScript 工程师都应懂的33个概念
2018/10/22 Javascript
JavaScript多种图形实现代码实例
2020/06/28 Javascript
Python实现的生成自我描述脚本分享(很有意思的程序)
2014/07/18 Python
Python StringIO模块实现在内存缓冲区中读写数据
2015/04/08 Python
Python 正则表达式入门(中级篇)
2016/12/07 Python
Python+Turtle动态绘制一棵树实例分享
2018/01/16 Python
详解Python中打乱列表顺序random.shuffle()的使用方法
2019/11/11 Python
python图形用户接口实例详解
2019/12/16 Python
Python面向对象程序设计之私有变量,私有方法原理与用法分析
2020/03/23 Python
Python如何实现FTP功能
2020/05/28 Python
python使用re模块爬取豆瓣Top250电影
2020/10/20 Python
CSS3网格的三个新特性详解
2014/04/04 HTML / CSS
企业年度评优方案
2014/06/02 职场文书
物业管理专业自荐信
2014/07/01 职场文书
小城镇建设汇报材料
2014/08/16 职场文书
2014最新版群众路线四风整改措施
2014/09/24 职场文书
2014年共青团工作总结
2014/12/10 职场文书
年会主持人开场白台词
2015/05/29 职场文书
公司安全管理制度范本
2015/08/05 职场文书
2016中秋节晚会开场白
2015/11/26 职场文书
演讲稿:态度决定一切
2019/04/02 职场文书
JVM的类加载器和双亲委派模式你了解吗
2022/03/13 Java/Android
Spring Boot DevTools 全局配置学习指南
2022/03/31 Java/Android
NoSQL优缺点与MongoDB数据库简介
2022/06/05 MongoDB