解决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操作input值的各种方法总结
Nov 21 Javascript
JQuery打造省市下拉框联动效果
May 18 Javascript
javascript实现复选框选中属性
Mar 25 Javascript
纯javascript制作日历控件
Jul 17 Javascript
jQuery插件扩展测试实例
Jun 21 Javascript
原生JS实现自定义滚动条效果
Oct 27 Javascript
VueJS组件之间通过props交互及验证的方式
Sep 04 Javascript
基于react组件之间的参数传递(详解)
Sep 05 Javascript
Vue精简版风格概述
Jan 30 Javascript
webpack4.0打包优化策略整理小结
Mar 30 Javascript
解决Layui 表单提交数据为空的问题
Aug 15 Javascript
学习 Vue.js 遇到的那些坑
Feb 02 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/01/11 PHP
基于magic_quotes_gpc与magic_quotes_runtime的区别与使用介绍
2013/04/22 PHP
Laravel5权限管理方法详解
2016/07/26 PHP
浅谈PHP错误类型及屏蔽方法
2017/05/27 PHP
关于 Laravel Redis 多个进程同时取队列问题详解
2017/12/25 PHP
asp(javascript)全角半角转换代码 dbc2sbc
2009/08/06 Javascript
jquery 弹出登录窗口实现代码
2009/12/24 Javascript
Clipboard.js 无需Flash的JavaScript复制粘贴库
2015/10/02 Javascript
vue+vuex+axio从后台获取数据存入vuex实现组件之间共享数据
2017/04/22 Javascript
vue.js的安装方法
2017/05/12 Javascript
微信小程序“摇一摇”的实例代码
2017/07/20 Javascript
Easyui和zTree两种方式分别实现树形下拉框
2017/08/04 Javascript
微信小程序6位或多位验证码密码输入框功能的实现代码
2018/05/29 Javascript
详解如何给React-Router添加路由页面切换时的过渡动画
2019/04/25 Javascript
JS实现纵向轮播图(初级版)
2020/01/18 Javascript
详解Python中的循环语句的用法
2015/04/09 Python
Pandas之drop_duplicates:去除重复项方法
2018/04/18 Python
python实现Windows电脑定时关机
2018/06/20 Python
Python 修改列表中的元素方法
2018/06/26 Python
对python3 中方法各种参数和返回值详解
2018/12/15 Python
详解利用python+opencv识别图片中的圆形(霍夫变换)
2019/07/01 Python
Python类的绑定方法和非绑定方法实例解析
2020/03/04 Python
python requests.get带header
2020/05/05 Python
CSS3中使用RGBA设置透明度的示例
2015/08/04 HTML / CSS
萌新的HTML5 入门指南
2020/11/06 HTML / CSS
跑步爱好者一站式服务网站:Jack Rabbit
2016/09/01 全球购物
JD Sports意大利:英国篮球和运动时尚的领导者
2017/10/29 全球购物
Java多态性的定义以及类型
2014/09/16 面试题
Weblogic和WebSphere不同特点
2012/05/09 面试题
小学生防溺水广播稿
2014/01/12 职场文书
蛋糕店的商业计划书范文
2014/01/27 职场文书
模具设计与制造专业自荐书
2014/07/01 职场文书
募捐感谢信
2015/01/22 职场文书
小班上学期个人总结
2015/02/12 职场文书
【海涛教你打DOTA】黑鸟第一视角解说
2022/04/01 DOTA
vue数据字典取键值项目的字典问题
2022/04/12 Vue.js