從java中來說:2減1.1等於幾?

在Java中有一個奇怪的現象,我們編寫程式碼2-1。1,原本以為結果是非常明顯的0。9,但答案卻讓人大吃一驚,如圖:

從java中來說:2減1.1等於幾?

原因在於:Java基本資料型別中的float、double型別的實質是浮點數,浮點數不能儲存精確的資料,這樣的話,浮點數在進行計算的時候,計算結果就不是精確的值。所以這裡得出經驗,在實際開發中,我們在對數值進行計算的時候,應儘量避免使用Java的+ - * / 等運算子,因為容易出現損失精度的問題,導致最終的計算結果錯誤。

從java中來說:2減1.1等於幾?

尤其是在電商平臺中都是杜絕使用此種計算方式的,因為由於這種計算導致金額出現的誤差,所帶來的損失是無法估量的,也許就因為差一分錢,導致報表計算錯誤,客戶賬單對不上,都會帶來大麻煩。所以我們有必要找到一種正確的計算方法。

Java在java。math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。雙精度浮點型變數double可以處理16位有效數。在實際應用中,需要對更大或者更小的數進行運算和處理。float和double只能用來做科學計算或者是工程計算,在商業計算中要用java。math。BigDecimal。BigDecimal所建立的是物件,我們不能使用傳統的+、-、*、/等算術運算子直接對其物件進行數學運算,而必須呼叫其相對應的方法。

1、加法

從java中來說:2減1.1等於幾?

2、減法

從java中來說:2減1.1等於幾?

3、乘法

從java中來說:2減1.1等於幾?

在上述的截圖中,會發現我們在做運算之前,都會將double值轉化為String值,儘管BigDecimal提供了多種構造方法,也是支援傳入double值的,但這裡我們並不推薦。因為傳入double值是容易出問題的,如圖:

從java中來說:2減1.1等於幾?

a)引數型別為double的構造方法的結果有一定的不可預知性。有人可能認為在Java中寫入newBigDecimal(0。1)所建立的BigDecimal正好等於 0。1(非標度值 1,其標度為 1),但是它實際上等於0。1000000000000000055511151231257827021181583404541015625。這是因為0。1無法準確地表示為 double(或者說對於該情況,不能表示為任何有限長度的二進位制小數)。這樣,傳入到構造方法的值不會正好等於 0。1(雖然表面上等於該值)。

b)另一方面,String 構造方法是完全可預知的:寫入 newBigDecimal(“0。1”) 將建立一個 BigDecimal,它正好等於預期的 0。1。因此,比較而言,通常建議優先使用String構造方法。

c)當double必須用作BigDecimal的源時,請注意,此構造方法提供了一個準確轉換;它不提供與以下操作相同的結果:先使用

Double。toString(double)

方法,然後使用

BigDecimal(String)

構造方法。將double轉換為String,也可以使用String的static方法:String。

valueOf(double)

4、除法

從java中來說:2減1.1等於幾?

在使用除法時,我們發現divide方法中,我們多傳入了幾個引數。如果對於可以除盡的數不傳入這兩個引數也是沒有問題的,但如果我們使用100除以3會出現什麼問題呢?

從java中來說:2減1.1等於幾?

我們發現報錯了,原因在於:透過BigDecimal的divide方法進行除法時當不整除,出現無限迴圈小數時,就會拋異常:java。lang。ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result。 所以不管能不能除盡,我們都要防患於未然告訴運算器我們除不盡的方案是什麼。

BigDecimal已經幫助我們定義好了舍入模式,只有在作除法運算或四捨五入時才用到舍入模式。如下圖:

從java中來說:2減1.1等於幾?

這麼多的四捨五入模式,我們在實際開發中應該使用那種呢,這個還是要分情況的。我倒是建議使用UNNECESSARY這種模式:計算結果是精確的,不需要四捨五入,那你可能會說這樣不就有問題了嗎?彆著急,待計算完成後我們再單獨對結果進行四捨五入?為什麼要這樣呢?因為我們不能保證我們的程式中只存在一次計算,如果我們有一個公式要連續對數值進行乘法和除法,每次都四捨五入,那計算結果才會有問題,但如果我們只對最終的結果值四捨五入就沒有問題了,因為多數在儲存的時候,資料庫都要求保留兩位小數。首先我們來看下不同的模式下計算的結果值有什麼差異?

從java中來說:2減1.1等於幾?

在UNNECESSARY的時候最為精確。因為其保留的小數也最多。具體我們可以開啟原始碼自己看下原因。那最終我們如何將數值保留兩位小數呢?

從java中來說:2減1.1等於幾?

當然,我的這個經驗我也不能百分百是完全正確的,只是說在我的日常工作中的確這麼做的,如果各位有不同的意見請儘快告訴我。

推薦一下我的java免費資料分享群:614181335,裡面都是學習java的,如果你正在學習,小編歡迎你加入,不定期分享乾貨,包括影片原始碼等,歡迎初學和進階中的小夥伴

從java中來說:2減1.1等於幾?