numeric_limits::radix

以前作成したfloat_t(boost::int_tのfloat版)ですが、根本的なところに問題がありました。
float_tは浮動小数点型の精度をチェックするのにstd::numeric_limits<T>::digitsを参照しています。
自分はこれをずっとビット数だと勘違いしていました。
実際には、numeric_limitsに指数部の基数を示すradixというメンバがあって、digitsはradix進法での仮数部の桁数になります。なので、仮数の精度を調べるにはradixとdigitsを見ないといけません。
ところが、radixの異なる2つの浮動小数点型では、精度が大きいからといって必ずしも小さい型の全ての値を表現できるというわけではありません。これは、10進の0.1が2進で正確に表現できないという話と同じです。
なので、IEEE 754のSingle/Doubleの値を完全に表現できる型を選択するためにfloat_tを使用することは一般には不可能です。
妥協案としては、

  • digits10で10進でのおおよその精度を調べる
  • 型のサイズだけで判定する(可能ならパディングのサイズは除く)
  • IEEE 754以外サポートしない

なんかが考えられますが、最後の案でいいやという気になってきました。