【C#】0.1を掛けると誤差が出る理由
— バグではなくコンピュータの仕様です —
プログラミングを学び始めると、次のような現象に出会うことがあります。
Console.WriteLine(0.1 + 0.2);
結果:
0.30000000000000004
「計算間違ってない?」
と思いますよね。
でもこれは バグではありません。
コンピュータの仕組みによる必然的な結果です。
この記事では初学者向けに分かりやすく説明します。
■ まず現象を確認してみる
double x = 1.0;
double y = x * 0.1;
Console.WriteLine(y);
出力例:
0.10000000000000001
さらに:
Console.WriteLine(0.1 + 0.2 == 0.3);
False
直感と違う結果になります。
■ 原因(重要)
コンピュータは10進数で計算していない
私たちは普段
10進数
を使っていますが、コンピュータは
2進数(0と1)
で数値を保存します。
■ 0.1は2進数で正確に表現できない
10進数の
0.1
を2進数に変換すると
0.0001100110011001100110011...
無限に続きます(循環小数)。
つまり
- メモリに収まりきらない
- 途中で切り捨てる
- 近似値になる
- 計算すると誤差が出る
これは すべての言語共通の仕様 です
(C#, Java, Python, C++ など)
■ 浮動小数点という仕組み
double や float は
浮動小数点数(IEEE754)
という形式で保存されています。
ざっくり言うと:
- 有効桁数が有限
- 丸めが発生
- 完全一致しない
これが誤差の正体です。
■ 実務での対処方法
✔ お金・正確さ重要 → decimal を使う
decimal a = 0.1m;
decimal b = 0.2m;
Console.WriteLine(a + b);
結果
0.3
理由:
- decimal は10進ベース保存
- 小数を正確に扱える
金融・会計では必須です
✔ double同士を直接比較しない
NG:
if (a == b)
OK:
if (Math.Abs(a - b) < 0.0000001)
誤差の範囲内なら一致とみなす
これはゲーム・物理・Unityでも重要です
✔ 表示だけ丸める
Console.WriteLine(value.ToString("F2"));
参考)

内部誤差は残るが見た目を整える
■ まとめ
重要ポイントは3つだけ覚えましょう
1️⃣ コンピュータは2進数で計算する
2️⃣ 0.1は2進数で正確に保存できない
3️⃣ 誤差はバグではなく仕様
そして実務では
- 正確さ重視 → decimal
- 計算速度重視 → double
- 比較は誤差込み
これを使い分けます
■ 一歩進んだ学習へ
この話は次の分野に繋がります
- 基本情報技術者試験(頻出)
- 数値計算
- ゲーム物理
- シミュレーション
- AI/機械学習
つまり
プロになるほど重要になる基礎知識 です。
■ 最後に
この現象に気付いた人はとても良い観察をしています。
プログラミングは「動いた」で終わりではなく
なぜそうなるのか
を考えた瞬間から理解が深まります。
この違和感は成長の入口です。
ぜひ実際にコードを動かして体験してみてください。





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