本文へ移動
科学と技術の「いま」を、深く、やさしく読み解くサイエンスマガジン
サイエンス・イニシアティブ
サイエンス

丸め誤差とは何かと浮動小数点で誤差が生じる理由と対策を徹底解説

文:相馬 悠人 約9分で読めます

プログラムで 0.1 + 0.2 を計算したはずなのに、結果が 0.30000000000000004 になって驚いた経験はないでしょうか。

これはバグではありません。

コンピュータが数値を扱う仕組みそのものに起因する、避けて通れない現象です。個人的にも数値計算の入門者だったころ、この「たった一桁のズレ」の意味がわからず、原因を突き止めるのに数日かかった記憶があります。

この記事では、丸め誤差とは何かという基本から、浮動小数点でなぜ誤差が生まれるのか、そして実務で安全に付き合うための具体的な対策までを、順を追って整理していきます。

この記事で学べること

  • 丸め誤差は「有限桁で実数を表す」限り必ず生じる原理的な誤差である。
  • 0.1が2進数で無限循環するため、0.1+0.2が0.3にならない。
  • 誤差は蓄積し、桁落ち・情報落ちで一気に精度が悪化することがある。
  • 金額計算では浮動小数点を避け、整数や10進型を使うのが鉄則である。
  • 等号比較をやめ、許容誤差での比較に切り替えるだけで多くの不具合が防げる。

丸め誤差とは何か

丸め誤差とは、実数を有限の桁数で表現するときに、表せない部分を切り捨て・四捨五入・切り上げなどで「丸める」ことによって入り込む誤差のことです。

言い換えれば、本来無限に続く数字を、限られた入れ物に無理やり収めた結果生じるズレです。

たとえば 1 ÷ 3 を計算すると 0.3333... と無限に続きますが、紙の上でも実際には 0.3333 あたりで書くのをやめます。この「やめた瞬間」に生じるのが丸め誤差です。コンピュータの内部でも、まったく同じことが起きています。

数学の世界では実数は無限の精度を持ちますが、メモリという物理的に有限な入れ物を使う以上、どこかで妥協せざるを得ない。これが丸め誤差の本質です。

浮動小数点で誤差が生じる理由

丸め誤差とは何か - 丸め誤差とは 浮動小数点で誤差が生じる理由と対策
丸め誤差とは何か – 丸め誤差とは 浮動小数点で誤差が生じる理由と対策

ここが最もつまずきやすい部分です。丁寧に見ていきましょう。

コンピュータは2進数で数を表す

私たちが普段使う10進数では、0.1 や 0.25 はきれいに書けます。

しかしコンピュータの内部は、すべて 0 と 1 の2進数で動いています。ここで重要なのは、10進数では有限桁で書ける数でも、2進数では無限に循環してしまう場合がある。という点です。

具体的に 0.1 を2進数に変換すると、0.0001100110011... と「0011」が延々と繰り返される無限循環小数になります。10進数の 1/3 が割り切れないのとまったく同じ構造です。

IEEE 754という共通ルール

現代のほとんどのコンピュータは、浮動小数点数を「IEEE 754」という国際規格に従って表現します。

浮動小数点数とは、符号 × 仮数 × 2の指数乗 という形で、大きな数から小さな数まで柔軟に表す方式です。よく使われる倍精度(double)では、数値を64ビットで表現します。

この仮数部に割り当てられるビット数は有限(倍精度で52ビット)なので、先ほどの無限に続く 0.1 はどこかで打ち切られます。その打ち切りの瞬間に、丸め誤差が確定するわけです。

だから0.1+0.2が0.3にならない

ここまでを踏まえると、有名なあの現象が説明できます。

0.10.2 も、内部では正確な値ではなく「ごくわずかにズレた近似値」として格納されています。そのズレを含んだ2つを足すため、結果もぴったり 0.3 にはならず、0.30000000000000004 という微小な誤差を含んだ数になるのです。

💡 実体験から学んだこと
在庫管理のツールを作っていたとき、合計金額の判定に if (total == 1000.0) と書いたところ、条件に一致しない不具合が発生しました。原因はまさに丸め誤差。等号での比較をやめただけで、あっさり解決しました。

誤差の性質と累積のこわさ

浮動小数点で誤差が生じる理由 - 丸め誤差とは 浮動小数点で誤差が生じる理由と対策
浮動小数点で誤差が生じる理由 – 丸め誤差とは 浮動小数点で誤差が生じる理由と対策

1回の丸め誤差はごく小さな値です。倍精度なら誤差は10進で15〜16桁目あたりに現れる程度で、日常的な計算ではほとんど問題になりません。

問題は、計算を繰り返したときです。

小さな誤差でも、何万回、何百万回と加算や乗算を重ねると、少しずつ積み重なって無視できない大きさに育つことがあります。これを誤差の累積と呼びます。とくに数値シミュレーションや反復計算では、この蓄積が結果の信頼性を左右します。

桁落ちと情報落ち

累積以上に厄介なのが、一気に精度が失われる二つの現象です。

桁落ちは、ほぼ等しい2つの数を引き算したときに起こります。有効な桁が打ち消し合って消え、残った下位の桁が相対的に大きな誤差を持ってしまう現象です。

