解决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 相关文章推荐
Mootools 1.2 手风琴(Accordion)教程
Sep 15 Javascript
JS Excel读取和写入操作(模板操作)实现代码
Apr 11 Javascript
一个可绑定数据源的jQuery数据表格插件
Jul 17 Javascript
用js解决数字不能换行问题
Aug 10 Javascript
Javascript数组与字典用法分析
Dec 13 Javascript
JavaScript中Cookie操作实例
Jan 09 Javascript
浅谈被jQuery抛弃的函数及替代函数
May 03 Javascript
微信小程序 免费SSL证书https、TLS版本问题的解决办法
Dec 14 Javascript
js实现适配不同的屏幕大小
Apr 10 Javascript
微信小程序url与token设置详解
Sep 26 Javascript
详解puppeteer使用代理
Dec 27 Javascript
js中Generator函数的深入讲解
Apr 07 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中MVC的开发经验分享
2012/05/17 PHP
生成随机字符串和验证码的类的PHP实例
2013/12/24 PHP
php中convert_uuencode()与convert_uuencode函数用法实例
2014/11/22 PHP
phpstorm激活码2020附使用详细教程
2020/09/25 PHP
IE8 中使用加速器(Activities)
2010/05/14 Javascript
jquery 的 $(&quot;#id&quot;).html() 无内容的解决方法
2010/06/07 Javascript
读jQuery之十四 (触发事件核心方法)
2011/08/23 Javascript
JS 打印界面的CSS居中代码适用所有浏览器
2014/03/19 Javascript
js自动生成的元素与页面原有元素发生堆叠的解决方法
2014/09/04 Javascript
禁止iframe脚本弹出的窗口覆盖了父窗口的方法
2014/09/06 Javascript
老生常谈原生JS执行环境与作用域
2016/11/22 Javascript
Angular项目中$scope.$apply()方法的使用详解
2017/07/26 Javascript
BootStrap实现文件上传并带有进度条效果
2017/09/11 Javascript
详解vue-cli中的ESlint配置文件eslintrc.js
2017/09/25 Javascript
JS基于对象的链表实现与使用方法示例
2019/01/31 Javascript
使用 Vue 实现一个虚拟列表的方法
2019/08/20 Javascript
JS 事件机制完整示例分析
2020/01/15 Javascript
使用JavaScript实现网页秒表功能(含开始、暂停、继续、重置功能)
2020/06/05 Javascript
python实现多线程采集的2个代码例子
2014/07/07 Python
Django框架中render_to_response()函数的使用方法
2015/07/16 Python
TensorFlow Session会话控制&amp;Variable变量详解
2018/07/30 Python
Python实现计算文件MD5和SHA1的方法示例
2019/06/11 Python
使用python获取(宜宾市地震信息)地震信息
2019/06/20 Python
python把转列表为集合的方法
2019/06/28 Python
Python3将数据保存为txt文件的方法
2019/09/12 Python
PyTorch 对应点相乘、矩阵相乘实例
2019/12/27 Python
python实现模拟器爬取抖音评论数据的示例代码
2021/01/06 Python
泰国的头号网上婴儿用品店:Motherhood.co.th
2019/04/09 全球购物
Hotels.com泰国:酒店预订网站
2019/11/20 全球购物
兰兰过桥教学反思
2014/02/08 职场文书
大学生入党推荐书范文
2014/05/17 职场文书
年度安全生产目标责任书
2014/07/23 职场文书
学校运动会广播稿
2014/10/11 职场文书
Oracle表空间与权限的深入讲解
2021/11/17 Oracle
20180830晚上第一届KSL半决赛 雨神vs解冻(二龙 三炮解说)
2022/04/01 星际争霸
Python线程池与GIL全局锁实现抽奖小案例
2022/04/13 Python