2015.07.10 システム
新人エンジニアのための言語紹介3
こんにちは、エンジニアの阿久津です。
さて、前回Javaをインストールしてから数週間たちました。
今回についてはJavaの基礎的な項目ですが、
意外と間違えやすい【BigDecimal】について説明してみようかと思います。
1.BigDecimalとは・・・?
J2SEに含まれるクラスのひとつ。パッケージも含めたクラス名はjava.math.BigDecimal。
実数値を格納するためのクラス。 ただし、格納方法は浮動小数点ではない。
double型のような浮動小数点形式で実数を処理すると、丸め誤差が生まれる。
そのため、正確な値を格納するために、浮動小数点ではない丸め誤差の発生しない方法で値を格納するのがBigDecimalクラスである。
はい、いろいろ複雑な用語が出てきました。
簡単に説明すると
浮動小数点のdoubleとかで計算する際には2進数が使用されます。
例)
0.5→0.1
0.05→0.00001001001001001……
例の通り、2進数では表記できないものが存在します。
これを踏まえて下記に実際にコードを載せました。
是非、実行して計算結果を確かめてみてください。
例)
try {
// 初期設定
double doubletest = 0;
// 計算実行
for (int counter = 1; counter <= 10; counter++) {
doubletest += (double) 0.3;
}
// 結果表示
System.out.println("(double型) :" + doubletest);
} catch (Exception e) {
System.out.println("エラー:" + e.toString());
}
実行結果:2.9999999999999996
ものすごく小さな誤差が出てますね。
でも誤差は誤差なので計算結果が正確であるとはいえません。
では正確に計算するためにはどうすればいいのか?
そこでBigDecimalを使用します。
try {
// 初期設定
BigDecimal bigtest1 = new BigDecimal("0.3");
BigDecimal bigtest2 = new BigDecimal("0.0");
// 計算実行
for (int counter = 1; counter <= 10; counter++) {
bigtest2 = bigtest2.add(bigtest1);
}
// 結果表示
System.out.println("(BigDecimal):" + bigtest2);
} catch (Exception e) {
System.out.println("エラー:" + e.toString());
}
実行結果:3.0
しっかりと「3.0」となっています。
このように小数の計算の際にはBigDecimalを使うと
丸め誤差がなく、正確に計算ができます。
正確に計算できるなら、すべての小数計算でBigDecimalを使おうと
思う方もいると思いますが、BigDecimalにも欠点があります。
1.循環小数や無限小数に注意しなくてはならない。
2.計算が遅いというリスクがある。
なんと数値型で計算するより約100倍くらい差がある
計算が遅いというのは結構つらいですね。
シューティングゲームの座標を想像してみるとわかりやすいかもしれませんね
ほんの少し場所がずれても速く移動できるほうがいいのか。
時間をかけてでも正確な場所に移動したほうがいいのか。
私としては速い方がいいと思いますね。
結論から言うとひとつの方法を使い続けるのではなく、
使い分けが重要ってことだと思います。
正確な計算をしたいときに便利なBigDecimal
皆さんも機会があれば使ってみてはいかがでしょうか?
では、また何週間後かにお会いしましょう。