Java數值避免浮點型計算丟失精度問題


問題描述及方案

  • 假設我們在做電商項目,在進行計算時這個丟失精度在產品價格計算就會出現問題,很有可能造成我們手里有9.99元然后后面會有一堆9,但是呢這些錢無法購買一個10元的商品。
    在某些編程語言中有專門處理貨幣的類型,但是Java沒有,不過沒關系我們可以通過BigDecimal來解決這個問題。
  • 下面我們來看幾個例子。

testOne

  • Test1
  • 這個呢就是Java本身對於浮點計算的時候會丟失精度,一定要注意,一定要注意,它所引起的事情呢基本沒有小事,如果在線上訂購量大的話,會引起大的故障,可能會導致下不了訂單或是對賬出現問題

testTwo

  • Test2
  • 當使用BigDecimal后結果就更亂了,比test1結果還可怕又長又亂,它算出來的數比0.06是多的還是剛才那個意思,假設我們現在,
    銀行卡里面有0.06元然后我買的兩個商品,分別是0.05元和0.01,當我下單的時候如果沒有做處理那么他需要付的是0.06000000000000000298372437868010820238851010799407958984375 這就導致余額不夠,訂單無法下。這還沒解決,不要緊,接着看

testThree

  • Test3
  • 用String的BigDecimal構造器,這個結果就是我們想要的,本身呢BigDecimal這個類型是用它來解決這個問題但是我們在選擇用它的時候,一定一定一定要選擇它的String構造器一旦不用就像test2一樣會發生嚴重過的精度問題,這個原則在《Effective Java》這本書中也有說,是說這個原則如果float和double只能用來做 科學計算或者工程計算,但是在商業計算中我們要用BigDecimal。

源碼分析

1.說明

  • 在java.math包中找到API類BigDecimal,然后找到BigDecimal(double)構造方法
  • 說明
  • 源代碼里寫的很明白這個結果和這個構造器就會產生這個種問題它是無限接近於這么一個數這個構造器呢不是正好的,而是等於0.1

2.用法

  • 用法
  • 如果用這個構造器呢,把它轉成String,用Double的toString(double),里面放double然后用BigDecimal(String)這個String去構造,
    也就是說如果要用的話,就把它轉成String然后在選擇用BigDecimal的String構造器去獲得結果。另外3個這里就不講了自己去看;
  • 為了方便我們可以把它寫成一個util類,日后我整理完了會把它放在GitHub上。

原文:http://www.godql.com/blog/2017/05/17/Precision/
作者:Dr.Lester


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM