Dela via


flyttalsregler

Direct3D stöder flera flyttalsrepresentationer. Alla flyttalsberäkningar utförs enligt en definierad delmängd av IEEE 754 32-bitars regler för flyttal med enkel precision.

32-bitars flyttalsregler

Det finns två uppsättningar regler: de som följer IEEE-754 och de som avviker från standarden.

följer IEEE-754-standardens regler

Vissa av dessa regler är ett enda alternativ där IEEE-754 erbjuder alternativ.

  • Dividera med 0 ger +/- INF, förutom 0/0 vilket resulterar i NaN.

  • loggen för (+/-) 0 producerar -INF.  

    Logaritmen för ett negativt värde (förutom -0) ger NaN.

  • Omvänd kvadratrot (rsq) eller kvadratrot (sqrt) av ett negativt tal genererar NaN.  

    Undantaget är -0; sqrt(-0) producerar -0, och rsq(-0) producerar -INF.

  • INF – INF = NaN

  • (+/-)INF/ (+/-)INF = NaN

  • (+/-)INF * 0 = NaN

  • NaN (valfritt OP) valfritt värde = NaN

  • Jämförelserna EQ, GT, GE, LT och LE returnerar FALSEnär antingen eller båda operanderna är NaN.

  • Jämförelser ignorerar tecknet 0 (så +0 är lika med -0).

  • När antingen eller båda operanderna är NaN returnerar jämförelsen NE TRUE.

  • Jämförelser av alla icke-NaN-värden mot +/- INF returnerar rätt resultat.

Avvikelser eller ytterligare krav från IEEE-754-regler

  • IEEE-754 kräver flyttalsoperationer att ge ett resultat som är det närmaste representerbara värdet av ett oändligt exakt resultat, känt som "runda till närmaste jämna".

    Direct3D 11 och uppåt definierar samma krav som IEEE-754: 32-bitars flyttalsoperationer ger ett resultat som ligger inom 0,5 enhet i sista position (ULP) för det oändligt exakta resultatet. Det innebär till exempel att hårdvara tillåts trunkera resultat till 32-bitars istället för att utföra avrundning till närmaste jämna tal, eftersom det i så fall skulle resultera i ett fel på högst 0,5 ULP. Den här regeln gäller endast addition, subtraktion och multiplikation.

    Tidigare versioner av Direct3D definierar ett lösare krav än IEEE-754: 32-bitars flyttalsoperationer ger ett resultat som ligger inom en ULP av det oändligt precisa resultatet. Det innebär till exempel att maskinvaran tillåts trunkera resultat till 32-bitars istället för att utföra avrundning till närmaste jämna tal, eftersom det skulle leda till fel på högst en ULP.

  • Det finns inget stöd för flyttalsundantag, statusbitar eller fällor.

  • Denormaliserade värden omvandlas till teckenbevarade nollor vid inmatning och utmatning av alla flyttalsoperationer. Undantag görs för alla I/O- eller dataflyttsåtgärder som inte manipulerar data.

  • Tillstånd som innehåller flyttalsvärden, till exempel Viewport MinDepth/MaxDepth- eller BorderColor-värden, kan anges som denormvärden och kan eller kanske inte rensas innan maskinvaran använder dem.

  • Min- eller maxoperationer rensar bort denormtillstånd för jämförelse, men resultatet kan vara eller kanske inte är spolat bort från denormtillståndet.

  • NaN-indata till en operation genererar alltid NaN som utdata. Men det exakta bitmönstret för NaN krävs inte för att förbli detsamma (såvida inte åtgärden är en rå flyttinstruktion – som inte ändrar data.)

  • Min- eller maxåtgärder för vilka endast en operand är NaN returnerar den andra operanden som resultat (i strid med jämförelseregler som vi tittade på tidigare). Det här är en IEEE 754R-regel.

    IEEE-754R-specifikationen för flyttalsoperationerna min och max anger att om en av inmatningarna till min eller max är ett QNaN-värde som är tyst, är resultatet av operationen den andra parametern. Till exempel:

    min(x,QNaN) == min(QNaN,x) == x (same for max)
    

    En revision av IEEE-754R-specifikationen antog ett annat beteende för min och max när en indata är ett "signalerande" SNaN-värde jämfört med ett QNaN-värde:

    min(x,SNaN) == min(SNaN,x) == QNaN (same for max)
    
    

    I allmänhet följer Direct3D standarderna för aritmetik: IEEE-754 och IEEE-754R. Men i det här fallet har vi en avvikelse.

    De aritmetiska reglerna i Direct3D 10 och senare gör ingen skillnad mellan tysta och signalerande NaN-värden (QNaN jämfört med SNaN). Alla NaN-värden hanteras på samma sätt. När det gäller min och max är Direct3D-beteendet för alla NaN-värden som hur QNaN hanteras i IEEE-754R-definitionen. (För fullständighet – om båda indata är NaN returneras alla NaN-värden.)

  • En annan IEEE 754R-regel är att min(-0,+0) == min(+0,-0) == -0 och max(-0,+0) == max(+0,-0) == +0, vilket respekterar tecknet, i motsats till jämförelsereglerna för signerad noll (som vi såg tidigare). Direct3D rekommenderar IEEE 754R-beteendet här, men tillämpar det inte. Det är tillåtet att resultatet av att jämföra nollor är beroende av parametrarnas ordning, med hjälp av en jämförelse som ignorerar tecknen.

  • x*1.0f resulterar alltid i x (utom när denormaliserade tal spolas).

  • x/1.0f resulterar alltid i x (utom när denormaliserade tal rensas bort).

  • x +/- 0.0f resulterar alltid i x (förutom när denormala värden spolas bort). Men -0 + 0 = +0.

  • Fuserade operationer (till exempel mad, dp3) ger resultat som inte är mindre exakta än den sämsta möjliga serieordningen för utvärdering av den ofuserade formen av operationen. Definitionen av den sämsta möjliga ordningen i toleranssyfte är inte en fast definition för en viss sammansvetsad åtgärd. det beror på de specifika värdena för indata. De enskilda stegen i den osammansatta expansionen har en toleransgräns på 1 ULP (eller för instruktioner som Direct3D anropar med en mindre strikt tolerans än 1 ULP tillåts den mindre strikta toleransen).

  • Sammansvetsade åtgärder följer samma NaN-regler som icke-sammansvetsade åtgärder.

  • sqrt och rcp har 1 ULP-tolerans. Shaderns reciproka och reciproka kvadratrotsinstruktioner, rcp och rsq, har sina egna separata krav på avslappnad precision.

  • Multiplicera och dividera varje operation med 32-bitars flyttalsprecision (med en noggrannhet på 0,5 ULP för multiplikation, 1,0 ULP för reciprok). Om x/y implementeras direkt måste resultatet ha större eller lika noggrannhet än en tvåstegsmetod.

