エクセルの癖|端数蓄積で計算結果がずれる理由とIEEE 754の話

皆さんこんにちは。

エンタです。

数量集計をエクセルで組んでいて、「全部足したら手計算と1円ズレてる」って経験ありませんか?

法面工事の積算でも、面積×単価×消費税みたいに数式を重ねていくと、最終行で必ず1円・1m²の差が出る現象です。

これ、エクセルのバグじゃなくてIEEE 754という浮動小数点の世界共通仕様が原因ですw

昔メチャムカついて調べたことがあったので、皆様にもw

と言ってもイマドキあまりExcel使って計算しませんか?

私は未だにExcel派!

コレが一番何でも出来ちゃうので・・・w


閑話休題

今回は、エクセル(と多くのソフト)で発生する端数蓄積誤差の正体を、IEEE 754倍精度浮動小数点の仕様から、

ROUND関数による正しい回避方法まで数量計算でイラつきながらやった経験を解説します。

Microsoft公式ドキュメントに明確に記載のある話なので、根拠は100%確実です。

端数蓄積で1円ズレる典型

エクセルの癖の正体|IEEE 754仕様

結論だけを言うと、エクセルの計算誤差はバグではなくIEEE 754という浮動小数点演算の規格に厳密に従った結果です。

は?って感じですよね。

 

MicrosoftはExcelの計算精度について次のように明記しています:Microsoft ExcelはIEEE 754仕様に基づいて設計されており、浮動小数点数の格納方法と計算方法を決定している。Excelは1.79769313486232E308から2.2250738585072E-308までの数値を格納できるが、有効桁数は15桁以内に限られる。

Microsoft Learn 公式ドキュメント「浮動小数点演算を使用すると、Excel で不正確な結果が得られます」

つまり、エクセルは内部で全ての数値を2進数で扱っているため、10進数で書いた数字を2進数に変換する際に丸め誤差が生まれる。

これが計算を重ねると累積していく、というのが現象の本質です。

なぜ10進数→2進数で誤差が出るのか

「0.1」のような10進数で有限な数が、2進数では無限に循環する小数になることが原因。

10進数 2進数表現 備考
0.5 0.1 ぴったり表現できる
0.25 0.01 ぴったり表現できる
0.1 0.0001100110011…(循環) 無限循環、丸め誤差発生
0.2 0.0011001100110…(循環) 同上
0.3 0.0100110011001…(循環) 同上

IEEE 754倍精度(64bit)では、この無限循環をある桁で打ち切って格納するので、わずかな誤差(約 ±2.8 × 10⁻¹⁷ 程度)が生まれます(Microsoft Learn)。

10進数0.1を2進数変換すると無限循環する仕組み

具体例|エクセルで起こる典型的なズレ

前提知識|TRUE と FALSE の意味

具体例に入る前に、エクセルの TRUE / FALSE をおさらいします。

今更ながら、これは皆さん基本中の基本なので絶対覚えておくとイイですよ!

エクセルで 「=」や「>」や「<」 を使うと、その結果が TRUE(真・等しい/成り立つ)FALSE(偽・等しくない/成り立たない) で返ってきます。

数式 意味 結果
=1=1 1と1は等しい? TRUE
=1=2 1と2は等しい? FALSE
=5>3 5は3より大きい? TRUE

つまり =A1=0.3 で FALSE が返る」=「A1の中身は0.3と等しくない」 という意味になります。これを念頭に下の例を見てください。

※数式は表記の都合で全角イコール(=)で記載しています。実際にエクセルへ入力する際は半角の「=」に直してください。

例1|0.1 + 0.2 ≠ 0.3 のミステリー

エクセルのセルに以下を入力してみてください

セル 数式 表示結果 内部での値
A1 =0.1+0.2 0.3 0.30000000000000004…
A2 =A1=0.3 FALSE (厳密には等しくない)

表示は正しい「0.3」なのに、=A1=0.3 で比較すると FALSE になる。これがIEEE 754の癖ですwww

ムカつきますよねw

例2|100個足すと整数からズレる

=SUM(A1:A100) のように複数セルを合算すると、各セルの微小誤差が100個分積み上がる

  • 0.1 × 100 を1個1個足し算 → 9.99999999999998… のような結果
  • 期待値の 10 にぴったり一致しないことがある