情報落ちは、絶対値が大きく異なる数を足し引きしたときに起こります。小さいほうの数が、大きいほうの数の下位桁に埋もれて「なかったこと」にされてしまうのです。

⚠️
計算の順序が結果を変える
情報落ちがあるため、多数の数を合計するときは「絶対値の小さいものから順に足す」だけで精度が改善する場合があります。数学的には順序を変えても同じはずの計算が、浮動小数点では違う答えになる点に注意してください。

実務での安全な対策

誤差の性質と累積のこわさ - 丸め誤差とは 浮動小数点で誤差が生じる理由と対策
誤差の性質と累積のこわさ – 丸め誤差とは 浮動小数点で誤差が生じる理由と対策

誤差の存在は消せません。しかし、正しい付き合い方を知っていれば、実務でトラブルを起こすことはほとんどなくなります。

1

等号比較をやめる

浮動小数点同士を == で比べず、差の絶対値が十分小さいかで判定します。

2

適切な型を選ぶ

金額は整数(最小単位)や10進型を使い、浮動小数点を避けます。

3

計算方法を工夫する

桁落ちを避ける式変形や、足す順序の工夫で誤差を抑えます。

等号ではなく許容誤差で比べる

最も効果が大きく、すぐ実践できる対策です。

a == b と書く代わりに、abs(a - b) < 1e-9 のように「許容できる誤差の範囲に収まっているか」で判定します。この許容値をイプシロン(ε)と呼び、扱う数値の大きさに合わせて調整します。

お金の計算には浮動小数点を使わない

会計や決済のように1円のズレも許されない場面では、浮動小数点は使わないのが鉄則です。

金額を「円」ではなく「銭」や最小単位の整数として扱う、あるいはPythonの Decimal、Javaの BigDecimal といった10進数を正確に扱う型を使います。個人的には、金額を扱うコードでは最初から整数か10進型を選ぶルールを決めておくと、後々のトラブルが劇的に減ると感じています。

計算の設計そのものを見直す

桁落ちが起きやすい引き算は、数式を変形して回避できる場合があります。

また、問題を扱いやすい単位に分けて考える発想も有効です。大きな計算を小さな部分に分割して精度を管理する考え方は、困難は分割せよというデカルトの格言にも通じるものがあります。

誤差対策チェックリスト




浮動小数点を使うメリットとデメリット

誤差があると聞くと欠陥のように感じますが、浮動小数点はきわめて実用的な仕組みです。

メリット

  • 極小から極大まで広い範囲を扱える
  • ハードウェアで高速に計算できる
  • 科学計算やグラフィックスに最適

デメリット

  • 一部の10進小数を正確に表せない
  • 誤差が累積する可能性がある
  • 厳密な金額計算には不向き

大切なのは、特性を理解したうえで用途に合わせて使い分けることです。速度と範囲が欲しい科学計算では浮動小数点、正確さが命の会計処理では整数や10進型、という具合です。

よくある質問

丸め誤差と桁落ちは同じものですか

厳密には異なります。丸め誤差は数を有限桁に収めるときに生じる基本的な誤差全般を指し、桁落ちはその一種として、近い値同士の引き算で有効桁が失われる特定の現象を指します。桁落ちは丸め誤差が顕在化する典型的な場面と捉えるとわかりやすいです。

float と double のどちらを使えばよいですか

特別な理由がなければ、精度に余裕のある double(倍精度)をおすすめします。float(単精度)はメモリや速度が重要な場面で使われますが、誤差が大きくなりやすいためです。ただしどちらも根本的に丸め誤差は避けられません。

誤差をゼロにする方法はありますか

浮動小数点を使う限りゼロにはできません。ただし、整数演算や有理数を分数のまま扱うライブラリ、任意精度の10進型を使えば、対象とする計算の範囲内では誤差のない結果が得られます。用途に応じた道具の選択が答えになります。

許容誤差の値はどう決めればよいですか

扱う数値の大きさによって変わるため一律には決まりません。1前後の値なら 1e-9 程度がよく使われますが、非常に大きな数や小さな数を扱う場合は、値の大きさに比例した相対誤差で判定するほうが安全です。

プログラミング以外でも丸め誤差は問題になりますか

はい。表計算ソフトの集計や、統計処理、機械学習の学習過程など、数値計算を伴うあらゆる場面で関係します。とくに大量の数を扱うデータ分析では、累積誤差を意識するかどうかで結果の信頼性が変わってきます。

まとめ

丸め誤差は、有限のメモリで無限の実数を扱おうとする以上、原理的に避けられない現象です。

0.1 + 0.2 がぴったり 0.3 にならないのは、コンピュータの欠陥ではなく、2進数と有限桁という仕組みから生まれる自然な結果でした。

まず今日から試せるのは、浮動小数点の等号比較を許容誤差での比較に置き換えることです。そして金額のような厳密さが求められる計算では、整数型や10進型を選ぶ習慣をつけてみてください。

誤差の存在を正しく理解することは、信頼できるプログラムを書くための確かな第一歩になるはずです。

相馬 悠人

相馬 悠人サイエンス・イニシアティブ編集部

サイエンス・イニシアティブ編集長。大学院で物理学を専攻後、出版社で科学雑誌の編集に約10年携わる。専門は宇宙・物理領域。…

この執筆者の記事一覧 →
上部へスクロール