解决JS浮点数运算出现Bug的方法

 更新时间:2013年03月12日 12:12:33   作者:  
解决JS浮点数运算出现Bug的方法,需要的朋友可以参考一下

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>

相关文章

  • 使用smartupload组件实现jsp+jdbc上传下载文件实例解析

    使用smartupload组件实现jsp+jdbc上传下载文件实例解析

    这篇文章主要介绍了使用smartupload组件实现jsp+jdbc上传下载文件实例解析,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-01-01
  • 原生JS实现pc端轮播图效果

    原生JS实现pc端轮播图效果

    这篇文章主要为大家详细介绍了原生JS实现pc端轮播图效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • Js中Symbol的静态属性及用途详解

    Js中Symbol的静态属性及用途详解

    JavaScript 语言在 ES6 规范中引入了 Symbol 类型,它是一种原始数据类型,用于创建唯一的标识符,本文将介绍 Symbol 类型的所有静态属性,并举例说明它们的用途和使用场景,希望对大家有所帮助
    2023-12-12
  • bootstrap 下拉多选框进行多选传值问题代码分析

    bootstrap 下拉多选框进行多选传值问题代码分析

    项目开发遇到个问题,就是引入bootstrap下拉多选框进行多选的时候,用form表单提交到后台,获取不到多选的值,只能获取的选择的第一个值,怎么回事呢?下面小编给大家分析下bootstrap 下拉多选框进行多选传值问题,一起看看吧
    2017-02-02
  • js实现tab选项卡函数代码

    js实现tab选项卡函数代码

    js实现tab选项卡函数代码,需要的朋友可以参考下,这样的代码也是比较常用的,相当原理也比较简单。
    2010-04-04
  • 深入解析Parcel如何进行自定义配置

    深入解析Parcel如何进行自定义配置

    Parcel 是现代前端开发中不可或缺的工具之一,以其“零配置”的特性迅速赢得了开发者的青睐,本文将通过几个实例详细介绍如何进行 Parcel 的自定义配置,感兴趣的小伙伴可以了解下
    2024-12-12
  • 不唐突的JavaScript的七条准则整理收集

    不唐突的JavaScript的七条准则整理收集

    在开始设计你的脚本之前,要考虑的第一件事情就是检查一下你要为其编写脚本的HTML代码,看看有什么东西可以帮助你达到目的。
    2008-10-10
  • js实现前面自动补全位数的方法

    js实现前面自动补全位数的方法

    今天小编就为大家分享一篇js实现前面自动补全位数的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10
  • js实现下拉框选择要显示图片的方法

    js实现下拉框选择要显示图片的方法

    这篇文章主要介绍了js实现下拉框选择要显示图片的方法,涉及针对js操作select的技巧,非常具有实用价值,需要的朋友可以参考下
    2015-02-02
  • javascript实现倒计时提示框

    javascript实现倒计时提示框

    这篇文章主要为大家详细介绍了javascript实现倒计时提示框,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-03-03

最新评论