解决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的左右滚动实现代码
Dec 03 Javascript
javascript学习笔记(十) js对象 继承
Jun 19 Javascript
jQuery获取当前对象标签名称的方法
Feb 07 Javascript
扒一扒JavaScript 预解释
Jan 28 Javascript
localResizeIMG先压缩后使用ajax无刷新上传(移动端)
Aug 11 Javascript
javascript运动效果实例总结(放大缩小、滑动淡入、滚动)
Jan 08 Javascript
微信小程序 toast 详解及实例代码
Nov 09 Javascript
es6学习笔记之Async函数基本教程
May 11 Javascript
jQuery Datatables表头不对齐的解决办法
Nov 27 jQuery
详解vue使用vue-layer-mobile组件实现toast,loading效果
Aug 31 Javascript
Vue前后端不同端口的实现方法
Sep 19 Javascript
小程序实现多选框功能
Oct 30 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实现文件安全下载
2006/10/09 PHP
CI框架扩展系统核心类的方法分析
2016/05/23 PHP
php fread读取文件注意事项
2016/09/24 PHP
javascript 操作cookies及正确使用cookies的属性
2009/10/15 Javascript
尝试在让script的type属性等于text/html
2013/01/15 Javascript
原生JS实现加入收藏夹的代码
2013/10/24 Javascript
js使用html()或text()方法获取设置p标签的显示的值
2014/08/01 Javascript
Jquery实现兼容各大浏览器的Enter回车切换输入焦点的方法
2014/09/01 Javascript
JavaScript之Vue.js【入门基础】
2016/12/06 Javascript
jQuery与js实现颜色渐变的方法
2016/12/30 Javascript
Vue报错:Uncaught TypeError: Cannot assign to read only property’exports‘ of object’#‘的解决方法
2017/06/17 Javascript
javaScript之split与join的区别(详解)
2017/11/08 Javascript
详解vue+webpack+express中间件接口使用
2018/07/17 Javascript
layui实现文件或图片上传记录
2018/08/28 Javascript
浅谈React Event实现原理
2018/09/20 Javascript
微信小程序购物车、父子组件传值及calc的注意事项总结
2018/11/14 Javascript
vue中组件的3种使用方式详解
2019/03/23 Javascript
Python编写屏幕截图程序方法
2015/02/18 Python
利用Python实现图书超期提醒
2016/08/02 Python
Django的HttpRequest和HttpResponse对象详解
2018/01/26 Python
详解python列表生成式和列表生成式器区别
2019/03/27 Python
Python实现去除图片中指定颜色的像素功能示例
2019/04/13 Python
Python Datetime模块和Calendar模块用法实例分析
2019/04/15 Python
安装docker-compose的两种最简方法
2019/07/30 Python
Python利用命名空间解析XML文档
2020/08/10 Python
python 爬虫爬取京东ps4售卖情况
2020/12/18 Python
CSS超出文本指定宽度用省略号代替和文本不换行
2016/05/05 HTML / CSS
html5时钟实现代码
2010/10/22 HTML / CSS
加拿大著名时装品牌:SOIA & KYO
2016/08/23 全球购物
某公司.Net方向面试题
2014/04/24 面试题
介绍一下Java的事务处理
2012/12/07 面试题
红头文件任命书范本
2014/06/05 职场文书
六五普法宣传标语
2014/10/06 职场文书
试用期自我评价范文
2015/03/10 职场文书
python代码实现扫码关注公众号登录的实战
2021/11/01 Python
微信小程序APP的事件绑定以及传递参数时的冒泡和捕获
2022/04/19 Javascript