きどたかのブログ

いつか誰かがこのブログからトラブルを解決しますように。

Javaプログラマーがjava.math.BigDecimalについて知るべきこと

2012/11/4追記
こっち見てもらった方がいいかも。
Javaプログラマーのためのjava.math.BigDecimalまとめ - きどたかのブログ
2012/11/4追記 終わり


ざっくりと羅列してみた。

  1. java.math.BigDecimalは、クラス説明にある通り任意精度のスケールなし整数と、32bitのスケールで構成される。つまりは、BigDecimalはBigIntegerとintで構成されている。
  2. precisionとは「精度」であり、仮数の桁数である。仮数は任意精度のスケールなし整数のBigIntegerで、その10進表現での桁数である。
  3. precisionは一番左から初めに現れる0以外の数字から数えた桁数である。0.03の精度は1であり、スケール2である。
  4. BigDecimalの精度はprecisionで表現出来るが、double等の浮動小数点の精度は全体で使用するbit数で表現する。
  5. scaleとは小数点以下の桁数であり、それは基数10の指数部分である。(値2精度1スケール1= 0.2 = 2*10^-1 = 2E1)
  6. scaleをマイナス方向に増やすと、10倍づつ値は大きくなる。100は精度3スケール0だったり、精度1スケール-2なんてことがある。
  7. scaleはexponentであるが、BigDecimalの話をする場合はscaleと表現した方が良い。
  8. 0と0.0は等価(equals)ではないが、同一の順序付けである。(compareTo)
  9. intで表されていた丸めモードは、EnumのRoundingModeを使う新しい方法へシフトすべきだ。
  10. 演算中の丸め位置の指定はprecisionとscaleの二種類があるが、scaleの指定が出来るのは除算のみである。
  11. precisionとscaleの違いは、仮数の左端から考えるのがprecision、右端から考えてるのがscaleである。
  12. scale操作をする場合、一番右端から考えるのではなく、現在の小数点からの相対位置で考える。
  13. valueOf(double)を誤用してはならない。コンストラクタを使った方が、valueOf(double)よりも精度が高くなっている。
  14. スケールはオーバーフロー・アンダーフローすることがある。intの範囲を出てしまうケースがある。
  15. ゼロ除算すると例外になる。浮動小数点ではないのでInfiniteとかにはない。
  16. 正や負の無限大やNaNであるdoubleをコンストラクタやvalueOfに渡すとエラーになる。
  17. ハードウェア固有のDFP(10進浮動小数点)を使う場合、通常はprecisionによる計算をする。しかもMathContextの定数になっているようなIEEE規格が一般的。
  18. 数学的なlogを用いた計算、底数変換を用いて、precisionを0.3(=log[10] 2)で割ると、2進数の必要桁数(bit数)が求まり、その桁数を32で割れば、BigIntegerが内部で保持しないといけないint[]の要素数が求まる。
  19. toString()を安易に使うな。toPlainString()も読みなさい。
  20. movePointLeftやmovePointRightは、基本はスケール操作だが、精度の操作になるケースがある。