土木の数量集計で 「面積×単価」の100行集計 をすると、最終行で ±数円〜数十円のズレ が起こるのはこのため。

エクセルの100セルSUM計算で端数が累積して整数からズレる例|数量集計の典型エラー]

例3|法面面積計算の端数蓄積(法面現場あるある)

具体的に法面工事の面積計算で起こりやすいパターン:

  • 法枠工:Excelで平方根つかって面積計算しそれを足していく
  • 最終 SUM 行で、手計算と 0.1〜0.5 m2のズレ

原因が分からず半日潰れるパターンです。

昔コレでホントに何度も何度も計算して記憶あります!w

回避策|ROUND関数で都度丸める

表示形式の「小数桁数を減らす」だけでは不十分

エクセルの「セルの書式設定」で小数桁数を減らす方法は、

表示上だけ丸めるだけで、内部値は依然として誤差を持ったまま

次の計算に渡すと誤差が残ったままなので、根本解決になりません。

真の解決策は、関数で値そのものを丸めること。

ROUND関数の使い分け

関数 動作 用途
=ROUND(値, 桁数) 四捨五入 一般用途・金額計算
=ROUNDDOWN(値, 桁数) 切り捨て 安全側に倒す積算
=ROUNDUP(値, 桁数) 切り上げ 資材発注数量(不足回避)
=INT(値) 整数化(負数は床関数) 整数値で打ち止めたい場合
=FLOOR(値, 単位) 指定単位で切り捨て 10円単位・100円単位の丸め
=CEILING(値, 単位) 指定単位で切り上げ 同上、不足回避用

ROUND関数で都度丸めて端数を消す正しいやり方|金額計算の手順

積算や試算では必ずこうやって!

工事の積算・試算で私がやっているのは次の流れ:

  • 金額計算は常に =ROUND(数量*単価*1.10, 0) で円単位に都度丸める
  • 数量計算(面積・体積)は =ROUND(値, 2) で小数2桁まで 丸めて固定する
  • 集計の最終行で再計算しない(途中で丸めた値の単純合計)

これで、手計算と1円もズレない計算書が作れます。

「Excel計算精度オプション」も併用できる

エクセルには 「表示桁数で計算する」というオプションもあります(ファイル → オプション → 詳細設定 → このブックを計算するとき)。

これをONにすると、セルの表示形式に従って内部値も丸めて計算してくれます。ただし、

  • ブック全体に適用される(部分的に効かせられない)
  • 既存の計算結果が一気に変わる可能性がある
  • チームで共有する積算書では使わない方が無難

ぶっちゃけ、現実的にはこのオプションは使わずに、ROUND関数で個別に制御する方が安全という方がオススメ。

エクセル以外でも同じ|IEEE 754準拠の限界

IEEE 754の浮動小数点誤差は、エクセル特有の問題ではなく、Google Spreadsheet・Numbers・OpenOfficeなど全ての主要表計算ソフトで発生します。

さらに、C言語・Python・JavaScript・SQLなど、ほとんどのプログラミング言語でも同じ仕様。

IEEE 754はExcel以外の全表計算・プログラミング言語で共通仕様|誤差は世界共通

つまり、「エクセルだから不正確」ではなく、世界共通の仕様。それを土木屋として理解して、ROUND関数を使うのが正解です。

押さえる5つのチェックポイント

面積計算等・数量計算でエクセルを使う時は、次の5点を押さえてください。

  • 金額計算は常に =ROUND(…,0) で円単位に丸める
  • 数量計算は =ROUND(…,2) で小数2桁固定
  • 表示形式での丸めは内部値を変えないことを意識
  • =A1=0.3 のような直接比較を避ける(FALSE 判定の罠)
  • チームで使う積算書では「精度オプション」を使わない

迷ったらまず「ROUND関数を1段挟むかどうか」を考えてください。

1個ROUNDを挟むだけで、IEEE 754起因のズレは99%消えます。

エクセルが「癖」を持っているのではなく、世界の浮動小数点演算の癖を私たちが理解して使いこなす。

 

それではまた。

打設における配置誤差の必要性を問われるが、答えはいつも1つ!

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください