2010-08-10 130 views
0

可能重複:
John Carmack’s Unusual Fast Inverse Square Root (Quake III)這個C習語是什麼意思?

我碰到這段代碼就最近一個博客 - 它是從Quake3的引擎。這意味着使用Newton-Rhapson方法快速計算反平方根。

float InvSqrt (float x){ 
    float xhalf = 0.5f*x; 
    int i = *(int*)&x; 
    i = 0x5f3759df - (i>>1); 
    x = *(float*)&i; 
    x = x*(1.5f - xhalf*x*x); 
    return x; 
} 

做什麼原因int i = *(int*)&x;?做int i = (int) x;反而給出了完全不同的結果。

+10

我敢肯定這是不是C程序員之間的一個成語。 – nos 2010-08-10 19:01:57

+3

將'float'強制轉換爲'int'完全不同於將'float'指針轉換爲'int'指針。此外,這種方法比'rsqrtss' x86指令慢得多,準確度也低。 – zneak 2010-08-10 19:06:10

+6

我認爲,這是不是一個真正的重複,因爲它要求對'*爲(int *)&x',而不是魔術常量'0x5f3759df'這是其他問題的主要焦點。 – 2010-08-10 19:21:36

回答

7

int i = *(int*)&x;不轉換x爲int - 它的作用是讓的實際位浮點數x,它通常表示爲比您預期的整個其他4個字節的值。

作爲參考,這樣做,這是一個非常糟糕的主意,除非你知道浮點值究竟是如何在內存中表示。

+4

這更糟糕的想法,因爲重新解釋調用未定義的行爲,現代編譯器作者喜歡將其優化。 – 2010-08-11 18:02:49

7

int i = *(int*)&x;說:「拿四個字節從而彌補了浮點值x和對待他們,好像他們是一個int。」浮點值和int值使用完全不同的方法存儲(例如INT 4和浮動4.0有完全不同的位模式),

2

i最終數量爲x中的號碼的IEEE浮點表示的二進制值。鏈接解釋了這個樣子。這不是一個常見的C語言習慣,這是在SSE指令被添加到商用x86處理器之前的一個聰明的技巧。