2015年5月27日水曜日

小数点以下の微妙な誤差について

みなさん、SASやExcel等で出した結果が小数点以下の深い桁で微妙に合わない
「なぜ?」という経験はありませんか?


Excelだと、こんな感じの現象。













SASだと、こんな感じの現象。





今回はこの現象について、なるべく簡単にお伝えできたらと思います。

深く知りたい方は、コンピュータの仕組や世界的に準拠されている
技術標準 IEEE(アイ・トリプリ・イー)辺りを調べていただくと
よいかと思います。


では、改めてこの現象が起こる理由についてですが
それはズバリ!!

コンピュータでの計算は2進数で行われているということ
そして『10進数の小数を2進数へ変換 及び 2進数から10進数へ戻す際の
丸め誤差によるズレ』 これが、理由です。


...???


と、言葉で言うとこれだけですが
まったくわかりませんよね...

なので、少しだけ深堀したいと思います。



『有効桁数』

コンピュータ上で表現できる、数値の桁数のことを「有効桁数」とよんでいます。

コンピュータ上で計算する場合、人力でやるには無理があるような桁数でも
計算が可能ではありますが、普段使用する中でそこまで大きい桁数を必要とするわけでもなく
また、たとえコンピュータとはいえ、無限に桁数を増やせるわけではありません。

そこで、有効と思われる桁数を決めて、その範囲内で計算するようになっており
これを「有効桁数」と読んでいます。

「有効桁数」は一般的には「IEEE」が定めている基準を準拠しており
小数点以下の桁数は15桁となっています。
それに伴い「有効桁数」を超えた場合、丸め処理が行われています。



『循環小数』

ある桁から先で同じ数字の列が無限に繰り返される少数のことを「循環小数」とよびます。
例えば、「0.3333333333・・・・」のことです。

この「循環小数」は桁数を決めておかなければ、、際限なく桁数を増やしてしまいます。
その桁数を決めているのが「有効桁数」になります。



『計算は2進数』

コンピュータ上では私たちが普段行う10進数での計算は行われません。
通常は2進数を用いて計算が行われます。

なぜ、2進数で行われているかについては、ここでは省略しますが
整数や小数であっても2進数に変換され、計算後10進数に再変換され
画面上に表示されています。



『誤差発生の仕組み』

コンピュータ上において「計算は2進数」で行われるため、小数であっても10進数から2進数に変換しますが、ほとんどの場合において「循環小数」になってしまい正確に表現できないという
問題が存在します。
そのため「有効桁数」にあわせるため、丸め処理が行われます。
丸め処理が行われた数値を10進数に戻すため、誤差が生まれます。


例えば、10進数で「0.1」を2進数に変換した場合、以下の図のように
「000110011001100110011....」と「循環小数」なります。
ここで、「有効桁数」を超えた部分で丸め処理を行います。











この丸め後の2進数を10進数に変換すると、「0.10000000000000000055511 …」となり
赤色の数字の部分が誤差になるというわけです。



まとめ

ザックリとではありますが、わかりましたでしょうか。
結論を言いますと、『コンピュータ上で計算する限り、計算誤差は必ずある』です。

こう言いますと、どうにもならないようにも思えますが対策することは可能です。
すぐに実践可能な対策に以下のものがあります。

・あらかじめ必要な桁数を決めておき、四捨五入や切り捨てなどを使用する。
    あらかじめ、使用する桁数を決めておけば、誤差が出る深い部分を
    使用しないで済みます。
    ほとんどの場合において小数点以下第2位、多くても第5位くらいではないでしょうか。

    また、比較する際においても、決めておいた桁数のみで比較を行い、
    それ以下の桁は許容範囲内として処理する。
    但し、今回の現象とは無関係の部分での誤差まで許容してしまわないように
    注意が必要です。


いかがでしたでしょうか、深く知っていなくても
「こんな現象が起きてるんだな~」
っていうのだけでも、覚えておいてもらえれば
実際に直面した時にスムーズに対処できるのではないでしょうか。


0 件のコメント:

コメントを投稿

ネイチャーインサイト サイトリニューアル&NIBLOGの引っ越し

ご連絡が遅くなりましたが、 ネイチャーインサイトの際とがリニューアルしました。 https://www.n-insight.co.jp/ それに伴い、NIBLOGも引っ越しすることになりました。 https://www.n-insight.co.jp/niblog/ ...