2010-08-04 55 views
4

在後端,我將貨幣值存儲在一個Money類中,該類包裝一個BigDecimal並將舍入設置爲始終爲Half Even。所有基本操作都可以正常工作並按預期行事。但是我需要以2的刻度向用戶顯示這些值,這就是我的四捨五入錯誤。在Java的UI中顯示資金的正確方法是什麼?

例如,我在後端具有這些值:

一個= 109.11432
B = 9015.57069
C = 9124.68501

它們中的每一個被格式化到PT-BR區域設置:

NumberFormat nf = NumberFormat.getInstance(); 
nf.setCurrency(Currency.getInstance(new Locale("pt","BR"))); 
nf.setMinimumFractionDigits(2); 
nf.setMaximumFractionDigits(2); 
String n = nf.format(valor); 
return n; 

然後,我有

A = 109,11
B = 9.015,57
C = 9.124,69

這是很正常的,在第一。但c應該是a + b。有了真正的價值,這是有保證的,但舍入給我一個0.01的錯誤。

處理這種情況的正確方法是什麼?

+0

我不認爲你應該存儲109.11432,圍繞它,我的意思是當你去商店時,收銀員要求你支付5,90132美元? ;] – 2010-08-04 20:53:53

+0

在我得到這些結果之前,我做了很多操作,大量的乘法,加法,除法,導致我展示的這些值。如果我圍繞每一個操作,最後我的錯誤比1分大得多。我以前做過。 – 2010-08-05 23:18:47

回答

1

它似乎正在做你想要的。您存儲它的方式遠遠超過0.01。如果這不是你的意圖,那麼就停止這樣做:)

如果你想要一個+ b等於c有2個小數位,那麼你需要在添加之前舍入。解決您的問題取決於您的應用程序的要求。存儲貨幣的一種常見方式實際上是一個整數。這樣,你不能存儲分數,你永遠不會有你目前描述的問題。

但它確實取決於您的要求。你是否需要基於0.01或者完全精確度進行金錢算術,然後圍繞最終結果?這是一個商業問題,而不是技術問題。

+0

確定你可以有同樣的問題 - 你仍然需要在某個時候回合。 – 2010-08-04 21:03:36

+0

不,你不可能有完全相同的問題,因爲他添加了兩個存儲的貨幣值。在使用整數時添加兩個存儲的貨幣值不能有1 + 7 = 9,這是他正確的問題。 使用整數迫使您在存儲值之前作出舍入和算術的相應決定。 – mentics 2010-08-05 20:23:29

+0

我需要根據完整的準確性進行金錢算術,然後圍繞最終結果。那就是問題所在。 – 2010-08-05 23:20:11

0

如果我正在寫金錢課,我會讓它包含兩個整數部分 - 美元和美分(或雷亞爾和centavos,或其他)。這樣你永遠不會得到分數美分。你只需要在加法和減法操作中處理超過100美分的滾動。

編輯:

對我原來的答覆的評論有一個好點。另一種選擇是隻存儲美分數,然後在需要顯示時除以100。

+0

我不認爲這是處理這個問題的好方法,所以執行所有操作時會出現太多問題,以便它們正常工作。我認爲這太容易出錯。 – 2010-08-04 20:44:53

1

請注意,NumberFormat可以有rounding mode

但是最終,沒有四捨五入方法可以滿足像「這些值必須加在一起」這樣的業務需求,而不是專門爲這種情況設計的。 Round-half-even旨在避免大規模偏差,而不是單個最後十進制誤差。那麼你最初從哪裏獲得數據?這就是你必須確保舍入保留總數的地方。

由於您只顯示2位數據,因此存儲8位小數的數據真的是一項要求嗎?我也會質疑「有了真實值,這是有保證的」的假設,因爲同樣的事情發生在那裏,在任何計算產生值後舍入到8位數。

相關問題