解决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 相关文章推荐
dotopAlert 提示用户需安装播放器的代码
Sep 17 Javascript
mailto的使用技巧分享
Dec 21 Javascript
JQuery设置和去除disabled属性的5种方法总结
May 16 Javascript
jquery如何判断表格同一列不同行input数据是否重复
May 14 Javascript
JavaScript实现穷举排列(permutation)算法谜题解答
Dec 29 Javascript
JS实现仿google、百度搜索框输入信息智能提示的实现方法
Apr 20 Javascript
JavaScript jquery及AJAX小结
Jan 24 Javascript
基于JavaScript实现的快速排序算法分析
Apr 14 Javascript
JS点击缩略图整屏居中放大图片效果
Jul 04 Javascript
JS开发中基本数据类型具体有哪几种
Oct 19 Javascript
JavaScript中工厂函数与构造函数示例详解
May 06 Javascript
layui富文本编辑器前端无法取值的解决方法
Sep 18 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
如何分别全角和半角以避免乱码
2006/10/09 PHP
php基础知识:类与对象(3) 构造函数和析构函数
2006/12/13 PHP
windows7下安装php的php-ssh2扩展教程
2014/07/04 PHP
PHP bin2hex()函数基础实例讲解
2019/02/11 PHP
详解PHP神奇又有用的Trait
2019/03/25 PHP
Thinkphp5框架简单实现钩子(Hook)行为的方法示例
2019/09/03 PHP
比较详细的关于javascript 解析json的代码
2009/12/16 Javascript
Jquery 最近浏览过的商品的功能实现代码
2010/05/14 Javascript
jQuery获取Select选择的Text和Value(详细汇总)
2013/01/25 Javascript
使用Js让Html中特殊字符不被转义
2013/11/05 Javascript
jQuery动态改变多行文本框高度的方法
2016/09/07 Javascript
Bootstrap Table表格一直加载(load)不了数据的快速解决方法
2016/09/17 Javascript
jQuery在ie6下无法设置select选中的解决方法详解
2016/09/20 Javascript
JavaScript手风琴页面制作
2017/05/17 Javascript
详解利用eventemitter2实现Vue组件通信
2019/11/04 Javascript
nuxt.js添加环境变量,区分项目打包环境操作
2020/11/06 Javascript
Python开发的单词频率统计工具wordsworth使用方法
2014/06/25 Python
python获取本机mac地址和ip地址的方法
2015/04/29 Python
Python脚本获取操作系统版本信息
2016/12/17 Python
Python实现字符串格式化的方法小结
2017/02/20 Python
python判断字符串或者集合是否为空的实例
2019/01/23 Python
简单分析python的类变量、实例变量
2019/08/23 Python
Python 字符串池化的前提
2020/07/03 Python
Python爬虫与反爬虫大战
2020/07/30 Python
Rossignol金鸡美国官网:始于1907年法国百年雪具品牌
2019/03/06 全球购物
利用指针变量实现队列的入队操作
2012/04/07 面试题
电子商务应届生求职信
2013/11/16 职场文书
小学教师师德整改措施
2014/09/29 职场文书
孕妇离婚协议书范本
2014/11/20 职场文书
具结保证书范本
2015/05/11 职场文书
2016年秋季新学期致辞
2015/07/30 职场文书
合作协议书格式范本
2016/03/21 职场文书
2016年清明节期间群众祭祀活动工作总结
2016/04/01 职场文书
详解redis分布式锁的这些坑
2021/05/19 Redis
mysql5.6主从搭建以及不同步问题详解
2021/12/04 MySQL
前端JS获取URL参数的4种方法总结
2022/04/05 Javascript