2016-03-23 85 views
1

我正在尋找地震中使用的反轉sqrt的示例代碼。這是什麼意思*(int *)&x當typecasting?

我看到float類型的變量:float x = 16;

並且然後int可變藉此表達式的值:int i = *(int*)&a;

我理解(從右到左)的方式是,它需要的將變量a的地址類型化爲一個整型指針,然後獲取該指針的值並將其分配給i

當我在控制檯輸出變量i這是一個很大的整數值。 有人能解釋一下這裏發生了什麼嗎?

因爲我預計變量i16

+1

此代碼演示了由於嚴格的別名違反規則而導致的未定義行爲,這可能是您需要了解的唯一一件事。 – SergeyA

回答

9

&a取地址爲a,浮點數; (int *)保持相同的地址,但現在告訴編譯器假裝int存儲在那裏; int i = *然後從該地址加載int

所以你得到一個與float相同的位模式的整數。浮動和整數具有非常不同的編碼,所以您最終會得到一個非常不同的值。

浮動可能會制定like this,但它不是必需的;你的架構可能會做別的。可能作者正在做一個特定於平臺的優化版本frexp

int i = (int)x;將簡單地將float轉換爲int,給你16

+1

我編輯過,以表明它可能是一個優化的嘗試,以拉出尾數和/或指數。從浮點到整數的轉換是昂貴的(相對而言,你知道),但假設你知道你的值總是在0到1的範圍內,也就是說你已經知道指數,你可能想直接獲取尾數作爲位你的int。經典的例子是CPU上的圖像處理:如果所有的顏色都以[0.0,1.0)中的數字開始,那麼通常你的輸出也是[0.0,1.0),但你需要發送整數字節到顯卡。 – Tommy

+1

你沒有提到的一件事是,由於違反嚴格的別名規則,代碼是未定義的行爲。 – SergeyA

+0

@SergeyA確實,我覺得完全沒有資格做出合適的編輯。從C99開始,6.2.7定義了兼容類型,以便不包含int和float,並且6.5.16強制在指針分配中需要兼容的指向類型,但只能在混合中使用賦值運算符。我很難找到最終的鏈接,以顯示在中間沒有臨時任務時適用相同的規則。所以我標記爲社區維基。請先潛入 – Tommy