タイプT
の場合std::is_floating_point<T>::value
はtrue
ですが、C++標準では、T
を実装する方法について何か指定していますか?
たとえば、T
は符号/仮数/指数表現に従う必要がありますか?それとも完全に恣意的でしょうか?
N3337から:
[basic.fundamental/8]:
浮動小数点のタイプには、float、double、およびlongdoubleの3つがあります。 double型は、少なくともfloatと同じ精度を提供し、long double型は、少なくともdoubleと同じ精度を提供します。 float型の値のセットは、double型の値のセットのサブセットです。 double型の値のセットは、longdouble型の値のセットのサブセットです。 浮動小数点型の値表現は実装定義です。積分型と浮動型は、まとめて算術型と呼ばれます。標準テンプレートstd :: numeric_limits(18.3)の特殊化は、実装の各算術型の最大値と最小値を指定するものとします。
実装でIEEE-754が使用されているかどうかを確認する場合は、 std::numeric_limits::is_iec559
:を使用できます。
static_assert(std::numeric_limits<double>::is_iec559,
"This code requires IEEE-754 doubles");
この領域には、 has_infinity
、 quiet_NaN
、 more など、他にも多くのヘルパー特性があります。
C標準には「付録」(C11では付録F)があり、Cの実装がIEC 60559、IEEE754の後継標準)に準拠することの意味を示しています。附属書Fに準拠する実装には、IEEE表現の浮動小数点数が必要です。ただし、この附属書の実装はオプションであり、コア標準では、浮動小数点数の表現について何も言わないようにしています。
C++に相当する別館があるかどうかはわかりません。 N3337には表示されませんが、個別に配布されている可能性があります。 std::numeric_limits<floating-type>::is_iec559
の存在は、C++委員会が少なくともthoughtこれについてですが、おそらくC委員会ほど詳細ではないことを示しています。 (C++標準がC標準の一連の編集として表現されていないことは、常に残念なことです。)
特別な実装は必要ありません。 C++標準では、それについてはまったく説明されていません。 C標準では、浮動小数点数に対して想定される概念モデルについて、符号、指数、仮数を基数b
などでかなり詳しく説明しています。ただし、これは純粋に説明的なものであり、実装の要件ではないことを具体的に述べています(C11、脚注21)。
浮動小数点モデルは、各浮動小数点特性の説明を明確にすることを目的としており、実装の浮動小数点演算が同一である必要はありません。
とはいえ、詳細は異なる場合がありますが、少なくとも、(たとえば)double
の適合実装を作成し、公正に適合しなかったように思われます。 )通常のモデル(つまり、仮数と指数)と密接に連携することは困難です(または、少なくとも競争力のあるパフォーマンスで行うのは困難です)。ただし、順序を並べ替えたり、別のベースを使用したりするなど、他の方法で変更することは特に難しいことではありません。
std::numeric_limits<T>::digits
(およびstd::numeric_limits<T>::digits10
)の定義は、浮動小数点型としてリストされているものが、かなり広い範囲の大きさにわたってすべての数値に対して(少なくともほぼ)同じ精度を保持する必要があることをかなり直接的に意味します。これを実現するための最も明白な方法は、仮数に割り当てられたビット/桁の数と、指数に割り当てられた他の(個別の)ビットのセットを用意することです。
std::is_floating_point
のアイデアは、異なるOriginのユーザーコードをより適切に連携させることです。技術的には、未定義の動作を引き起こすことなく、int
をstd::is_floating_point
として指定できます。ただし、T n
で繰り返し除算する必要のあるテンプレートライブラリがあるとします。処理を高速化するために、ライブラリはT ni = 1 / n
を作成し、除算をn
に置き換えてni
を乗算します。これは浮動小数点数には最適ですが、整数には失敗します。したがって、ライブラリはstd::is_floating_point<T>::value == true
の場合にのみ最適化を正しく実行します。嘘をついた場合、コードはおそらく標準の観点からは機能しますが、論理的な観点からは正しくありません。したがって、より大きなfloat
のように動作するクラスを作成する場合はstd::is_floating_point
としてマークし、そうでない場合はマークしないでください。これにより、最適なコードと正しいコードの両方が得られるはずです。