js做四則運算時,精度丟失問題及解決方法

2021-09-10 01:30:25 字數 2506 閱讀 9177

這個問題可以說是程式設計師必踩的坑,因此網上針對該問題的分析有很多也很詳細,解決方法也比較統一,寫法也是大同小異,本以為預期效果真能如他們所說是完美的,然而效果卻是差強人意。

首先,先來看看兩數相加的乙個經典問題,網上找過不少資料的人會發現,大多數人分析精度問題都是由此展開,然而最後所謂的解決方法成也在它,敗也在它。

0.1+0.2=0.30000000000000004
網上所說的完美解決方法:

function add(arg1,arg2)catch(e) 

trycatch(e)

maxdigits=math.pow(10,math.max(digits1,digits2))

return (arg1*maxdigits+arg2*maxdigits)/maxdigits

}

應用後的輸出結果:

0.1+0.2=0.3

從結果可以看出,這方法是完美的解決了這個經典問題,那其他數做運算是不是也都能完美解決呢?在我多數測試後發現並沒有,本以為有可能是開發環境或者瀏覽器導致的問題,但是切換了多個開發環境和瀏覽器也還是如此,因此可知,方法本身就有問題。

兩數直接相加的輸出結果:

2.22+2.22=4.44

4.44+2.22=6.66

6.66+2.22=8.88

8.88+2.22=11.100000000000001

11.10+2.22=13.32

13.32+2.22=15.540000000000001

應用網上找的方法的輸出結果:

2.22+2.22=4.44

4.44+2.22=6.660000000000001

6.66+2.22=8.88

8.88+2.22=11.100000000000001

11.10+2.22=13.32

13.32+2.22=15.54

對比兩次結果可以發現,有些數的精度問題是解決了,而有些數根本沒有解決,甚至還導致有些本不會出現精度問題的數產生了問題,除了加法,關於減乘除網上那些方法也一概行不通,限於篇幅,這裡就不再一一舉例。

最後發現那些方法都有個共同特徵,就是將原來帶n位小數的浮點數乘以10的n次方再進行運算,但是沒有解決的主要問題,還是資料型別運算。只要存在浮點數的運算,怎麼算也都會有精度問題。

因此,還是要保證參與運算的數為整數才行。保證為整數其實這點就是他們方法中將原來帶n位小數的浮點數乘以10的n次方,但還需要強制指定型別為int。但是如果直接將乘以10的n次方後的數轉換為integer物件,會導致在乘方時出現精度問題而出現精度丟失,即計算結果有誤。因此還是需要利用math庫中round方法,將數四捨五入取整再進行運算。

兩數相加方法:

function add(arg1, arg2)
應用該方法進行兩數相加的運算結果:

0.1+0.2=0.3

2.22+2.22=4.44

4.44+2.22=6.66

6.66+2.22=8.88

8.88+2.22=11.1

11.10+2.22=13.32

13.32+2.22=15.54

兩數相減(既一正數加一負數):

function subtract(arg1, arg2)
兩數相乘:

function multiple(arg1, arg2)
兩數相除:

/**

* arg1與arg2相除,並以四捨五入的方式保留小數點後2位

*/function divide(arg1, arg2) catch (e)

try catch (e)

return this.tofixed((n1 / n2) * math.pow(10, d2 - d1), 2);

} /**

* arg以四捨五入的方式保留小數點後n位

*/function tofixed(arg, n)

try else if (len == n)

// 小數以0開頭要往前補0

var b0 = '', k = 0

while(k < n && ds[1].substring(0, ++k) == '0')

return number(ds[0] + '.' + b0 + (d + carryd))

}} catch (e) {}

return arg

}

注:js中自帶的tofixed函式會把多餘的小數直接截掉,因此,這裡我進行重寫,採用四捨五入的方式保留小數,該方法也很實用。

解決double型別資料四則運算精度丟失問題

直接對double型別的資料進行計算,很容易發生精度丟失問題 使用bigdecimal類計算,可以避免精度丟失 double num2 double.parsedouble numstack.pop double num1 double.parsedouble numstack.pop bigdec...

高精度四則運算模板

1.讀取方式 利用 c string 讀取 2.儲存方式 利用c vector 儲存 示例 string a,b vector int a,b cin a b 對每個字元型數字減去 0 for int i a.size 1 i 0 i a.push back a i 0 數字逆序儲存 低位先存 高位...

js四則運算符

只有當加法運算時,其中一方是字串型別,就會把另乙個也轉為字串型別。其他運算只要其中一方是數字,那麼另一方就轉為數字。並且加法運算會觸發三種型別轉換 將值轉換為原始值,轉換為數字,轉換為字串。template section class p 10 el button type danger click...