Direct3D 11 支援數個浮點表示法。 所有浮點運算都會在 IEEE 754 32 位單精度浮點規則的已定義子集下運作。
32 位浮點規則
有兩組規則:符合 IEEE-754 的規則,以及偏離標準的規則。
遵從 IEEE-754 規則
其中有些規則是 IEEE-754 提供選擇的單一選項。
- 用 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 定義相同的需求:32 位浮點運算產生的結果需在無限精確結果的 0.5 單位最後位置(ULP)以內。 這表示,例如,硬體允許將結果截斷為32位,而不是執行四捨五入到最接近的偶數,因為這樣會產生最大0.5 ULP的誤差。此規則僅適用於加法、減法和乘法。
不支援浮點數例外、狀態位元或陷阱。
非正常化數值在任何浮點數學運算的輸入和輸出時會被清除為帶符號的零。 對於任何不操作數據的I/O或數據移動作業,都會破例。
包含浮點值的狀態,例如 Viewport MinDepth/MaxDepth、BorderColor 值,可以作為非正常值提供,並且在硬體使用它們之前可能會或可能不會被清除。
最小或最大作業會排清反數,但結果可能或可能不會清除反數。
將 NaN 輸入到作業中時,輸出結果為 NaN。 但是 NaN 的確切位模式不需要維持不變(除非作業是一個不改變數據的原始移動指令)。
只有一個作數為 NaN 的最小或最大作業會傳回另一個作數作為結果(與我們稍早查看的比較規則相反)。 這是 IEEE 754R 規則。
Direct3D 10 和更新版本中的算術規則不會區分「無訊息」和「訊號」NaN 值(QNaN 與 SNaN)。 所有 「NaN」 值都會以相同的方式處理。
如果 min() 或 max() 的兩個輸入都是 NaN,則會傳回任何 NaN。
IEEE 754R 規則是 min(-0,+0) == min(+0,-0) == -0,而 max(-0,+0) == max(+0,-0) == +0;以紀念符號。 這與有符號的零的比較規則相反(如上所述)。 Direct3D 11 建議此處遵循 IEEE 754R 行為,但不會強制要求這樣做,允許結果依賴於參數順序,使用忽略符號的比較來達到比較零的效果。
x*1.0f 的結果總是 x(除非非規範化數清除)。
x/1.0f 總是會得到 x(除非去除了非規範化數 (denorm))。
x +/- 0.0f 一律會產生 x (除非非正規化值被清除)。 但 -0 + 0 = +0。
融合運算(如乘加 mad、dp3)的結果,精度不會低於其未融合展開中最差可能的序列順序的評估結果。 針對容錯目的,最差可能排序的定義不是指定融合運算的固定定義;這取決於輸入的特定值。 未融合擴展中的個別步驟均允許 1 個 ULP 容差(或對於 Direct3D 所呼叫的任何指令,若具有比 1 ULP 更寬鬆的容差,則允許更寬鬆的容差)。
Fused 作業遵循與非融合作業相同的 NaN 規則。
sqrt 和 rcp 有 1 個 ULP 容錯。 著色器倒數和倒數平方根指令,rcp 和 rsq,有其自己的寬鬆精度要求。
在 32 位元浮點數精度層級下,乘法和除法運算的精確度分別為 0.5 ULP(乘法)和 1.0 ULP(除法中倒數運算)。 如果直接實作 x/y,結果必須大於或等於雙步驟方法的精確度。
64 位 (雙精確度) 浮點規則
硬體和顯示驅動程式選擇性地支援雙精確度浮點數。 若要指出支援,當您使用 D3D11_FEATURE_DOUBLES呼叫 ID3D11Device::CheckFeatureSupport 時,驅動程式會將 DoublePrecisionFloatShaderOpsD3D11_FEATURE_DATA_DOUBLES 設為 TRUE。 驅動程式和硬體然後必須支援所有雙精度浮點指令。
雙精確度指示遵循 IEEE 754R 行為需求。
雙精確度數據需要產生反正規化值的支持(沒有排清到零的行為)。 同樣地,指令不會將反正規化數據讀取為帶正負號的零,而是遵循反正規化值。
16 位浮點規則
Direct3D 11 也支援浮點數的 16 位表示法。
格式:
- MSB 位位置中的 1 個符號位 (s)
- 5 位偏差指數 (e)
- 10 位元的分數部分(f),以及一個額外的隱藏位元
float16 值 (v) 遵循下列規則:
- 如果 e == 31 和 f != 0,則無論 s 為何,v 都是 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 也支援 11 位和 10 位浮點格式。
格式:
- 無符號位
- 5 位偏差指數 (e)
- 11 位格式的分數部分(f)有 6 位,10 位格式的分數部分(f)有 5 位,這兩種情況下,都有一個額外的隱藏位。
float11/float10 值 (v) 遵循下列規則:
- 如果 e == 31 和 f != 0,則 v 為 NaN
- 如果 e == 31 和 f == 0,則 v = +infinity
- 如果 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 位浮點數會保留非規範化數。
- 任何會導致數位小於零的作業都會固定為零。
相關主題