プロジェクト

全般

プロフィール

操作

JavaでBigDecimalが必要な理由を理解するために、doubleやfloatでは問題が発生するケースを考えながら説明します。


1. double や float の誤差問題

doubleやfloatは**浮動小数点数(IEEE 754)**を使用しており、10進数を正確に表現できないため、計算時に誤差が発生します。

誤差の例

public class Main {
    public static void main(String[] args) {
        double a = 0.1;
        double b = 0.2;
        double c = a + b;

        System.out.println("0.1 + 0.2 = " + c); // 期待: 0.3, 実際: 0.30000000000000004
    }
}

出力

0.1 + 0.2 = 0.30000000000000004

このように、double では 誤差が発生するため、正確な計算が必要な場面(金融計算など)には適さない ことが分かります。


2. BigDecimal を使うと誤差が発生しない

BigDecimal は 任意精度の10進数演算をサポート するため、誤差のない計算が可能です。

BigDecimalを使用した例

import java.math.BigDecimal;

public class Main {
    public static void main(String[] args) {
        BigDecimal a = new BigDecimal("0.1");
        BigDecimal b = new BigDecimal("0.2");
        BigDecimal c = a.add(b);

        System.out.println("0.1 + 0.2 = " + c); // 正確に 0.3 になる
    }
}

出力

0.1 + 0.2 = 0.3

BigDecimal を使用すると、誤差のない計算が可能になります。


3. BigDecimal の用途

BigDecimal は以下のような用途で使用されます。

(1) 金融・会計計算

  • お金の計算(銀行、税金、請求書など)
  • 例えば、0.1円単位で計算が必要な場合、double の誤差では問題になる
  • BigDecimal なら 正確な桁数で管理できる

(2) 高精度の科学計算

  • 天文学、物理シミュレーションなど で高精度が必要な場合
  • double の誤差が大きな影響を及ぼす計算では BigDecimal を使う

(3) 数値フォーマットが重要な場面

  • 税率、為替レート などの値を厳密に管理
  • double では丸め誤差が発生するため、厳密な計算が必要

4. BigDecimal の注意点

(1) BigDecimal の生成には String を使う

BigDecimal x = new BigDecimal("0.1"); // 正確
BigDecimal y = new BigDecimal(0.1);   // doubleの誤差がそのまま適用される(NG)

new BigDecimal(0.1) の場合、既に double の誤差が含まれてしまうため、必ず String を使って生成 するのがベスト。


(2) BigDecimal の演算方法

BigDecimal は + や * などの演算子が使えない ため、メソッドを使う必要があります。

操作 メソッド 例
加算 add(BigDecimal) a.add(b)
減算 subtract(BigDecimal) a.subtract(b)
乗算 multiply(BigDecimal) a.multiply(b)
除算 divide(BigDecimal, RoundingMode) a.divide(b, RoundingMode.HALF_UP)
比較 compareTo(BigDecimal) a.compareTo(b) == 0

(3) BigDecimal の丸め

divide() を使う際、丸めモード(RoundingMode)を指定する必要 があります。

import java.math.BigDecimal;
import java.math.RoundingMode;

public class Main {
    public static void main(String[] args) {
        BigDecimal a = new BigDecimal("10");
        BigDecimal b = new BigDecimal("3");

        BigDecimal result = a.divide(b, 2, RoundingMode.HALF_UP); // 小数点以下2桁で四捨五入
        System.out.println("10 / 3 = " + result);
    }
}

出力

10 / 3 = 3.33

double のように 無限小数になってエラーになることを防ぐ ことができます。


5. まとめ

double BigDecimal
精度 誤差が出る(10進数を正確に表現できない) 任意精度で計算できる
計算 + - * / で直接演算可能 add() subtract() などのメソッドを使用
用途 高速な計算が必要な場面(例: グラフィック処理) 金融計算、会計、正確な数値管理
丸め処理 Math.round() で対応 RoundingMode を使用
比較 == を使うと誤差で問題が出る compareTo() を使えば正確

6. BigDecimal を使うべきケース

✅ 金融計算(お金の計算)
✅ 精度が必要な科学計算
✅ 厳密な値の管理(税率、為替など)

🚀 一方で、double が適しているケースもある

  • 大量の数値演算(例えば機械学習、物理エンジン)
  • パフォーマンス重視のアプリ

BigDecimal は計算精度が高いが、計算速度は double より遅いため、適材適所で使い分けることが重要です!

渡邉 拓英 さんが1年以上前に更新 · 0件の履歴