解决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 相关文章推荐
收集的网上用的ajax之chat.js文件
Apr 08 Javascript
JavaScript与函数式编程解释
Apr 27 Javascript
用jQuery实现检测浏览器及版本的脚本代码
Jan 22 Javascript
理解Javascript_05_原型继承原理
Oct 13 Javascript
js用typeof方法判断undefined类型
Jul 15 Javascript
javascript实现微信分享
Dec 23 Javascript
Jquery使用小技巧汇总
Dec 29 Javascript
详解JavaScript异步编程中jQuery的promise对象的作用
May 03 Javascript
纯原生js实现table表格的增删
Jan 05 Javascript
微信小程序之几种常见的弹框提示信息实现详解
Jul 11 Javascript
刷新页面后让控制台的js代码继续执行
Sep 20 Javascript
判断JavaScript中的两个变量是否相等的操作符
Dec 21 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
thinkPHP实现基于ajax的评论回复功能
2018/06/22 PHP
利用jQuery插件扩展识别浏览器内核与外壳的类型和版本的实现代码
2011/10/22 Javascript
深入理解JS中的变量及作用域、undefined与null
2014/03/04 Javascript
js身份证判断方法支持15位和18位
2014/03/18 Javascript
JavaScript中统计Textarea字数并提示还能输入的字符
2014/06/10 Javascript
jquery使用hide方法隐藏指定id的元素
2015/03/30 Javascript
js实现固定显示区域内自动缩放图片的方法
2015/07/18 Javascript
jQuery实现输入框下拉列表树插件特效代码分享
2015/08/27 Javascript
浅谈Javascript中的Label语句
2016/12/14 Javascript
AngularJS页面带参跳转及参数解析操作示例
2017/06/28 Javascript
vue 2.5.1 源码学习 之Vue.extend 和 data的合并策略
2019/06/04 Javascript
uni app仿微信顶部导航条功能
2019/09/17 Javascript
详解JavaScript修改注册表的方法
2020/01/05 Javascript
angular *Ngif else用法详解
2020/12/15 Javascript
[01:03:00]DOTA2上海特级锦标赛A组败者赛 EHOME VS CDEC第一局
2016/02/25 DOTA
Python中使用MELIAE分析程序内存占用实例
2015/02/18 Python
在Django中创建第一个静态视图
2015/07/15 Python
Python中的变量和作用域详解
2016/07/13 Python
Python 使用PIL numpy 实现拼接图片的示例
2018/05/08 Python
Python使用sorted对字典的key或value排序
2018/11/15 Python
PyCharm在新窗口打开项目的方法
2019/01/17 Python
Python中print和return的作用及区别解析
2019/05/05 Python
使用python matploblib库绘制准确率,损失率折线图
2020/06/16 Python
pandas数据分组groupby()和统计函数agg()的使用
2021/03/04 Python
使用CSS3制作一个简单的Chrome模拟器
2015/07/15 HTML / CSS
Urban Outfitters英国官网:美国平价服饰品牌
2016/11/25 全球购物
阿尔卡特(中国)的面试题目
2014/08/20 面试题
医药代表个人求职信范本
2013/12/19 职场文书
船舶专业个人求职信范文
2014/01/02 职场文书
优秀导游先进事迹材料
2014/01/25 职场文书
《会走路的树》教后反思
2014/04/19 职场文书
合伙协议书范本
2014/04/21 职场文书
管理标语大全
2014/06/24 职场文书
个人工作表现评价材料
2014/09/21 职场文书
法律意见书范文
2015/05/20 职场文书
农村老人去世追悼词
2015/06/23 职场文书