Direct3D では、いくつかの浮動小数点表現がサポートされています。 すべての浮動小数点計算は、IEEE 754 32 ビット単精度浮動小数点規則の定義済みのサブセットで動作します。
32 ビット浮動小数点規則
規則には、IEEE-754 に準拠するものと標準から逸脱した規則の 2 つのセットがあります。
IEEE-754 規則を順守しました。
これらの規則の一部は、IEEE-754 が選択肢を提供する 1 つのオプションです。
0 で除算すると +/- INF が生成されます。ただし、0/0 を除くと NaN になります。
(+/-) 0 のログでは-INF が生成されます。
負の値 (-0以外) の対数は NaN を生成します。
負の数の逆平方根 (rsq) または平方根 (sqrt) は NaN を生成します。
例外は -0 です。sqrt(-0) は -0 を生成し、rsq(-0) は -INF を生成します。
INF - INF = NaN
(+/-)INF / (+/-)INF = NaN
(+/-)INF * 0 = NaN
NaN (任意の OP) 任意の値 = NaN
一方または両方のオペランドが NaN の場合、EQ、GT、GE、LT、LE の比較は FALSEを返します。
比較では、0 の符号は無視されます (したがって、+0 は -0と等しくなります)。
一方または両方のオペランドが NaN の場合、比較 NE は TRUEを返します。
NaN 以外の値を +/- INF と比較すると、正しい結果が返されます。
IEEE-754 規則からの逸脱または追加要件
IEEE-754 では、無限に正確な結果に最も近い表現可能な値である結果を生成するために浮動小数点演算が必要です。これは、最も近い偶数への丸めと呼ばれます。
Direct3D 11 以降では、IEEE-754 と同じ要件が定義されています。32 ビット浮動小数点演算では、無限に正確な結果の 0.5 単位の最終位置 (ULP) 以内の結果が生成されます。 つまり、たとえば、ハードウェアでは、最大 0.5 ULP のエラーが発生するため、最も近い偶数へのラウンドを実行するのではなく、結果を 32 ビットに切り捨てることが許可されます。 この規則は、加算、減算、乗算にのみ適用されます。
以前のバージョンの Direct3D では、IEEE-754 よりも緩い要件が定義されています。32 ビット浮動小数点演算では、無限に正確な結果の 1 つの単位の最終位置 (1 ULP) 内にある結果が生成されます。 つまり、たとえば、ハードウェアでは、最大 1 つの ULP のエラーが発生するため、最も近い偶数へのラウンドを実行するのではなく、結果を 32 ビットに切り捨てることが許可されます。
浮動小数点例外、状態ビット、またはトラップはサポートされません。
非正規化は、浮動小数点演算の入力と出力で符号保持ゼロにフラッシュされます。 例外は、データを操作しない I/O またはデータ移動操作に対して行われます。
ビューポート MinDepth/MaxDepth 値や BorderColor 値などの浮動小数点値を含む状態は、非正規化値として提供される場合があり、ハードウェアがそれらを使用する前にフラッシュされる場合と、フラッシュされない場合があります。
最小または最大の演算では、比較のために非正規化数が丸められますが、結果では非正規化数の丸めが行われる場合とそうでない場合があります。
操作への NaN 入力では、常に出力時に NaN が生成されます。 ただし、NaN の正確なビット パターンは同じままである必要はありません (操作が生の移動命令である場合を除き、データは変更されません)。
1 つのオペランドのみが NaN である最小または最大の演算は、もう一方のオペランドを結果として返します (前に見た比較規則とは異なり)。 これは IEEE 754R 規則です。
浮動小数点の最小および最大操作の IEEE-754R 仕様では、min または max への入力の 1 つがクワイエット QNaN 値である場合、演算の結果はもう 1 つのパラメーターであると述べています。 例えば次が挙げられます。
min(x,QNaN) == min(QNaN,x) == x (same for max)
IEEE-754R 仕様の改訂では、1 つの入力が "シグナリング" SNaN 値と QNaN 値の場合に、min と max に対して異なる動作が採用されました。
min(x,SNaN) == min(SNaN,x) == QNaN (same for max)
一般に、Direct3D は算術の標準 (IEEE-754 および IEEE-754R) に従います。 しかし、この場合、偏差があります。
Direct3D 10 以降の算術規則では、静かな NaN 値とシグナリング NaN 値 (QNaN と SNaN) は区別されません。 すべての NaN 値は、同じ方法で処理されます。 min と max の場合、NaN 値の Direct3D 動作は、IEEE-754R 定義での QNaN の処理方法と似ています。 (完全性のために、 - 両方の入力がNaNの場合は、任意のNaN値が返されます。
もう 1 つの IEEE 754R 規則は、min(-0,+0) == min(+0,-0) == -0、および max(-0,+0) == max(+0,-0) == +0 という規則です。これは、符号付きゼロの比較規則とは対照的です (前に説明したように)。 Direct3D では、ここでは IEEE 754R の動作を推奨していますが、この動作は強制されません。ゼロを比較した結果は、符号を無視する比較を使用して、パラメーターの順序に依存することが許容されます。
x*1.0f は常に x になります (非正規数がフラッシュされた場合を除く)。
x/1.0f は常に x となります (丸められた非正規化数を除く)。
x +/- 0.0f は常に x になります (デノーマル数がフラッシュされる場合を除く)。 ただし、-0 + 0 = +0 です。
融合演算(mad、dp3 など)は、操作の非融合拡張を最も精度の低いシリアル順序で評価する場合と同等以上の精度の結果を生成します。 許容度を目的とした最悪の順序付けの定義は、特定の融合演算の固定された定義ではありません。入力の特定の値に依存します。 融合されていない拡張の個々のステップは、それぞれ許容される 1 ULP 許容値です (または、Direct3D が 1 ULP より緩い許容度で呼び出す命令の場合は、より緩い許容範囲が許可されます)。
融合された操作は、非融合操作と同じ NaN ルールに従います。
sqrt と rcp には、1 つの ULP 許容値があります。 シェーダーの逆数命令 rcp と逆数平方根命令 rsqには、それぞれ固有の緩和された精度要件があります。
乗算と除算は、32 ビット浮動小数点精度レベル (乗算の場合は 0.5 ULP、逆数の場合は 1.0 ULP) で動作します。 x/y が直接実装される場合、結果は 2 段階のメソッドよりも高いまたは等しい精度である必要があります。
64 ビット (倍精度) 浮動小数点規則
ハードウェアおよびディスプレイ ドライバーは、オプションで倍精度浮動小数点をサポートします。 サポートを示すために、ID3D11Device::CheckFeatureSupport を、D3D11_FEATURE_DOUBLESで呼び出したとき、ドライバーは DoublePrecisionFloatShaderOps を D3D11_FEATURE_DATA_DOUBLES の TRUE に設定します。 ドライバーとハードウェアは、すべての倍精度浮動小数点命令をサポートする必要があります。
倍精度命令は、IEEE 754R の動作要件に従います。
倍精度データには非正規化された値の生成のサポートが必要です (フラッシュからゼロへの動作はありません)。 同様に、命令は非正規化されたデータを符号付きゼロとして読み取りません。非正規化値が優先されます。
16 ビット浮動小数点規則
Direct3D では、浮動小数点数の 16 ビット表現もサポートされています。
形式:
- MSB ビット位置に 1 符号ビット
- 5 ビットのバイアス付き指数 (e)
- 小数 (f) に 10 ビット (隠しビットに 1 ビット)
float16 値 (v) は、次の規則に従います。
- e == 31 および f != 0 の場合、v は s に関係なく NaN になります
- e == 31 および f == 0 の場合、v = (-1)s*infinity (符号付き無限大)
- e が 0 ~ 31 の場合、v = (-1)s*2(e-15)*(1.f)
- e == 0 および f != 0 の場合、v = (-1)s*2(e-14)*(0.f) (非正規化された数値)
- e == 0 および f == 0 の場合、v = (-1)s*0 (符号付きゼロ)
32 ビット浮動小数点ルールは、前に説明したビット レイアウト用に調整された 16 ビット浮動小数点数にも保持されます。 これに対する例外は次のとおりです。
- 精度: 16 ビット浮動小数点数に対する非融合演算では、無限に正確な結果に最も近い表現可能な値である結果が生成されます (IEEE-754 ごとに最も近い偶数に丸め、16 ビット値に適用されます)。 32 ビット浮動小数点ルールは 1 ULP 許容値に準拠し、16 ビット浮動小数点ルールは、融合されていない操作の場合は 0.5 ULP、融合操作の場合は 0.6 ULP に準拠します。
- 16 ビット浮動小数点数はデノーマルを保持します。
11 ビットおよび 10 ビット浮動小数点規則
Direct3D では、11 ビットおよび 10 ビットの浮動小数点形式もサポートされます。
形式:
- 符号ビットなし
- 5 ビットのバイアス付き指数 (e)
- 11 ビット形式の場合は 6 ビットの分数 (f)、10 ビット形式の場合は 5 ビットの分数 (f)、どちらの場合も追加の隠しビット。
float11/float10 値 (v) は、次の規則に従います。
- e == 31 および f != 0 の場合、v は NaN です
- e == 31 および f == 0 の場合、v = +無限大
- e が 0 から 31 の場合、v = 2(e-15)*(1.f)
- e == 0 および f != 0 の場合、v = *2(e-14)*(0.f) (非正規化された数値)
- e == 0 および f == 0 の場合、v = 0 (ゼロ)
32 ビット浮動小数点規則は、前に説明したビット レイアウトに合わせて調整された 11 ビットおよび 10 ビットの浮動小数点数にも保持されます。 例外は次のとおりです。
- 精度: 32 ビット浮動小数点規則は、0.5 ULP に準拠します。
- 10/11 ビットの浮動小数点数で非正規化数を保持。
- 0 未満の数値になる演算は、0 にクランプされます。
関連トピック