Pergunta

Trabalho em diferentes serviços da Web e sempre uso o WSDL primeiro.

Jaxb gera para um tipo como:

<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>

um tipo de ligação a java BigDecimal (como é mencionado na especificação JAXB).

Quando eu faço uma operação aritmética simples com valores do tipo double (que são armazenados em um banco de dados e mapeados via Hibernate para o Tipo Double) Eu tenho problemas.

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

Qual seria o caminho certo?

  1. Converter todos os meus valores em duplo (Jaxb Ligation de BigDecimal para double)
  2. Mapeamento de hibernato double para Bigdecimal

e faça todas as minhas operações aritméticas em um tipo de objeto.

Foi útil?

Solução

Você nunca quer usar ponto flutuante formatos (como double e float em Java) para operações de moeda, porque elas têm precisão limitada e foram projetadas para manter valores que de alguma forma são derivados da medição (nesse caso, eles não são absolutamente precisos, para começar, nesse caso, a precisão limitada é menos um problema ).

O que todo cientista da computação deve saber sobre aritmética de ponto flutuante é a artigo sobre o tópico. É um pouco pesado em matemática, mas realmente ajuda a entender isso (alternativamente, o artigo vinculado por Michael Borgwardt é Muito de mais fácil de entender e ainda demonstra/explica o problema).

Para evitar esse tipo de problema, certifique -se de usar BigDecimal exclusivamente em seu código e que todos os pontos de armazenamento/transferência externos também usam valores de ponto fixo/precisão arbitrária (ou seja, seu banco de dados também não deve armazenar números de ponto flutuante).

Outras dicas

  • Leia o Guia de ponto flutuante
  • Nunca usar double ou float Para valores em dinheiro
  • Usar BigDecimal Em vez disso, é exatamente para isso
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top