Java | 小数の丸め誤差

Java Java
スポンサーリンク

では、Javaの 小数の丸め誤差(浮動小数点誤差) を、初心者でも理解できるように 簡単なコードと図イメージ で説明します。


背景:丸め誤差とは?

  • Javaの float / double二進数で小数を表現しています。
  • そのため、10進数の「0.1」や「0.2」は 正確に表せない場合があります。
  • 結果として計算すると、直感的には正しい値でも、微妙にずれた値が出ることがあります。

例:0.1 + 0.2

0.1 + 0.2 → 0.30000000000000004

実験プログラム(丸め誤差確認)

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

        System.out.println("a = " + a); // 0.1
        System.out.println("b = " + b); // 0.2
        System.out.println("a + b = " + c); // 0.30000000000000004

        // float型でも確認
        float f1 = 0.1F;
        float f2 = 0.2F;
        float f3 = f1 + f2;
        System.out.println("float f1 + f2 = " + f3); // 0.3 (丸めあり)
    }
}
Java

実行結果例

a = 0.1
b = 0.2
a + b = 0.30000000000000004
float f1 + f2 = 0.3
  • double では 0.1 + 0.2 が 正確に 0.3 にならないことが分かります。
  • float は精度が低いので、計算結果がざっくり丸められます。

図でイメージ

10進数での直感:   0.1 + 0.2 = 0.3
二進数での内部表現:
0.1  ≈ 0.0001100110011001100110011001100110011001100110011...
0.2  ≈ 0.0011001100110011001100110011001100110011001100110...
-----------------------------------------------
計算結果  ≈ 0.0100110011001100110011001100110011001100110011010...  ← 0.3 ではない!
  • 小数は二進数では無限に続く値になるため、内部で 切り捨て・丸め が発生します。
  • それが「丸め誤差(浮動小数点誤差)」です。

注意点

  • 小数の比較は 直接 == で判定しない double a = 0.1 + 0.2; if (a == 0.3) { // NG! System.out.println("等しい"); } else { System.out.println("等しくない"); // 実際はこちらが出る }
  • 代わりに 誤差範囲(許容誤差)を使う double eps = 1e-10; if (Math.abs(a - 0.3) < eps) { System.out.println("ほぼ等しい"); }

練習アイデア

  1. 0.1 + 0.2floatdouble で比較する
  2. 0.1 * 3 が 0.3 になるか確認する
  3. 許容誤差 eps を使って安全に比較する

Java
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました