Javascript优化后的加减乘除(解决js浮点数计算bug)

说明

众所周知,js在计算浮点数时候,结果可能会不准确。比如:(在chrome中的运算结果)

2.2 + 2.1 = 4.300000000000001

2.2 - 1.9 = 0.30000000000000027

2.2 * 2.2 = 4.840000000000001

2.1 / 0.3 = 7.000000000000001

网上流传的代码(有bug)

网上流传的优化后的代码如下(有问题的代码,请勿使用)

function add(a, b) {
    var c, d, e;
    try {
        c = a.toString().split(".")[1].length;
    } catch (f) {
        c = 0;
    }
    try {
        d = b.toString().split(".")[1].length;
    } catch (f) {
        d = 0;
    }
    return e = Math.pow(10, Math.max(c, d)), (a * e + b * e) / e;
}

function sub(a, b) {
    var c, d, e;
    try {
        c = a.toString().split(".")[1].length;
    } catch (f) {
        c = 0;
    }
    try {
        d = b.toString().split(".")[1].length;
    } catch (f) {
        d = 0;
    }
    return e = Math.pow(10, Math.max(c, d)), (a * e - b * e) / e;
}

function mul(a, b) {
    var c = 0,
        d = a.toString(),
        e = b.toString();
    try {
        c += d.split(".")[1].length;
    } catch (f) {}
    try {
        c += e.split(".")[1].length;
    } catch (f) {}
    return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
}

function div(a, b) {
    var c, d, e = 0,
        f = 0;
    try {
        e = a.toString().split(".")[1].length;
    } catch (g) {}
    try {
        f = b.toString().split(".")[1].length;
    } catch (g) {}
    return c = Number(a.toString().replace(".", "")), d = Number(b.toString().replace(".", "")), c / d * Math.pow(10, f - e);
}

原理就是将浮点数转化为整数来计算。

问题代码测试

但是上面的优化方法真的解决问题了吗,我们可以简单做下测试。

测试代码如下:(测试运算中加法)

function test(){
    var a = (Math.random() * 100).toFixed(2) - 0;
    var b = (Math.random() * 1000).toFixed(2) - 0;
    var result = add(a, b);
    if ((result + ‘‘).length > 10) {
        console.error(‘被加数:‘+a,‘加数:‘+b, ‘结果:‘+result);
        return;
    }
    setTimeout(function() {
        test();
    }, 10);
}
test();

问题代码测试结果

浏览器控制台很快就打印了结果,说明被测试的加法运算代码存在运算不准确的问题。

测试运行结果:

问题代码出错原因

既然上面的代码有问题,那么出错的点在哪里,我们就以计算错误的数字来调试代码。

被加数:19.36 加数:601.19 结果:620.5500000000001

调试的过程及结果如下:

我们发现原来是其中的乘法计算错误。

修正方法

网上有一些版本你会发现在最终返回结果的时候加上了toFixed,这是一种解决方法。

另外既然是乘法出错,我们何不将乘法换成优化后的乘法了。比如修改后的加法如下:

function add(a, b) {
    var c, d, e;
    try {
        c = a.toString().split(".")[1].length;
    } catch (f) {
        c = 0;
    }
    try {
        d = b.toString().split(".")[1].length;
    } catch (f) {
        d = 0;
    }
    return e = Math.pow(10, Math.max(c, d)), (mul(a, e) + mul(b, e)) / e;
}

然后用上面的方法进行测试,等了”一天“,控制台也没打印了。说明这次真的把问题解决了。

最终版(正确版)

function add(a, b) {
    var c, d, e;
    try {
        c = a.toString().split(".")[1].length;
    } catch (f) {
        c = 0;
    }
    try {
        d = b.toString().split(".")[1].length;
    } catch (f) {
        d = 0;
    }
    return e = Math.pow(10, Math.max(c, d)), (mul(a, e) + mul(b, e)) / e;
}

function sub(a, b) {
    var c, d, e;
    try {
        c = a.toString().split(".")[1].length;
    } catch (f) {
        c = 0;
    }
    try {
        d = b.toString().split(".")[1].length;
    } catch (f) {
        d = 0;
    }
    return e = Math.pow(10, Math.max(c, d)), (mul(a, e) - mul(b, e)) / e;
}

function mul(a, b) {
    var c = 0,
        d = a.toString(),
        e = b.toString();
    try {
        c += d.split(".")[1].length;
    } catch (f) {}
    try {
        c += e.split(".")[1].length;
    } catch (f) {}
    return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
}

function div(a, b) {
    var c, d, e = 0,
        f = 0;
    try {
        e = a.toString().split(".")[1].length;
    } catch (g) {}
    try {
        f = b.toString().split(".")[1].length;
    } catch (g) {}
    return c = Number(a.toString().replace(".", "")), d = Number(b.toString().replace(".", "")), mul(c / d, Math.pow(10, f - e));
}
时间: 2024-10-14 13:00:08

