解决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 相关文章推荐
JavaScript学习笔记记录我的旅程
May 23 Javascript
javascript自动给文本url地址增加链接的方法分享
Jan 20 Javascript
JavaScript+CSS无限极分类效果完整实现方法
Dec 22 Javascript
初步使用Node连接Mysql数据库
Mar 03 Javascript
简单解析JavaScript中的__proto__属性
May 10 Javascript
jQuery筛选数组之grep、each、inArray、map的用法及遍历json对象
Jun 20 Javascript
详解百度百科目录导航树小插件
Jan 08 Javascript
详解JS中的立即执行函数
Feb 24 Javascript
vue一个页面实现音乐播放器的示例
Feb 06 Javascript
JS异步错误捕获的一些事小结
Apr 26 Javascript
深入理解javascript prototype的相关知识
Sep 19 Javascript
Layui选项卡制作历史浏览记录的方法
Sep 28 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 session 预定义数组
2009/03/16 PHP
PHP编程过程中需要了解的this,self,parent的区别
2009/12/30 PHP
php学习笔记 数组遍历实现代码
2011/06/09 PHP
PHP使用header()输出图片缓存实例
2014/12/09 PHP
thinkphp框架无限级栏目的排序功能实现方法示例
2020/03/29 PHP
jQuery中调用WebService方法小结
2011/03/28 Javascript
js利用事件的阻止冒泡实现点击空白模态框的隐藏
2014/01/24 Javascript
JavaScript实现点击自动选择TextArea文本的方法
2015/07/02 Javascript
angular json对象push到数组中的方法
2018/02/27 Javascript
MVVM 双向绑定的实现代码
2018/06/21 Javascript
实例分析vue循环列表动态数据的处理方法
2018/09/28 Javascript
详解ES7 Decorator 入门解析
2019/02/18 Javascript
Element图表初始大小及窗口自适应实现
2020/07/10 Javascript
详解vue中v-on事件监听指令的基本用法
2020/07/22 Javascript
jQuery编写QQ简易聊天框
2020/08/27 jQuery
[01:00:30]TFT vs VGJ.T Supermajor 败者组 BO3 第一场 6.5
2018/06/06 DOTA
python urllib urlopen()对象方法/代理的补充说明
2017/06/29 Python
python中使用正则表达式的后向搜索肯定模式(推荐)
2017/11/11 Python
Python实现的圆形绘制(画圆)示例
2018/01/31 Python
Pandas:Series和DataFrame删除指定轴上数据的方法
2018/11/10 Python
Python读取分割压缩TXT文本文件实例
2020/02/14 Python
django 解决自定义序列化返回处理数据为null的问题
2020/05/20 Python
Django 解决开发自定义抛出异常的问题
2020/05/21 Python
Python中无限循环需要什么条件
2020/05/27 Python
基于python实现判断字符串是否数字算法
2020/07/10 Python
python实现图书馆抢座(自动预约)功能的示例代码
2020/09/29 Python
python如何利用Mitmproxy抓包
2020/10/10 Python
德国baby-markt婴儿用品瑞士网站:baby-markt.ch
2017/06/09 全球购物
Hotels.com台湾:饭店订房网
2017/09/06 全球购物
个人实习生的自我评价
2014/02/16 职场文书
2014年学校总务处工作总结
2014/12/08 职场文书
2015年全国“爱牙日”宣传活动总结
2015/03/23 职场文书
辣妈辣妹观后感
2015/06/10 职场文书
MySQL 用 limit 为什么会影响性能
2021/09/15 MySQL
Python必备技巧之字符数据操作详解
2022/03/23 Python