Java BigDecimalクラスの使用と注意事項

3260 ワード

BigDecimalの概要
JDKドキュメント(中国語)の説明は以下の通りです.
可変で任意の精度の符号付き10進数.BigDecimalは任意の精度の整数非スケール値と32ビットの整数スケール(scale)からなる.ゼロまたは正の場合、スケールは小数点以下の桁数です.負数の場合、その数の非スケール値に10の負のscale乗を乗算します.したがって、BigDecimalが表す数値は(unscaledValue)× 10-scale).
具体的な解釈
1.「BigDecimalオブジェクトの値は可変」.この点はBigDecimalオブジェクトの演算関数において次のように表現されています.

   BigDecimal a = new BigDecimal("1.22");  
  
System.out.println("construct with a String value: " + a); 
BigDecimal b = new BigDecimal("2.22"); 
a.add(b); 
System.out.println("a plus b is : " + a);

私たちは簡単に出力すると思います.
construct with a Stringvalue:  1.22 a plus b is :3.44
しかし実際にはa plus b is:1.22
2.「BigDecimalは、任意の精度の整数非スケール値と32ビットの整数スケール(scale)で構成されています.スケール値がゼロまたは正の場合、スケールは小数点以下の桁数になります.」この言葉はこう見ることができます.
例:-12および13.412
表示:-12× 10-0および13412× 10-3
ここで(非スケール値とスケール)で表すと、それぞれ[-12,0]と[13412,3]
3.「スケール値が負の場合、その数の非スケール値に10の負のscale乗を乗じます」.この言葉はこう見ることができます.
例:120.00
この値は:12000と表示されます.× 10-2
ここで(非スケーリング値とスケーリング)で表すと,[1200,2]
ここで、スケールの値は正数2のままですが、次の操作を行います.
BigDecimal amount = new BigDecimal("-120.00");  //戻り値は小数点以下ですが、表示形式からすべての末尾ゼロのBigDecimalを削除します.  amount = amount.stripTrailingZeros(); 
この値は:12× 10-(-1)
ここでは(非スケーリング値とスケーリング)でそれぞれ:[12,-1]
使用上の注意
1.コンストラクタ

   BigDecimal aDouble =new BigDecimal(1.22);  
  
System.out.println("construct with a double value: " + aDouble); 
BigDecimal aString = new BigDecimal("1.22"); 
System.out.println("construct with a String value: " + aString);

出力結果は次のとおりです.
construct with a doublevalue:1.2199999999999999733546474089962430298328399658203125 construct with a String value: 1.22
JDKの説明:
a)パラメータタイプdoubleの構造方法の結果には一定の予知性がある.JavaにnewBigDecimal(0.1)を書き込んで作成されたBigDecimalは、ちょうど0.1(スケール値1ではなく、スケール値1)に等しいと考えられているかもしれませんが、実際には0.100000000000555123125782702181583404541015625に等しくなります.これは、0.1をdoubleと正確に表すことができないためである(または、この場合、任意の限られた長さのバイナリ小数として表すことができない).これにより、構造方法に入力される値は、表面的には0.1に等しくない.
b)一方、String構造方法は完全に予知可能である:newBigDecimal(「0.1」)を書き込むと、予想される0.1にちょうど等しいBigDecimalが作成される.したがって、比較的には、通常、String構造方法を優先的に使用することが推奨される.
c)doubleがBigDecimalのソースとして使用する必要がある場合、この構造方法は正確な変換を提供することに注意してください.Double.toString(double)メソッドを使用してからBigDecimal(String)コンストラクションメソッドを使用すると、次の操作と同じ結果は得られません.doubleをStringに変換するには、Stringのstaticメソッド:String.valueOf(double)を使用します.
2.演算操作.加減乗除は実際には最終的に新しいBigDecimalオブジェクトを返します.BigDecimalは可変であり、ステップごとに演算を行うと新しいオブジェクトが生成されるのでa.add(b);加算操作をしたが、aは加算操作後の値を保存しておらず、正しい使い方はa=a.add(b)であるべきである.
例:
BigDecimalオブジェクトが整数かどうかを判定します.

   private boolean isIntegerValue(BigDecimal bd) {  
  
  return bd.signum() == 0 || bd.scale() <= 0 || bd.stripTrailingZeros().scale() <= 0; 
}

なぜそうするのか、次の例をテストしてください.

   BigDecimal amount = new BigDecimal("-120.00");//     "0", "0.00", "1.00","10.00" "10.10"  
  
System.out.println(amount.signum());//  
System.out.println(amount.scale()); //  
System.out.println(amount.stripTrailingZeros().scale());//

参考:クラスBigDecimal