二進数の計算で「10進数の 0.1」を扱うと丸め誤差が出る理由
(情報処理試験・プログラミング初学者~中級者を想定しています)
プログラミングを学び始めた人が、ほぼ必ず一度は出会う疑問があります。
「0.1 + 0.2 が 0.3 にならないのはなぜ?」
これは言語のバグでも、計算ミスでもありません。
原因は、二進数では 10進数の 0.1 を正確に表現できないことにあります。
本記事では、
- なぜ 0.1 が正確に表せないのか
- 二進数での具体的な変換過程
- 丸め誤差が発生する仕組み
- 実務や試験での正しい理解ポイント
を順序立てて解説します。
結論から言うと
10進数の 0.1 は、二進数では無限小数になるため、必ず誤差が生じます。
これは仕様上の問題であり、
どの言語(C / C# / Java / Python / JavaScript)でも同じです。
10進数の 0.1 を二進数に変換してみる
小数の基数変換の基本
小数を二進数に変換するときは、
「2 を掛けて整数部分を取り出す」操作を繰り返します。
0.1 × 2 を繰り返す
| 回数 | 計算 | 整数部 |
|---|---|---|
| 1 | 0.1 × 2 = 0.2 | 0 |
| 2 | 0.2 × 2 = 0.4 | 0 |
| 3 | 0.4 × 2 = 0.8 | 0 |
| 4 | 0.8 × 2 = 1.6 | 1 |
| 5 | 0.6 × 2 = 1.2 | 1 |
| 6 | 0.2 × 2 = 0.4 | 0 |
| 7 | 0.4 × 2 = 0.8 | 0 |
| 8 | 0.8 × 2 = 1.6 | 1 |
| … | … | … |
ここで注目してください。
0.2 → 0.4 → 0.8 → 1.6 → 0.6 → 0.2
という循環が発生しています。
二進数表現(無限小数)
整数部を並べると、
0.000110011001100110011...
つまり、
0.1(10進) = 0.0001100110011…(2進)
終わりません。
なぜ無限小数になるのか?
10進では「割り切れる」が、2進では割り切れない
- 10進数の 0.1 = 1 ÷ 10
- 10 = 2 × 5
👉 5 という因数が含まれるため、2進では割り切れない
これは数学的に避けられません。
| 分数 | 10進 | 2進 |
|---|---|---|
| 1/2 | 0.5 | 0.1 |
| 1/4 | 0.25 | 0.01 |
| 1/8 | 0.125 | 0.001 |
| 1/10 | 0.1 | 無限小数 |
コンピュータはどう処理しているか
浮動小数点数(IEEE 754)
多くの言語では IEEE 754 という規格で数値を扱います。
- 小数は 有限ビット数 しか持てない
- 無限小数は 途中で切り捨て or 丸め るしかない
結果として、
0.1 ≒ 0.10000000000000000555...
のような 近似値 が内部的に保存されます。
実際のコード例
C# の例
double a = 0.1;
double b = 0.2;
Console.WriteLine(a + b);
出力結果:
0.30000000000000004
これは誤差が「見えている」だけです。
よくある誤解
「計算精度が低いから?」
❌ 違います
👉 どれだけ精度を上げても、無限小数は完全には表せません
「0.1 が特別おかしい?」
❌ 違います
👉 10進で有限でも、2進では無限になる数は多数あります
実務・試験での正しい扱い方
1. 浮動小数点数の比較は直接しない
if (a == 0.3) // NG
代わりに:
if (Math.Abs(a - 0.3) < 1e-9) // OK
2. 金額計算は decimal を使う(C#)
decimal x = 0.1m;
decimal y = 0.2m;
Console.WriteLine(x + y); // 0.3
※ decimal は 10進数ベース で設計されています。
3. 情報処理試験でのポイント
- 0.1 は二進数で正確に表せない
- 浮動小数点は近似値
- 丸め誤差は仕様
この3点を理解していれば、
計算問題・概念問題ともに対応できます。
まとめ
- 10進数の 0.1 は、二進数では無限小数になる
- コンピュータは有限ビットで近似するため誤差が出る
- これはバグではなく「設計上の必然」
- 試験・実務では「誤差が出る前提」で扱うことが重要





ディスカッション
コメント一覧
まだ、コメントがありません