4

私はさまざまな Web サービスに取り組んでおり、常に 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. すべての値を double に変換します (JAXB バインディング からBigDecimaldouble)
  2. へのマッピングdoubleを休止状態にするBigdecimal

すべての算術演算を 1 つのオブジェクト タイプで実行します。

4

2 に答える 2

10

浮動小数点形式 ( Java のdoubleやなど) を通貨操作に使用することは絶対に避けてください。浮動小数点形式floatは精度が限られており、測定から何らかの方法で導出された値を保持するように設計されているためです (この場合、完全に正確であるとは限りません)。その場合、制限された精度はそれほど問題ではありません)。

What Every Computer Scientist Should Know About Floating-Point Arithmeticこのトピックに関する記事です。数学は少し重いですが、それを理解するのに本当に役立ちます (あるいは、Michael Borgwardt によってリンクされた記事は理解しやすく、問題を実証/説明しています)。

この種の問題を回避するBigDecimalには、コード内で排他的にを使用、すべての外部ストレージ/転送ポイントも固定小数点/任意精度の値を使用するようにしてください (つまり、データベースも浮動小数点数を格納しないでください)。

于 2010-05-10T11:39:12.223 に答える
7
  • 浮動小数点ガイドを読む
  • doubleまたはfloat金額を使用しないでください
  • 代わりに使用してくださいBigDecimal。まさにそれが目的です
于 2010-05-10T11:40:00.247 に答える