簡體   English   中英

快速平方根逆算法中第一種類型校正的確切值是多少?

[英]What is the exact value of the first type-punning in fast square root inverse algorithm?

有了這段代碼,(這是Quake 3中使用的眾所周知的快速平方根逆算法),我無法理解打印輸出。 我從表面上了解了整個算法,但希望獲得深入的了解。 printf打印時i的值是什么? 這給了我1120403456。 是否取決於計算機的體系結構? 我讀過某處這樣的類型操縱會導致不確定的行為。 在另一個網站上,我讀到了那時i的值是此變量使用的位的確切值。 我對此感到困惑,並且誠實地期望i的值為100。如何解釋結果1120403456? 如何將此值轉換為十進制100? 這些位是以某種方式編碼的嗎? 這是代碼摘錄:

#include<stdio.h>

int main()
{
float x = 100;
float xhalf = 0.5f*x;
int i = *(int*)&x;
printf("%d", i);
i = 0x5f3759df - (i>>1);
x = *(float*)&i;
x = x*(1.5f-xhalf*x*x);
return x;

}

int i = *(int*)&x;之后打印的i的值int i = *(int*)&x; 是浮點數100.0的位表示形式,這是x初始化的對象。 由於您在printf使用%d格式,因此它將表示形式打印為十進制整數。

的位模式100.0在IEEE 32位float0x42c80000 ,這是1120403456十進制

要將1120403456或任何其他數字解釋為IEEE基本的32位二進制浮點數:

  • 將數字寫為32位,在這種情況下為01000010110010000000000000000000。
  • 第一位是符號。 0是+,而1是-。
  • 接下來的八位是指數的編碼。 它們是10000101,即十進制133。 指數使用偏差127進行編碼,這意味着所表示的2的實際冪是2 133-127 = 2 6 (如果指數為0或255,則這是一個具有不同含義的特殊值。)
  • 其余23位對有效位數進行編碼。 對於普通指數(代碼1到254),它們對以“ 1”開頭並附加23位“ 10010000000000000000000”以形成二進制數“ 1.10010000000000000000000”而形成的有效位數進行編碼。 以十進制表示,為1.5625。
  • 編碼的完整值是帶2的冪乘以有效數的符號:+ 2 6 •1.5625,等於64•1.5625,即100。

如果指數代碼為0,則表示2 -126 ,並且有效位數將以“ 0.”而不是“ 1”開頭。

如果指數代碼為255,且有效位為零,則對象將表示無窮大(根據符號位為+∞或-∞)。 如果指數代碼為255,並且有效位不為零,則該對象將表示非數字(NaN)。 NaN還有其他語義未包含在此答案中。

比Quake III早得多 ,盡管確切的魔術常數有所變化。

根據IEEE-754(大多數現代計算機使用的)對有限單精度浮點數進行編碼是

     31 30           23 22                                          0
     ├─┼─┬─┬─┬─┬─┬─┬─┬─┼─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┤
     │S│   Exponent    │                   Mantissa                  │
     └─┴───────────────┴─────────────────────────────────────────────┘

最高位S是符號。 如果設置,則該值為負,否則為正。

如果ExponentMantissa均為零,則值為0.0(如果S為零)或-0.0(如果S為1)。

如果Exponent為零,但Mantissa非零,則您有一個非常接近零的非正規數

Exponent為255(所有位均已設置)的表示形式保留為無窮大(如果Mantissa為零),而不是數字(如果Mantissa不為零)。

對於從1到254(含)之間的Exponent值, Mantissa包含Mantissa小數位,在整數位置含一個隱式1(這是(1)0 10000001 (1)1011011011011011011011 。)換句話說,對於這些Exponent值, Mantissa表示的值是從1.00000000000000000000000 2 (十進制1.0)到1.11111111111111111111111 2 (十進制1.99999994)(含)。

= Exponent (between 1 and 254, inclusive), and the logical value of Mantissa (between 1.0 and 1.99999994), then the value the single-precision floating point represents is 現在,如果我們僅考慮非負值( S清除), = Exponent (1到254之間,包括1和254之間),而Mantissa的邏輯值(1.0到1.99999994之間),則值為單精度浮點點代表是

= 2 - 127 × = 2 -127 ×

127是指數偏差。 is 平方根是

= 2 ( - 127)/2 × √ = 2 /2 - 127 × 2 63 × √2 × √ = - 127)/ = 2 / 2 - 127×2 63×√2×√

和平方根反比,這是這里的目標運算,

= 2 (127 - )/2 × 1/√ = 2 - /2 - 127 × 2 63 × √2 × 1/√ 1 = 2(127 - 2×1 = 2 - / 2 - 127×2 63×√2×1 /√

注意2127/2 = 2 63.5 = 2 63 ×√2。

. 如果我們采用整數表示形式,並將其向右移一位,我們實際上將減半。 要乘以2 63 ,我們需要將63加到指數上。 63×2 23 , we effectively just multiply by /2. 然而代替,對於平方根運算,乘以√2×√ ,我們有效地只是乘以 / 2。 這意味着(將整數表示右移一位,然后將63加到指數上)會得出平方根的估計值,對於大於1.0的自變量,其平方差在0.7071067到0.75之間,而系數在0.7071067到0.05之間。 0和1之間的值是1448.155(對於√0,它的輸出為5.421×10 -20,對於√1,它的輸出為0.75。)

. 注意,對於平方根的倒數運算,我們希望對求反。

). 事實證明,如果向右一位移位整數表示,然后減去從(1 01111100 1101110101100111011111)2(1597463007十進制,十六進制0x5f3759df,的√2127≈1304381​​7825332782212單精度浮點近似值) ,你得到的平方根的倒數(1 的一個很好的近似。 對於所有有限的普通自變量,近似值與正確值之間的距離為0.965624至1.0339603。 一個非常好的近似值! 對於頂部的平方根逆運算,您需要做的是一兩次牛頓方法迭代。 ) = 0 iff = 1/√ you need f( ) = 1/ ^2 - . So, each iteration in is - f( )/f'( ) = × (1.5 - 0.5 × × × . Which should look quite familiar.) (對於 0當且僅當 = 1 您需要 1 / ^ 2 - 因此,在每次迭代是 - ×(1.5-0.5× × × 。應該看起來很熟悉。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM