>>勉強の面倒を毎週見てくれる神サービスがこちら

コンピュータが計算した数字を100%信じてはいけない理由

プログラミング
この記事は約5分で読めます。

コンピュータって色んな計算できて、万能だよね~

と、そう思っている方が多いと思います。

しかし、実はコンピュータにも限界があって、間違いが存在します。

コンピュータがはじき出した数字だからといって100%鵜呑みにしてしまうと、間違った結論を導きかねません。

今回はそんなコンピュータの「限界」について紹介していきます。

コンピュータで√2を計算させてみよう

まず、コンピュータも間違うことがあるということを実感していただきましょう。

下は、Pythonというプログラミング言語を使って、\(\sqrt{2}\)(2の正の平方根)を30桁計算した結果です。

print(f"√2 = {2**0.5:.30f}")

##### 出力 #####
√2 = 1.414213562373095145474621858739

さて、これを見て

よし、\(\sqrt{2}\)が30桁求まったから、この値を使おう!

としてもよいでしょうか?

実は、先ほどコンピュータが計算した\(\sqrt{2}\)の値は小数第15桁までしか合っていません。

Wikipediaによると、正確な\(\sqrt{2}\)の値は

1.414213 562373 095048 801688 724209 ……

です。一方さっきコンピュータで計算した結果は

1.414213 562373 095145 474621 858739

です。これを見てわかるように、実はさっきコンピュータが計算した\(\sqrt{2}\)の値は小数第15位までしか合っていないのです。

私たちがプログラムを書くとき、コンピュータには
「30桁まで出せ!」
と命令すればちゃんと30桁出してくれるのですが、必ずしも30桁を正確に出してくれるとは限らないのです。

3.141592 653589 793238 462643 383279

信頼できる桁数は〇桁くらい

さっきは\(\sqrt{2}\)を計算させてみましたが、今度は0.1+0.1を計算してみましょう。

print(f"0.1 + 0.1 = {0.1+0.1 :.30f}")

##### 出力 #####
0.1 + 0.1 = 0.200000000000000011102230246252

おや……?明らかにおかしいですね。

小数第16位までは問題ないのですが、それより先の数字がズレてしまっています。

カンの良い人はお気づきかもしれませんが、普通のプログラムにおける計算の精度は15~16桁程度と言われています。

なぜ精度が16桁かというのは、次の節で解説します。

3.141592 653589 793238 462643 383279

誤差の原因

16桁分しか使えない

では、なぜ「0.1+0.1」というごく簡単な計算さえも誤差が入ってしまうのでしょうか。

それは、コンピュータが覚えておける桁数に制限があるからです。

「0.1+0.1」を例に、具体的に説明しましょう。

0.1という数字は、コンピュータ上では
1.000000000000000×10-1
のようにして表され(実際には2進法ですが、説明のために10進で書いています)、太字の部分は16桁(くらい)と制限されています(場合によって32桁などの規格もあります)

この表現を使って0.1+0.1を計算すると、
2.000000000000000×10-1
となります。

ここまでは良いのですが、問題なのは
「0.1+0.1の結果を、30桁で出せ」
と命令された場合です。

なぜ問題なのかというと、コンピュータ上には16桁ぶんの情報しかないのに30桁を出せと言われているからです。

そうなるとコンピュータはお手上げなので、16桁より先はヘンな値になってしまうのです。

”丸め”が誤差を生む

コンピュータが覚えておける桁数に限界がある以上、限界を超えたぶんの桁は捨てなければなりません。いわゆる四捨五入のようなこと(厳密には四捨五入ではない)をしなければなりません。

たとえば、(10進で)4桁しか記憶できないコンピュータを考え、次のような計算をさせてみます。

9.999×1.499÷1.499

まず、9.999×1.499を計算します。これを厳密に計算すると 14.988501 になりますが、この結果をコンピュータにそのまま覚えさせておくことはできません。いま、4桁しか記憶できない場合を想定しているため、

14.988501 ≒ 14.99

という数が記憶されます。この四捨五入のような操作を「丸め」と言ったりします。
次に 1.499 で割りましょう。すると…

14.99 ÷ 1.499 = 10 ≒ 10.00

となります。

これはおかしいですね。理論上は 9.999×1.499÷1.499=9.999 となるはずなのですが、4桁精度のコンピュータに計算させると 10 という答えが返ってきてしまいます。

小さな誤差が致命傷になることも

ここまで、コンピュータの精度には限界があるということを解説してきました。

しかし、

誤差なんてちょっとだし、大したことないでしょ~

と思うかもしれません。多くの場合、確かに誤差は無視できます。しかしごくまれに、わずかな誤差が計算を破綻させてしまう場合が考えられます。

例えば

$$\frac{1}{ab-cd}$$

という計算をコンピュータにさせます。ただし、\(ab-cd>0\)となることは数学的に保証されているとします。

しかしコンピュータが計算している以上、\(a,b,c,d\)にいろいろな値を代入して計算していると誤差が生じます。ですが大抵の場合無視できるので、これは想定内です。

ただし……もしかすると、偶然が重なって丸め誤差が生じ\(ab-cd\approx0\)という値になるかもしれません。数学的には\(ab-cd>0\)なのですが、丸めたせいで 0 になっているという場合です(たとえば、10-100 は正の値ですが桁数が大きいので0に丸められます)。

この場合ゼロで割ることはできませんから、エラーが発生します。

このようにわずかな誤差でも、理論に反する結果が得られるというヤバいことになることがおわかりいただけたかと思います。

最後に

近年、人工知能の技術が進歩して計算量がどんどん増えてきていますが、計算量が増えるぶん計算誤差が生じるおそれは高まっていきます。

普段はコンピュータがどのように計算しているかを意識することは少ないと思いますが、コンピュータの限界を知っておくことは非常に重要なのではないでしょうか。

最後までご覧いただきありがとうございました!

この記事は役に立ちましたか?
  • 役に立った 
  • 役に立たなかった 
  • ふつう 

記事への意見・感想はコチラ

タイトルとURLをコピーしました