2013-08-20 22 views
4

查找浮點數的絕對值的算法,超過here。 這是如何工作的?fabs()的這個實現是如何工作的?

//find absolute value 
double x; 
*(((int *) &x) + 1) &= 0x7fffffff; 

我不明白爲什麼1偏移是必要的。它說:

IA32 64位符號位是0x80000000在int地址偏移+1。

有人可以解決這個問題嗎?

+2

「有人可以解決這個問題並解釋嗎?」 - 也許你可以嘗試解釋一下? –

+4

@MitchWheat:也許你可以少一點判斷力。 OP的問題顯然是措辭,甚至解釋了特定的困惑點:抵消1. –

+0

@R:我問了一個有禮貌和合理的問題。你的牛肉是什麼? –

回答

8

該代碼在技術上無效C,因爲它打破了嚴格的別名規則。但是,如果你告訴你的編譯器不濫用別名規則,你就保證double S和int s的佈局在內存中,因爲它們是在x86:

(int *)&x是指向x。添加1將指針向前移動4個字節。取消引用會爲您提供double的第4至第7個字節。你掩蓋了這個高位,因爲這是double的最後一個字節。

順便提一句,您可以通過使用char *並添加7而不是1來阻止這種情況出現鋸齒違規。它仍然是非常不可移植的。

+0

很好的答案。你似乎很熟悉。 – nneonneo

+1

's/abuse/use /'... –

+2

並且隨着你對'char'的修改,我會說它只是*非常輕便*不可移植而不是非常可怕。真正唯一不可移植的方面是字節序假設。假設'double'是以IEEE格式存儲的IEEE雙精度是一個相當合理的假設。 –

1

這是高度依賴於平臺的。

無論如何,你有雙倍的最高位是符號位。

如果你的double有8個字節,而你的int有4個字節,並且你在LE系統上,那麼最高位是最後一個字節的最高位,或者是第二個整數。

所以你取第二個整數(你可以寫((int *)&x)[1] &= 0x7fffffff)並清除它的最高位。

7

double一個是8個字節寬,並且具有以下的格式:

enter image description here

您顯示該代碼假定int是4個字節寬,並且這兩個intdoublelittle-endian(意味着位0- 7存儲在字節0中,8-15存儲在字節1中,依此類推)。

如果x是指向double

*(((int *) &x) + 0) addresses bits 0 through 31; 
*(((int *) &x) + 1) addresses bits 32 through 63. 

因此,*(((int *) &x) + 1) &= 0x7fffffff集第63位到零,改變x到其絕對值。

+4

你應該真的從左到右翻轉那個圖像。 :) – tmyklebu

+13

@tmyklebu那,我的朋友,是endian戰爭是如何開始的。 :) –