JAXB,BigDecimal还是double?

5
我是一名有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我正在处理不同的网络服务,我总是使用WSDL First。

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>

在JAXB规范中提到的Java绑定类型BigDecimal

当我使用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. 将所有值转换为double(从BigDecimaldouble的JAXB绑定)
  2. double映射到Bigdecimal(使用Hibernate)

并且在一个对象类型中执行所有算术操作。

2个回答

10

在货币运算中,浮点数格式(例如Java中的doublefloat)由于精度有限且仅设计用于保存某些测量派生出的值(这种情况下它们本来就不是绝对精确的,因此精度受到的限制更少),因此您永远不应使用。

每个计算机科学家都应该了解的浮点算术知识是关于此主题的文章。它涉及一些数学内容,但真正有助于理解(或者,Michael Borgwardt链接的文章更易于理解,但仍能演示/解释问题)。

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


所以您建议使用BigDecimal类型进行所有计算,并将存储类型保留为doubel(SQL Anywhere DB)。 - Alex
1
@Alex:不,那不是我说的。我的意思是:“使用BigDecimal进行所有计算,并确保使用一种可以在存储中保持相同精度的数据类型(大多数数据库都有固定点数据类型,通常称为“decimal”或类似名称)。 - Joachim Sauer
我将数据库类型转换为十进制,并使用BigDecimal类型进行所有计算。我的问题现在已经解决了。谢谢。 - Alex

7
  • 阅读浮点数指南
  • 永远不要使用doublefloat来表示货币金额
  • 使用BigDecimal代替,这正是它的用途

这是一个很好的资源,比我链接的文章容易理解多了;-) - Joachim Sauer
@Joachim:这正是我写它的原因 :) - Michael Borgwardt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接