浮動小数点、コンピューターが完全な計算をしない理由

テック&ガジェット
この記事は約5分で読めます。

コンピューターは本当に「正確」なのか

コンピューターというと、非常に緻密で、一切のミスをしない存在のような印象があります。

どれだけ複雑な計算であっても正確に処理し、巨大な数字も高速に扱い、何万回、何億回と繰り返し計算しても絶対にずれない。多くの人が、コンピューターにはそうした「完全性」のようなものを感じていると思います。

確かに、コンピューターは人間よりはるかに高速で、はるかに正確です。

しかし、実際にはコンピューターもかなり曖昧な方法で数字を扱っている場面があります。特に小数点以下の数字については、「だいたいこの辺りで近いだろう」という近似値を使って計算していることが非常に多いのです。

有名なのが、

0.1 + 0.2 = 0.30000000000000004

のようになる現象です。初めて見ると、バグなのではないかと思ってしまいます。しかしこれは壊れているわけでも、計算を間違えたわけでもありません。むしろコンピューターは真面目に計算した結果として、この値を返しています。

私も最初は、コンピューターは数字を完璧に扱えるものだと思っていました。しかし調べていくと、実際には「完全な正確さ」を追求しているというより、「十分近い数字を高速に扱う」という方向で設計されていることが見えてきます。これはある意味、人間が現実社会で妥協しながら物事を進めている感覚に少し似ているのかもしれません。

人間の数字とコンピューターの数字は違う

私たち人間は普段、10進数を使っています。

0 1 2 3 4 5 6 7 8 9

という数字を使い、それを組み合わせて数を表現しています。とても自然で、感覚的にも理解しやすい方法です。

しかし、コンピューター内部では基本的に2進数が使われています。つまり、

0 と 1

だけで世界を表現しています。電気が流れているか、流れていないか。ONかOFFか。その単純な状態を大量に並べて、数字や文字、画像や音声までも表現しています。

1/2
1/4
1/8

のような数字は二進数で正確に表現できます。ところが、

1/10

のような数字は綺麗に終わりません。二進数で表そうとすると、

0.00011001100110011…

のように、永遠に数字が続いてしまいます。

もちろん、コンピューターは無限に数字を保存できるわけではありません。

そのため途中で、「この辺りで十分近いだろう」と判断して丸め込みます。つまり、0.1そのものを保存しているわけではなく、「0.1にかなり近い何か」を保存しているわけです。

人間からすると、0.1は非常に単純で綺麗な数字に見えます。しかしそれは、私たちが10進数を使っているからにすぎません。コンピューターから見ると、0.1は実はかなり扱いにくい数字なのです。

1/3が割り切れないのと同じことが起きている

浮動小数点について専門的に説明しようとするとかなり難しくなるのですが、本質だけで言えば、人間も同じようなことを普段からしています。

例えば、

1/3

を小数で表してくださいと言われたらどうでしょうか。

普通は、

0.333333…

と書きますよね。
しかし実際には3が永遠に続いてしまうので、どこかで打ち切るしかありません。

「なるべく近い数字」を使うしかないのです。

つまり、この時点ですでに「本物の1/3」ではなく、「1/3にかなり近い数字」を使っています。

すると、1/3 + 1/3 + 1/3 は本来 =1 になるはずなのに、

0.333333 × 3 をすると、 合計が 0.999999

のようになってしまう場合があります。
限りなく1に近いのですが、完全に1ではありません。

実はコンピューターの浮動小数点も、かなりこれに近いことをしています。人間は十進数で1/3をうまく書けずに困りますが、コンピューターは二進数で0.1をうまく書けずに困っているのです。

つまり、「コンピューターだから間違っている」のではなく、「使っている数字の仕組みそのものに限界がある」という話なのだと思います。

完全な正確さよりも「十分な速さ」を選んでいる

もちろん、理論上はもっと正確に計算する方法もあります。

実際、金融システムなどでは、浮動小数点を避けて整数で金額を管理することがあります。1円を「1」として扱い、小数を使わないことで誤差を防ぐわけです。

しかし、世の中のほとんどのコンピューターは、多少の誤差が出ることを前提にしながら動いています。その理由は単純で、「完全な正確さ」を求めると、処理速度やメモリ消費が大きく悪化してしまうからです。

コンピューターは、本当に正しい数字を無限に追いかけているわけではありません。ある程度近ければ、それを正しいものとして扱い、とにかく高速に処理することを優先しています。

実際、過去には数値計算の誤差が問題になったこともあります。有名なのが1994年の Pentium FDIV バグです。Intel のCPUが一部の割り算で誤った値を返す問題で、科学技術計算などでは深刻な影響を与える可能性がありました。

こうした事例を見ると、コンピューターという存在も決して万能ではなく、内部ではかなり泥臭い工夫や妥協をしながら動いていることが分かります。

以前の私は、コンピューターの計算というものは絶対的で、人間より遥かに完璧なものだと思っていました。しかし実際には、コンピューターもまた「限られた資源の中で、どこまで現実的に処理するか」を考えながら動いています。

完全な正しさよりも、実用性や速度を優先する。その姿勢は、どこか人間社会そのものにも似ているように感じます。

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