【IT】Excel初心者が小数のif判定で陥りやすいコンピュータの計算誤差という罠

コンピュータの計算誤差

Excelを使った例題

ここに全国的にチェーン展開する飲食会社があるとする。

A店、B店、C店

同社では利用客に5点満点のレビューをお願いしており、年度末に集計している。

昨年・今年のレビュー結果は以下の通り。

レビュー点数表

さて、社長から「前年より0.1以上高かった支店には金一封を出す」とお達しがあった。

前年よりレビュー評価が0.1以上高かった支店には金一封

そこで経理担当者はまずExcelに昨年、今年の点数を入力。

昨年と今年の点数

次に数式を使って、0.1以上プラスの支店を抽出した。

差が0.1以上なら〇を表示

結果こうなった。

期待通りの結果

しかしこの方法には落とし穴がある。

それは小数の「計算誤差」というものを考慮していない点だ。

もしお手元にExcelがあるなら試してみて欲しい。次のようにC店の数値を書き換えると〇は消える。

〇にならない

「3.9 – 3.8」と「3.8 – 3.7」の結果はどちらも「0.1」なのに、片方には〇が付いて、もう片方には〇が付かない罠。

わかりやすくする為に、直接数字を使って計算結果を出してみた。

計算結果はどちらも0.1

表示上はどちらも「0.1」なのだが、この2つは微妙に違う。

小数点の桁数を増やせば明らかになる。

小数点以下の表示桁数を増やす
0.1に限りなく近い数

もちろんこれはコンピュータ側の問題(というか2進数の限界)

人間が10進数で簡単にできる小数計算が、2進数で考えるコンピューターだと正確に表現できないことがあるのだ。

10進数でも「10 / 3 = 3.33333…」といった無限小数はあるが、2進数「3.8 – 3.7 = 0.09999…」もそれに近い。

機械のミスは人の責任になる

上記のように支店が3つならすぐ気づくが、100支店以上あると暗算を省略し、金一封が漏れる支店が出てくる。

そうなると誰が責任を取らされるか? 今回だとExcelを作成した経理担当者だろう。

レアケースなのでこの罠にはまる確率は低いが、仕事でExcelを使う人は一応知識として知っておこう。

正しい数式にする

計算誤差は、2進数で表現できない計算結果が、ほぼそれに近い数値で出ることが問題だ。

なので本来の桁数で四捨五入して、望みの数値に整えてしまえば良い。

ROUND関数

今回の場合、小数点1桁同士の引き算なので、小数第2位以下が発生することはない。

「ほぼ0.1の0.09999999……」という結果は「0.1」で受け取るのが妥当だろう。

小数点1桁でまるめ

という訳でROUND関数を使って、最初のif文を修正しよう。

丸めた計算結果と「>=0.1」の判定ならきちんと動作するはずだ。

数式にもROUND関数を使う
正しい結果

はっきり言って計算誤差なんてイレギュラーの範疇なので、常に意識して防止するのは困難だ。

しかし、知識があればもし遭遇しても「あれ?これってもしかして……」と気付くはずだ。

備えあれば患いなし。ぼんやりでもいいから憶えておこう。