JS-- 浮點數運算處理

來源:互聯網
上載者:User

標籤:自己   比較   res   length   string   tostring   highlight   存在   操作   

    一. 問題描述

     最近在做一個項目,頁面上會存在一些JS浮點數的運算,發現JS浮點數運算存在一些bug.譬如:

0.1+0.2 == 0.300000000000000040.1 + 0.7 == 0.79999999999999997*0.8 == 5.60000000000000055.6/7 == 0.7999999999999999

 

   二.解決方案    

   JS運算後都會有很小的誤差. 不像.Net或者Java那樣準確. 主要是JS重點不在運算上面,可是有時候項目一定要用到.想了一下大概有兩種解決方案

     A 方案一: 

    運算結果保留2-3位小數位元. 前端介面一般用到的運算比較少。精度要求不會太高。 所以取2位小數位即可。

     B. 方案二:

           將小數位元轉換為整數運算. 譬如:

0.1+0.2 =》 (1+2)/10 == 0.30.1 + 0.7 =》 (1+7)/10 == 0.87*0.8 == (7*8)/10 == 5.65.6/7 == (56/7)/10 == 0.1

       為了方便調用. 所以我們可以提取一個公用的方法出來.譬如下面的JSMath庫,JSMath重寫了加減乘除. 會先將參數轉換為整數再運算JSMath(參數1).操作(參數2)

       參數1和參數2分別就是運算的第一個Number和第二個Number. 計算後通過Value屬性擷取值.

(function() {    var JSMath = function() {        return this;    }    JSMath.prototype.from = function(value) {        // 支援JSMath參數傳遞主要是用於嵌套的調用        if ((typeof(value) == ‘object‘) && (value.value != undefined)) {            this.value = value.value;        } else {            this.value = value;        }        return this;    }  // 加法    JSMath.prototype.add = function(value) {        var thisValueString = this.value.toString();        var valueString = value.toString();        var timesCount1 = 0;        var timesCount2 = 0;        if (thisValueString.indexOf(‘.‘) > 0) {            timesCount1 = thisValueString.split(‘.‘)[1].length;        }        if (valueString.indexOf(‘.‘) > 0) {            timesCount2 = valueString.split(‘.‘)[1].length;        }        var maxtimeCount = timesCount1 > timesCount2 ? timesCount1 : timesCount2;        this.value = (Math.pow(10, maxtimeCount) * this.value + Math.pow(10, maxtimeCount) * value) / Math.pow(10, maxtimeCount);        return this;    }    // 減法    JSMath.prototype.sub = function(value) {        var thisValueString = this.value.toString();        var valueString = value.toString();        var timesCount1 = 0;        var timesCount2 = 0;        if (thisValueString.indexOf(‘.‘) > 0) {            timesCount1 = thisValueString.split(‘.‘)[1].length;        }        if (valueString.indexOf(‘.‘) > 0) {            timesCount2 = valueString.split(‘.‘)[1].length;        }        var maxtimeCount = timesCount1 > timesCount2 ? timesCount1 : timesCount2;        this.value = (Math.pow(10, maxtimeCount) * this.value - Math.pow(10, maxtimeCount) * value) / Math.pow(10, maxtimeCount);        return this;    }    // 除法      JSMath.prototype.div = function(value) {        var thisValueString = this.value.toString();        var valueString = value.toString();        var timesCount1 = 0;        var timesCount2 = 0;        if (thisValueString.indexOf(‘.‘) > 0) {            timesCount1 = thisValueString.split(‘.‘)[1].length;        }        if (valueString.indexOf(‘.‘) > 0) {            timesCount2 = valueString.split(‘.‘)[1].length;        }        var maxtimeCount = timesCount1 > timesCount2 ? timesCount1 : timesCount2;        this.value = ((Math.pow(10, maxtimeCount) * this.value) / (Math.pow(10, maxtimeCount) * value));        return this;    }  // 乘法    JSMath.prototype.times = function(value) {        var thisValueString = this.value.toString();        var valueString = value.toString();        var timesCount1 = 0;        var timesCount2 = 0;        if (thisValueString.indexOf(‘.‘) > 0) {            timesCount1 = thisValueString.split(‘.‘)[1].length;        }        if (valueString.indexOf(‘.‘) > 0) {            timesCount2 = valueString.split(‘.‘)[1].length;        }        var maxtimeCount = timesCount1 > timesCount2 ? timesCount1 : timesCount2;        this.value = (Math.pow(10, maxtimeCount) * this.value * Math.pow(10, maxtimeCount) * value) / Math.pow(10, maxtimeCount * 2);        return this;    }    if (window.JSMath == undefined) {        window.JSMath = function(value) {            var result = new JSMath();            result.from(value);            return result;        }    }})()
 

           B1.基本運算

0.1+0.2=> JSMath(0.1).add(0.2).value == 0.37+0.8=> JSMath(7).times(0.8).value == 5.65.6/7=> JSMath(5.6).div(7).value = 0.8

        B2.多目運算

0.05 + 0.05 + 0.2=> JSMath(JSMath(0.05).add(0.05)).add(0.2).value == 0.3(5+0.6)/7=> JSMath(JSMath(5).add(0.6)).div(7).value == 0.8

  三.小總結

    上面自己自己暫時知道的一些解決方案.不太清楚是否有開源的更可靠的三方庫來解決這個問題,如果有的話,希望博友推薦一下。

            貼一下Stockoverflow 裡面看到的一些解決方案:

            http://stackoverflow.com/questions/1458633/how-to-deal-with-floating-point-number-precision-in-javascript

           http://stackoverflow.com/questions/3556789/javascript-math-error-inexact-floats

JS-- 浮點數運算處理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.