ちゃんなるぶろぐ

新卒エンジニアが、日々の学びをアウトプット〜読書とプログラミング〜

コンピュータが計算ミスをする?!〜書籍『プログラムはなぜ動くのか』より〜

読み終えるまで約5分

どうも、ちゃんなるです。 今回は、あの正確無比なコンピュータが計算ミスをする…という事実を紹介します✌️

「んなアホなw」 「計算できないコンピュータ、冷やせない冷蔵庫みたいなもんやん笑」

色々と思うところはあるでしょう。しかし、事実としてある条件下では必ず計算ミスをしてしまうのが現代のコンピュータなのですよ…涙

*内容はこの本『プログラムはなぜ動くのか』を参考にしています。

①論より証拠、プログラム実行結果を見よう

実行するプログラム(今回はJavaScriptを使用しているが、別言語でも再現可能*1

let result = 0;            // 結果を格納する変数
for(let i=0; i<100; i++){  // 100回のループ処理を実行
    result += 0.1;         // 0.1をresultに加算し続ける
}
console.log(result);       // 結果: 9.99999999999998

次の画像を見てくださいな🙋‍♀️

f:id:Chan-Naru:20220308050412p:plain
paiza.io上のプログラム実行結果の例
*実行環境としてオンラインJavaScriptエディタのpaiza.ioを使用*2

「嘘やん、そんなわけないやろ笑」

ぜひ、ブラウザ上のコンソール、またはpaiza.ioのサイトなどで実行してみてください!

②なぜ10にならないの?

端的に言うと、コンピュータ内部では2進数が使われているから、です。

「ふぁ?」

私たちは10進数(0から9の10種の数字)を用いますが、コンピュータは計算や画面の表示などの全ての処理を2進数(0と1の2種類の数字)でのみ行います(詳細は省略)。

画面上で見る10進数の演算も、内部では2進数の値で行われており、画面に表示する際は10進数に変換してから表示しています(少々語弊のある表現かもしれませんがご了承くださいmm)。

そして、10進数の少数点数の中には2進数で表現できないものがあります。0.1はそのうちの一つであり、今回はこの0.1を用いて計算をしたため、誤差が乗って計算ミスにつながったのです。

③10進数の少数点数には2進数で表せないものがある!

例えば、10進数の5を2進数で表すと0.101となり、10進数の0.625を2進数で表すと0.101となります(計算過程は省略)。

10進数の0.1を2進数で表現すると…

0.000110011001100...

循環小数になってしまう、近似値で表すしかない涙

よって実際の値とはずれてしまう、というのが計算ミスの理由なのでした。

まとめ

コンピュータにもできない計算がある!少数を扱う計算には要注意!

計算ミスをする背景は、2進数では表現できない10進数の少数点数があるということ。

計算ミスを避けるには、2進数で表現できる値で計算を行うこと。正確な値が求められる場合は、少数の計算を避けた方がいいでしょう。今回の場合は、『0.1を100回加算』ではなく、下記のように『1を100回加算し最後に10で割る』少数を使わないように工夫するといいでしょう。

let result = 0;            // 結果を格納する変数
for(let i=0; i<100; i++){  // 100回のループ処理を実行
    result += 1;           // 1をresultに加算し続ける
}
result /= 10;              // resultを10で割る
console.log(result);       // 結果: 10!!!

書籍情報

プログラムはなぜ動くのか 第3版 知っておきたいプログラミングの基礎知識 [ 矢沢 久雄 ]

価格:2,640円
(2022/3/8 04:43時点)
感想(0件)

プログラムはなぜ動くのか 第3版 知っておきたいプログラミングの基礎知識【電子書籍】[ 矢沢 久雄 ]

価格:1,320円
(2022/3/8 04:43時点)
感想(0件)

  • 【書籍名】プログラムはなぜ動くのか
  • 【著者名】矢沢久雄
  • 【出版社】日経BP
  • 【出版日】2021年5月14日頃
  • 【ページ数】308

*1:書籍中ではC言語で実践しています。

*2:paiza.io