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