Regler för 64-bitars flyttal (dubbel precision)

Maskin- och grafikdrivrutiner kan möjligen stödja flyttal med dubbel precision. För att indikera stöd, när du anropar ID3D11Device::CheckFeatureSupport med D3D11_FEATURE_DOUBLES, sätter drivrutinen DoublePrecisionFloatShaderOps av D3D11_FEATURE_DATA_DOUBLES till TRUE. Drivrutinen och maskinvaran måste sedan stödja alla flyttalsinstruktioner med dubbel precision.

Instruktioner med dubbel precision följer beteendekraven för IEEE 754R.

Stöd för generering av denormaliserade värden krävs för data med dubbel precision (utan flush-to-zero-beteende). På samma sätt läser instruktionerna inte avnormaliserade data som en undertecknad nolla; de följer denormvärdet.

16 bitars flyttalsregler

Direct3D stöder också 16-bitars representationer av flyttalsnummer.

Format:

  • 1 teckenbit(er) i positionen för MSB-biten
  • 5 förskjutna bitar av exponenten (e)
  • 10 bit bråktal (f) med en ytterligare dold bit

Ett float16-värde (v) följer dessa regler:

  • om e == 31 och f != 0, är v NaN oavsett s
  • om e == 31 och f == 0, då är v = (-1)s*oändlighet (signerad oändlighet)
  • om e är mellan 0 och 31, v = (-1)s*2(e-15)*(1.f)
  • if e == 0 and f != 0, then v = (-1)s*2(e-14)*(0.f) (avnormaliserade tal)
  • Om e == 0 och f == 0, då v = (-1)s*0 (signerad nolla)

32-bitars flyttalsregler gäller även för 16-bitars flyttalsnummer, justerade för bitlayouten som beskrevs tidigare. Undantag till detta inkluderar:

  • Precision: Osammanfogade operationer på 16-bitars flyttal ger ett resultat som är det närmaste representerbara värdet till ett oändligt noggrant resultat (avrunda till närmaste jämna tal, enligt IEEE-754, tillämpat på 16-bitarsvärden). 32-bitars flyttalsregler följer 1 ULP-tolerans, 16-bitars flyttalregler följer 0,5 ULP för ofuserade åtgärder och 0,6 ULP för sammansvetsade åtgärder.
  • 16-bitars flyttal bevarar denormaliserade tal.

Regler för 11-bitars och 10-bitars flyttalsrepresentation

Direct3D stöder även 11-bitars- och 10-bitars flyttalformat.

Format:

  • Ingen teckenbit
  • 5 förskjutna bitar av exponenten (e)
  • 6 bitars bråk (f) för ett 11-bitars format, 5 bitar bråk (f) för ett 10-bitars format, med ytterligare en dold bit i båda fallen.

Ett float11/float10-värde (v) följer följande regler:

  • if e == 31 and f != 0, then v is NaN
  • if e == 31 and f == 0, then v = +infinity
  • om e är mellan 0 och 31, v = 2(e-15)*(1.f)
  • Om e == 0 och f != 0, då är v = *2(e-14)*(0.f) (denormaliserade tal)
  • om e == 0 och f == 0, sedan v = 0 (noll)

32-bitars flyttalsregler gäller även för 11- och 10-bitars flyttalsnummer, justerade för den bitlayout som beskrevs tidigare. Undantag är:

  • Noggrannhet: 32-bitars flyttalsregler följer enligt 0,5 ULP.
  • 10/11-bitars flyttal bevarar denormaliserade tal.
  • Alla åtgärder som skulle resultera i ett tal som är mindre än noll är fastklämda till noll.

Tillägg

Resurser

Texturer