js中Number数字数值运算后值不对的解决方法

问题:

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);
}

减法函数

function accSub(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));
//last modify by deeka
//动态控制精度长度
n = (r1 >= r2) ? r1 : r2;
return ((arg1 * m - arg2 * m) / m).toFixed(n);
}

在你要用的地方包含这些函数,然后调用它来计算就可以了。

比如你要计算:7*0.8 ,则改成 (7).mul(8)

其它运算类似,就可以得到比较精确的结果。

以上这篇js中Number数字数值运算后值不对的解决方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

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

    37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.08499999999998 怎么会这样,两个只有一位小数的数字相乘,怎么可能多出这么小数点出来. 我Google了一下,发现原来这是JavaScript浮点运算的一个bug. 比如:7*0.8 JavaScript算出来就是:5.6000000000000005 网上找到了一些解决办法,就是重新写了一些浮点运算的函数或直接扩大倍数运算. 下面就把这

  • js中Number数字数值运算后值不对的解决方法

    问题: 37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.08499999999998 怎么会这样,两个只有一位小数的数字相乘,怎么可能多出这么小数点出来. 我Google了一下,发现原来这是JavaScript浮点运算的一个bug. 比如:7*0.8 JavaScript算出来就是:5.6000000000000005 解决方法:网上找到了一些解决办法,就是重新写了一些浮点运算的函数. 下面就把这

  • 关于JS中setTimeout()无法调用带参函数问题的解决方法

    本文实例分析了JS中setTimeout()无法调用带参函数问题的解决方法.分享给大家供大家参考,具体如下: 解决方法:重写setTimeout() 方法,需要用到闭包函数.如下: var _st = window.setTimeout; window.setTimeout = function(fRef, mDelay){ if (typeof fRef == 'function') { var argu = Array.prototype.slice.call(arguments, 2);

  • js中class的点击事件没有效果的解决方法

    如下所示: $(".xx").clcik(function(){····}); 本来不用js生成类,是有点击效果的一但js里写,就没有点击效果了,如下: 做如下修改即可,监听document 以上就是小编为大家带来的js中class的点击事件没有效果的解决方法全部内容了,希望大家多多支持我们~

  • Vue数组中出现__ob__:Observer无法取值问题的解决方法

    目录 问题说明 解决问题 结果图 总结 问题说明 在开发项目中经常要从数据库中拿到数组然后复制给新的数组使用,但是会发现有时候会发现带有 __ob__: Observer 数组后缀的就是没有办法取到值,更可怕的是 console.log 却能看得到值.数组如下图所示: 解决问题 那么针对这样的问题博客上基本上都是说要将数组转化成string对象运用这个JSON.parse(JSON.stringify(数组))再进行赋值,然后一顿操作数组变成空!!! 说实话根本不是这个原因,哎被坑了一下午! 那

  • node.js中格式化数字增加千位符的几种方法

    每三位以逗号分隔的处理方式 正则方式: 复制代码 代码如下: "15000000".split("").reverse().join("").replace(/(\d{3})/g, "$1,").split("").reverse().join(""); "115000000".split("").reverse().join("&quo

  • js中的window.open返回object的错误的解决方法

    解决window.open后返回object的错误 复制代码 代码如下: <a href="javascript:void(window.open('','','width=200,height=200'))">window.open()</a> 只在js的外层加上一个void不带返回参数的声明. 顺便在这里将window.open函数的参数使用也列出来: window.open函数参数列表 window = object.open([URL ][, name

  • 提升node.js中使用redis的性能遇到的问题及解决方法

    问题初现 某基于node.js开发的业务系统向外提供了一个dubbo服务,提供向第三方缓存查询.设置多项业务数据并聚合操作结果.在QPS达到800时(两台虚拟机,每台机器4Core8G4node进程),在监控平台上出现了非常多的slow rt警告,平均接口响应达到60+ms,请求报警率达到80%+. 为找到造成该服务吞吐量过低的罪魁祸首,业务人员在请求日志中打点了所有查询缓存的操作,结果显示每个请求查询缓存耗时在50-100ms之间跳动.查询了redis-server的监控数据发现,不存在ser

  • 深入理解JS中Number(),parseInt(),parseFloat()三者比较

    参考阅读: 详解js中Number().parseInt()和parseFloat()的区别 详解JS转换数值函数Number().parseInt().parseFloat() 在项目开发中我们经常会用到转型方法,尤其是JS这种松散型的语言.其中比较常用的方法就是Number()方法和ParseInt()/ParseFloat()方法了,下面我们分别对这几种方法的转型机制进行详细地说明.具体内容详情如下所示: [正文内容] Number() --------------------------

  • 详解javaScript中Number数字类型的使用

    目录 前言 Number数字 自带属性值 基础使用 总结 源码地址 前言 Number和Math都属于JavaScript中的内置对象,Number数字类型作为基础数据类型,我们在开发过程中会经常用到,包括数字精度的格式化,还有字符串转换成数字等操作. Number数字 自带属性值 Number.EPSILON 两个可表示(representable)数之间的最小间隔. Number.MAX_SAFE_INTEGER JavaScript 中最大的安全整数 (2^53 - 1). Number.

  • js中字符型和数值型数字的互相转化方法(必看)

    数值型的数字字符型数字之间如何互相转化呢,其实有个很简便的方法: 比如字符串"123.45"和数值型123.45. 字符串型只要在前面加个+好就可以了. 数值型只要在后面加个空字符串""就可以了. 上图: 以上这篇js中字符型和数值型数字的互相转化方法(必看)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

随机推荐