こんにちは!しーま(@s59shima)です。
いつもブログをご覧いただきありがとうございます。
今回は、こんな悩みや疑問を持った人に向けて記事を書きました。

小数点を扱う計算で誤差が出てしまうのは何でだろ!?これだと正しい計算ができない・・・
小数点を扱う計算で誤差が出ないようにしたい方におすすめの記事です。
小数点を扱う計算方法は2つある
Javaで小数点を扱う計算をする場合は「double」を使用するか「BigDecimal」を使用するかのどちらかになります。doubleとBigDecimalの両方で四則演算をしてみます。
doubleを使う場合
public class Sample {
public static void main(String[] args) {
double a = 1.0;
double b = 3.0;
System.out.println( a + b );
System.out.println( a - b );
System.out.println( a * b );
System.out.println( a / b );
}
}
実行結果は以下の通り
4.0
-2.0
3.0
0.3333333333333333
BigDecimalを使う場合
import java.math.BigDecimal;
public class Sample {
public static void main(String[] args) {
BigDecimal c = new BigDecimal("1.0");
BigDecimal d = new BigDecimal("3.0");
System.out.println( c.add(d) );
System.out.println( c.subtract(d) );
System.out.println( c.multiply(d) );
System.out.println( c.divide(d, 16, BigDecimal.ROUND_HALF_UP));
}
}
実行結果は以下の通り
4.0
-2.0
3.00
0.3333333333333333
四則演算の書き方はdoubleとBigDecimalで違いはあるものの、問題なく計算が出来ることを確認しましたね。
doubleだと、誤差が発生する場合がある
なぜ小数点を扱う計算にはdoubleではなく、BigDecimalが有効なのか実験してみましょう。
初期値が「0」で、数値「0.1」を10回加算した場合、結果はどうなると思いますか!?

答えは「1」になりますよね。
doubleを使用した計算結果を見てみましょう
public class Sample {
public static void main(String[] args) {
double total = 0;
for ( int i=0; i<10; i++ ) {
total += 0.1;
}
System.out.println( total );
}
}
実行結果は以下の通り
0.9999999999999999
「1」ではなく、「0.9~」という結果になってしまい、わずかな誤差が発生してしまいました。
これは、doubleを使った小数点を扱う計算では、10進数から2進数に変換され処理されるからです。
小数点を含む計算は、BigDecimalが有効
では、BigDecimalを使って同じ計算をしてみましょう
import java.math.BigDecimal;
public class Sample {
public static void main(String[] args) {
BigDecimal total = new BigDecimal("0");
BigDecimal num = new BigDecimal("0.1");
for ( int i=0; i<100; i++ ) {
total = total.add(num);
}
System.out.println( total );
}
}
実行結果は以下の通り
10.0
期待通りの結果を得る事ができましたね

BigDecimalはdoubleと違って、2進数に変換せず処理を行うため、誤差を出さずに計算することができます。
それでは、具体的にBigDecimalを使用して四則演算をするための解説を行います。
BigDecimalクラスの基本的な使い方
BigDecimalを使用するために初期化時に気をつける点や四則演算用のメソッドを使用する点がありますので、そちらを解説します。
クラス図

BigDecimalクラスは「Number」クラスを継承しているため、doubleに変換するメソッド(doubleValue)を使用できたり、「Comparable」インターフェースを実装しているため、比較するメソッド(compareTo)が使用できます。
初期化
初期化するには、文字列型の値とした方が無難です。文字列以外でも初期化出来ますが、誤差が発生する場合があります。
// 初期化を文字列で宣言 ※推奨
BigDecimal total = new BigDecimal("0");
BigDecimal sum = new BigDecimal("0.1");
// 初期化を数値で宣言 ※誤差が発生する可能性アリ
BigDecimal total = new BigDecimal(0);
BigDecimal sum = new BigDecimal(0.1);
6種類の演算メソッド
演算処理 | メソッド名 | 精度指定 | スケール指定 | 丸め指定 |
---|---|---|---|---|
加算 | add | ● | ||
減算 | subtract | ● | ||
乗算 | multiply | ● | ||
除算 | divide | ● | ● | ● |
余り | remainder | ● | ||
乗 | pow | ● |
まとめ
今回は、小数点を扱う計算にはBigDecimalが有効という解説を行いました。
本記事をまとめると以下の通りです。
- 誤差を出さない小数点を扱う計算はBigDecimalが有効
- BigDecimalの初期化は、引数を文字列とする。
- BigDecimalの演算メソッドは6種類が用意されている。
MID WORKS
は業界トップクラスの低マージンで多くのエンジニアから選ばれています!!
IT系フリーランス専門エージェントサービス第1位の MID WORKS の無料会員登録はこちら