Referer一覧の存在に気づいたので、リンクして下さっている方々の文章を今更読んでいます。ただ、おそらく浮動小数点数の扱いが拙いのをround関数のせいにしているような文章を見つけました。もしそういう誤解があれば非常に残念だと思うと同時に、これだけ注目を集めたからには浮動小数点数一般の罠について簡単に紹介してみても良いかな、と思いつきました。浮動小数点数まわりでハマった人がここに検索でやってくることがあるかもしれません。

そんなわけで、今回のテーマは啓蒙です。浮動小数点数の不思議さについて簡単な紹介記事を書いてみました。また、第1回記事中の誤っている点について、1点訂正をします。今回はイメージ先行で書いてみましたが、伝えていないことはあっても嘘は書いていないつもりです。正確な内容が知りたくなった方はWikipediaの記事「浮動小数点数」を読むと良いでしょう。または、そこからリンクされている「浮動小数点演算について」を読めば完璧な知識を手に入れられると思います*1。

以下、この記事中ではIEEE64bit浮動小数点数のことを単に浮動小数点数と書くことにします。これは、Cで言うdouble型のことです。また、PHPやPerlやRubyやPythonで単に小数点を含んだ数を書いた場合にはIEEE64bit浮動小数点数として扱われます。

さて、浮動小数点数の正体をざっくり言うと、「大きい数も小さい数も表せる、有効数字が10進16桁程度の数」といったところです。僕らが知っている普段の小数と違う点は下記の2点です。

中身が2進数である 表現できる桁数が決まっている

そんなことわかってるよ、と思う人も多いかと思いますけど、本当にそうでしょうか。浮動小数点数の世界で「0.1を10回足してもおそらく1にならない」というのは教科書にも書いてあるようなことですけど、この事実から「よくわからないけど誤差が入るから怖いんだな、じゃあ使わないようにしよう」というくらいの認識の人が案外多いのではないでしょうか*2