Javascript最佳化後的加減乘除(解決js浮點數計算bug)__大資料

來源:互聯網
上載者:User
訪問http://qinshenxue.com/article.aspx?id=1查看最新文章 說明

眾所周知,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));}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.