では、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("ほぼ等しい"); }
練習アイデア
0.1 + 0.2をfloatとdoubleで比較する0.1 * 3が 0.3 になるか確認する- 許容誤差
epsを使って安全に比較する


