浮動小数点の代替手段は意外とたくさんある
More Floating Point Alternatives

浮動小数点以外にも数を表現する方法は複数存在する。10進浮動小数点(PythonのdecimalやJavaのBigDecimal)、正確な分数計算(Pythonのfractions、Lispの標準サポート)、記号計算(Mathematica、Maple、sympy)、区間演算、そしてIBMが1960年代に使っていた2進化10進数(ISO 8583などで現役)だ。いずれもソフトウェア実装のためハードウェアより遅く、言語ごとにライブラリが異なる。
これらはすべてソフトウェアで実装されている(ハードウェアではない)ため、かなり遅く、言語によって異なるライブラリがある。
HNでの議論
44- AlotOfReading
通常、自分のアルゴリズムを十分に理解して適切な浮動小数点の代替手段を選べるなら、浮動小数点コードを修正する方法も十分に理解しているはずで、実際にそうすべきなのはそれだ。
とはいえ、ここに挙げられているものの中には代替手段ではないものもある。記号計算はまったく別物だ。区間演算は浮動小数点の上に構築できるし(例えばIEEE-1788)、それ自体が直感に反する振る舞いの動物園のようなものだ。BCDは今日では代替手段というより歴史的遺物と呼ぶ方が適切だ。
このリストで本当に代替手段と言えるのは有理数と10進浮動小数点だけだろうが、浮動小数点の代替を検討しているなら、おそらくそれらでは君の抱える問題は解決しない。
- ashton314
これも興味深い:Herbieは数式を解析して、どこで浮動小数点誤差が蓄積されるかを突き止める手助けをしてくれる。https://herbie.uwplse.org/demo/
我々は速度と精度のトレードオフとして浮動小数点を使っている。IEEE 754は幅広いアプリケーションにとって非常に合理的なトレードオフだが、ここで挙げられているような手法の一つを使って精度を上げるために速度を犠牲にする必要がある箇所を特定できるなら、Herbieがその落とし穴をカバーしてくれる。
フォーマット間の切り替えに関する研究を見た記憶があるが、今すぐ引用できるものはない。
- Panzerschrek
場合によっては2進固定小数点数を使っている。ある側面では浮動小数点よりずっと優れている——加減算で精度が失われない(オーバーフロー/アンダーフローが起きなければ)、加減算は通常より高速(内部的には単なる整数演算だから)、整数とのキャストも安価(ビットシフトだけが必要)。
乗算は少し厄介だ。整数による乗算は自明。2つの固定小数点数を掛けると、結果の小数2進桁数は元の数の小数桁数の合計になる。結果は拡張型に格納するか、切り捨てるか、丸めることができる。
除算も問題なく動作するが、CPUがなぜか整数除算よりも浮動小数点除算をはるかに高速に行えるため、浮動小数点型と比べて遅くなることがある。
固定小数点数の唯一の欠点は、範囲と精度のバランスを注意深く保つ必要があることだ。コードベース全体で特定の精度を使うわけにはいかず、通常は個々の演算ごとに精度を選ぶ必要がある。
- thebeardisred
Posits(Unum)も忘れないでほしい。https://www.cs.cornell.edu/courses/cs6120/2019fa/blog/posits...
- timschmidt
おや、私のプロジェクトの一つが記事に関連している:https://github.com/timschmidt/hyperreal
これは無限精度の正確な構成可能実数で、優れた性能特性を持ち、明示的に名前を付けた非可逆エクスポート関数でのみ近似を行う。
最近のベンチマーク:https://github.com/timschmidt/hyperlattice/blob/805d092d1d96...