浮動小数点数と固定小数点数
浮動小数点数(float/double)と固定小数点数について、基本的な情報処理の知識としてみなさま学びますね。
そして、float/doubleは小数使いたくなったらプログラムでも気軽に使いますね。
「小数点の管理の仕方の違い」と習いますが、実際には非常に重要な機能の違いがあります。
0.1 + 0.2 => 0.30000000000000004
- 浮動小数点数 => ほとんどの小数は表現できないおおよその数字
- 固定小数点数 => 小数を表現できる実際の数字
浮動小数点数がどのぐらいおおよそかといえば、↓ぐらいデタラメ
0.1 + 0.2
=> 0.30000000000000004
0.1 + 0.7
=> 0.7999999999999999
↑はJavaScriptで一瞬で再現可能。
フロントエンドでお金の計算するの怖い
という時に使いましょう
2進数で無限小数になる数は表現できない
浮動小数点数が誤差を生じる理由は、2進数で無限小数になる数を正確に表現できないためです。ほとんどの10進数の小数は、2進数に正確に変換できません。
詳細は「浮動小数点 無限小数」とかでググってください。
「小数が浮動」ではなく「おおよその数しか表現できない」というのが浮動小数点数の正体なのです。
"精度"という言葉の罠
「Javaだと精度の問題があるからBigDecimal使いましょう。」とよく言われます。
精度
という言葉を単純に受け取ることは危険です。
例えば、「小数点以下10桁程度で誤差が生じるのかな?」というように考えてしまうと、仕様が1桁程度であれば関係ないと勘違いしてしまうかもしれません。というか私は何度かしています。
実際には上述の通りに、浮動小数そのものあが、おおよその数でしかなく、計算の過程でそれが累積してずれていきます。
「浮動小数使って計算したら値はずれてる覚悟がいる。」の方が感覚として大切です。
計算コストとかそういう話
じゃあ、みんな固定小数点使えば世界は平和じゃない。と感じますが、ゲーム/API/アプリ。。。とかなり(というかほとんど?)に浮動小数点数が使われます。CPUの性能指標とかまんまですね。
値がずれてしまう。と言っても精度の端の誤差ではあります。コンピューター全体でみると、精度の端の誤差よりも計算速度の方がよほど大切なのです。
コンピュータの世界って実は適当なのですね雑
概数、真数
MySQLやRDBMSなどのデーターベース界隈では「概数」「真数」という表現があります。
浮動小数などは↓のように対応します。
- 概数(浮動小数点型)
- 真数(固定小数点型、整数)
おおむねの数
と、まことの数
と、超分かりやすくないでしょうか?私は知ったときに目から鱗でした。
データーベース界隈では一般的に使われてる表現であり、別に世界で閉じておく必要もないと感じます。
プログラミング言語の説明にも普通に取り入れてしまって良いのではと思いました。