4

我从事不同的 Web 服务,我总是首先使用 WSDL。

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(存储在数据库中并通过 hibernate 映射到 double 类型)进行一些简单的算术运算时,我遇到了麻烦。

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

什么是正确的方法?

  1. 将我的所有值转换为双精度(JAXB 绑定从BigDecimaldouble
  2. 休眠映射doubleBigdecimal

并以一种对象类型执行我所有的算术运算。

4

2 回答 2

10

您永远不想使用浮点格式(例如JavadoublefloatJava)进行货币运算,因为它们的精度有限,并且被设计为保存以某种方式从测量中得出的值(在这种情况下,它们不是绝对精确的)首先,在这种情况下,有限的精度不是问题)。

关于浮点运算的每个计算机科学家都应该知道的内容是关于该主题的文章。数学有点重,但它确实有助于理解这一点(或者,Michael Borgwardt 链接到的文章容易理解,并且仍然演示/解释了问题)。

为避免此类问题,请确保您BigDecimal只在代码中使用,并且所有外部存储/传输点也使用定点/任意精度值(即您的数据库也不应该存储浮点数)。

于 2010-05-10T11:39:12.223 回答
7
  • 阅读浮点指南
  • 切勿使用doublefloat换取金钱
  • 改用BigDecimal,这正是它的用途
于 2010-05-10T11:40:00.247 回答