解决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 相关文章推荐
Add Formatted Text to a Word Document
Jun 15 Javascript
分享一个asp.net pager分页控件
Jan 04 Javascript
jQuery UI Dialog 创建友好的弹出对话框实现代码
Apr 12 Javascript
jQuery 淡入淡出 png图在ie8下有黑色边框的解决方法
Mar 05 Javascript
JS简单实现登陆验证附效果图
Nov 19 Javascript
JavaScript判断访问的来源是手机还是电脑,用的哪种浏览器
Dec 12 Javascript
如何在指定的地方插入html内容和文本内容
Dec 23 Javascript
AngularJS 支付倒计时功能实现思路
Jun 05 Javascript
vue router下的html5 history在iis服务器上的设置方法
Oct 18 Javascript
vue加载自定义的js文件方法
Mar 13 Javascript
浅谈webpack devtool里的7种SourceMap模式
Jan 14 Javascript
vue+webpack dev本地调试全局样式引用失效的解决方案
Nov 12 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读MYSQL中文乱码的解决方法
2006/12/17 PHP
php数据入库前清理 注意php intval与mysql的int取值范围不同
2010/12/12 PHP
基于flush()不能按顺序输出时的解决办法
2013/06/29 PHP
phpmyadmin打开很慢的解决方法
2014/04/21 PHP
Laravel框架中扩展函数、扩展自定义类的方法
2014/09/04 PHP
php实现在线通讯录功能(附源码)
2016/05/13 PHP
PHP基于Closure类创建匿名函数的方法详解
2017/08/17 PHP
javascript实现划词标记+划词搜索功能
2007/03/06 Javascript
禁用页面部分JavaScript不是全部而是部分
2014/09/03 Javascript
JavaScript编程的单例设计模讲解
2015/11/10 Javascript
javascript实现的网站访问量统计代码
2015/12/20 Javascript
js获取Html元素的实际宽度高度的方法
2016/05/19 Javascript
js 连续赋值的简单实现
2016/06/13 Javascript
javascript之IE版本检测超简单方法
2016/08/20 Javascript
Bootstarp基本模版学习教程
2017/02/01 Javascript
BootStrap Datetimepicker 汉化的实现代码
2017/02/10 Javascript
详解Angular模板引用变量及其作用域
2018/11/23 Javascript
详解js创建对象的几种方法及继承
2019/04/12 Javascript
详解如何探测小程序返回到webview页面
2019/05/14 Javascript
全面分析JavaScript 继承
2019/05/30 Javascript
为vue项目自动设置请求状态的配置方法
2019/06/09 Javascript
[04:29]【TI9采访】OG.N0tail在胜者组决赛后接受采访
2019/08/25 DOTA
python+selenium识别验证码并登录的示例代码
2017/12/21 Python
python3.5+tesseract+adb实现西瓜视频或头脑王者辅助答题
2018/01/17 Python
pyqt5简介及安装方法介绍
2018/01/31 Python
pthon贪吃蛇游戏详细代码
2019/01/27 Python
Python多线程threading模块用法实例分析
2019/05/22 Python
Python OpenCV 调用摄像头并截图保存功能的实现代码
2019/07/02 Python
Python字典dict常用方法函数实例
2020/11/09 Python
用python-webdriver实现自动填表的示例代码
2021/01/13 Python
青年教师典范事迹材料
2014/01/31 职场文书
小学母亲节活动方案
2014/03/14 职场文书
励志演讲稿500字
2014/08/21 职场文书
2014年最新领导班子整改方案
2014/09/27 职场文书
食品安全责任书范本
2015/05/09 职场文书
高温慰问简报
2015/07/21 职场文书