码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-02-09 23:16:17      阅读:406      评论:0      收藏:0      [点我收藏+]

标签:javascript   浮点数   运算优化   

说明

众所周知,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));
}

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

标签:javascript   浮点数   运算优化   

原文地址:http://blog.csdn.net/qinshenxue/article/details/43671763

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!