JAXB, BigDecimal или двойной? - PullRequest
4 голосов
/ 10 мая 2010

Я работаю над разными веб-сервисами и всегда использую 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>

тип привязки 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.2360000000000000153210777398271602578461170196533203125</ns5:totalextax>

Что будет правильным?

  1. Преобразовать все мои значения в двойные (привязка JAXB из BigDecimal в double)
  2. Отображение Hibernatedouble до Bigdecimal

и выполнять все мои арифметические операции в одном типе объекта.

Ответы [ 2 ]

10 голосов
/ 10 мая 2010

Вы никогда не хотите использовать форматы с плавающей запятой (например, double и float в Java) для валютных операций, поскольку они имеют ограниченную точность и предназначены для хранения значений, которые так или иначе получены из измерения (в этом случае они не совсем точны для начала, и в этом случае ограниченная точность является меньшей проблемой).

Что должен знать каждый компьютерный ученый об арифметике с плавающей точкой - это статья на эту тему. Это немного тяжело с математикой, но это действительно помогает понять (в качестве альтернативы, статья, на которую ссылается Майкл Боргвардт, намного проще для понимания и все еще демонстрирует / объясняет проблему).

Чтобы избежать такого рода проблем, убедитесь, что вы используете BigDecimal исключительно в своем коде и , чтобы все внешние точки хранения / передачи также использовали значения с фиксированной или произвольной точностью (т.е. база данных также не должна хранить числа с плавающей запятой).

7 голосов
/ 10 мая 2010
...