2010-05-10 84 views
4

我工作在不同的Web服務上,而且我總是使用WSDL First。JAXB,BigDecimal還是double?

JAXB生成用於像類型:

<xsd:simpleType name="CurrencyFormatTyp"> 
    <xsd:restriction base="xsd:decimal"> 
     <xsd:totalDigits value="13"/> 
     <xsd:fractionDigits value="2"/> 
     <xsd:minInclusive value="0.01"/> 
    </xsd:restriction> 
</xsd:simpleType> 

一個Java綁定類型BigDecimal(因爲它在JAXB規範真實提到的)。

當我然後做一些簡單的算術運算,類型爲double(它們存儲在數據庫中,並通過休眠映射到double類型)的值,我遇到了麻煩。

<ns5:charge>0.200000000000000011102230246251565404236316680908203125</ns5:charge>   
<ns5:addcharge>0.0360000000000000042188474935755948536098003387451171875</ns5:addcharge> 
<ns5:tax>0.047199999999999998900879205621095024980604648590087890625</ns5:tax> 
<ns5:totalextax>0.777398271602578461170196533203125</ns5:totalextax> 

什麼是正確的方法?

  1. 轉換我的所有數值爲雙
  2. Hibernate映射double(JAXB從BigDecimaldouble結合),以Bigdecimal

,做我所有的算術運算在一個對象類型。

回答

10

你再也不想使用floating point格式(在Java中如doublefloat)貨幣操作,因爲他們只有有限的精度,並已設計成認爲,在某種程度上,從測量得到的值(在這種情況下,他們並不是絕對準確的,在這種情況下,有限的精度不會成爲問題)。

What Every Computer Scientist Should Know About Floating-Point Arithmetic該主題的文章。這在數學上有點沉重,但它確實有助於理解(或者,由Michael Borgwardt鏈接的文章是很多更容易理解,並且仍然演示/解釋問題)。

爲了避免這種問題,請確保您使用BigDecimal只在你的代碼所有外部存儲/傳輸點使用定點/任意精度值以及(即你的數據庫不應該存儲浮點數字)。

+0

所以你建議做所有的計算與類型BigDecimal的,並將存儲類型保留爲double(SQL Anywhere DB)。 – Alex 2010-05-10 11:52:18

+1

@亞歷克斯:不,那**不**我說的。我在說的是:「用BigDecimal執行所有計算,並確保使用可保持存儲相同精度的數據類型(大多數數據庫都有一個定點數據類型,通常稱爲」十進制「或類似的東西)。 – 2010-05-10 11:55:34

+0

我將數據庫類型轉換爲十進制數,然後使用BigDecimal類型進行所有計算。我的問題現在已經修復。謝謝。 – Alex 2010-05-10 13:19:47

7
  • 閱讀Floating-Point Guide
  • 決不使用doublefloat金錢數額
  • 使用BigDecimal相反,這正是它是
+0

這是一個很好的資源,比我鏈接的文章更容易理解;-) – 2010-05-10 11:41:45

+0

@Joachim:完全正確爲什麼我寫了:) – 2010-05-10 11:52:34

+0

很好的資源,謝謝! – Alex 2010-05-10 13:19:11

相關問題