Javascript优化后的加减乘除(解决js浮点数计算bug)的相关文章

关于js浮点数计算精度不准确问题的解决办法

今天在计算商品价格的时候再次遇到js浮点数计算出现误差的问题,以前就一直碰到这个问题,都是简单的使用tofixed方法进行处理一下,这对于一个程序员来说是及其不严谨的.因此在网上收集了一些处理浮点数精度的文章.觉得别人写的挺好了,我在简单的总结一下,以方便后续查阅. 浮点数误差产生的原因: 先看一个实例: 0.1 + 0.2 =? 0.1 + 0.2 = 0.3? 我们先来看一段 JS. console.log( 0.1+ 0.2); 输出为 0.30000000000000004.是不是很奇葩

js浮点数计算问题 + 金额大写转换

一 js浮点数计算问题解决方案: 1.使用 NumberObject.toFixed(num) 方法 toFixed() 方法可把 Number 四舍五入为指定小数位数的数字. 2.较精度计算浮点数 //说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显.这个函数返回较为精确的加法结果. //调用:accAdd(arg1,arg2) //返回值:arg1加上arg2的精确结果 function accAdd(arg1, arg2) { var r1, r2, m; t

解决JS浮点数(小数)计算加减乘除的BUG

/**  ** 加法函数,用来得到精确的加法结果  ** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显.这个函数返回较为精确的加法结果.  ** 调用:accAdd(arg1,arg2)  ** 返回值:arg1加上arg2的精确结果  **/ function accAdd(arg1, arg2) {     var r1, r2, m, c;     try {         r1 = arg1.toString().split(".")[1].

JS浮点数运算Bug的解决办法【转】

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

js浮点数计算(加,减)

最近工作中经常遇到需要处理浮点型计算的问题,开始一直都在用把浮点数先乘以10的对应小数的位数的次方化成整数再去开始计算. 例如100.01+100.02,可以化成(100.01*100+100.02*100)/100来做计算,但是最近发一个浮点数乘以一个10的次方也会有精度问题发生,突然感觉前面的工作是不是有好多地方埋了很多坑啊,不能愉快的工作啦. 正好周未没什么别的计划,想研究下怎么处理JS的浮点型计算的精度问题 既然浮点数的计算精度有问题,那何不就在计算过程中绕过浮点型的计算了,于是有如下思

js浮点数算术出现多为小数

/****************************************解决JS浮点数(小数)计算加减乘除的BUG Start****************************************/ 问题:js浮点数运算问题---莫名出现多位小数 // 原因:这是由于在运算的时候先把浮点数转化成二进制后进行运算,// 但是有的小数在二进制编码后出现无限循环,// 因而导致计算出现了误差,在其它变成语言中也有类似的问题. /**** 加法函数,用来得到精确的加法结果** 说明:

js浮点数相加、减、乘、除精确计算

js 浮点数计算时 ,无缘无辜 后边冒出一堆 小数点………… 貌似js本身的问题,类型不定?????? 只能自己写函数处理..  http://blog.csdn.net/w4bobo/article/details/9143663 借鉴一下 1 //调用:accAdd(arg1,arg2) 2 //返回值:arg1加上arg2的精确结果 3 function accAdd(arg1,arg2){ 4 var r1,r2,m; 5 try{r1=arg1.toString().split(".&

使用live delegate on来解决js对后加载的html失效的问题

今天要写一个前端的东西.每多学一点知识,就可以少写几行代码.几十行代码.几个文件量的代码--这是真的.一直对前端的研究都是停留在遇到问题百度谷歌答案的做法.今天遇到这样一个问题:已经写好的js代码,对ajax加载的html失效了. 用好几组关键字都没有找到答案,最后这组帮我找到了解答的办法: javascript not work on ajax content 很幸运,我来到了:http://stackoverflow.com/questions/10161938/jquery-functio

Ajax中主页加载分页面后,分页面js脚本不执行的解决办法

没看懂,稍后再看 Ajax中主页加载分页面后,分页面js脚本不执行的解决办法 最近捣鼓JQuery,其中强大的Ajax系列函数令人印象深刻,所以做项目时毫不犹豫地采用了一下该技术,在主页中动态加载分页面进来,咋看效果 不错,都能实现了第一层次的加载,但深入下去问题就出来了:动态加载进来的页面中外联了js文件,其中的脚本却没有在加载后运行! (脚本在单独浏览该分页面时运行是正常的) 我郁闷了,打开Firefox中的Firebug查看了加载后的主页面中的DOM,所有元素的加载都是正常的啊~ 自己改来