查找浮點數的絕對值的算法,超過here。 這是如何工作的?fabs()的這個實現是如何工作的?
//find absolute value
double x;
*(((int *) &x) + 1) &= 0x7fffffff;
我不明白爲什麼1偏移是必要的。它說:
IA32 64位符號位是0x80000000在int地址偏移+1。
有人可以解決這個問題嗎?
查找浮點數的絕對值的算法,超過here。 這是如何工作的?fabs()的這個實現是如何工作的?
//find absolute value
double x;
*(((int *) &x) + 1) &= 0x7fffffff;
我不明白爲什麼1偏移是必要的。它說:
IA32 64位符號位是0x80000000在int地址偏移+1。
有人可以解決這個問題嗎?
該代碼在技術上無效C,因爲它打破了嚴格的別名規則。但是,如果你告訴你的編譯器不濫用別名規則,你就保證double
S和int
s的佈局在內存中,因爲它們是在x86:
(int *)&x
是指向x
。添加1將指針向前移動4個字節。取消引用會爲您提供double
的第4至第7個字節。你掩蓋了這個高位,因爲這是double
的最後一個字節。
順便提一句,您可以通過使用char *
並添加7而不是1來阻止這種情況出現鋸齒違規。它仍然是非常不可移植的。
很好的答案。你似乎很熟悉。 – nneonneo
's/abuse/use /'... –
並且隨着你對'char'的修改,我會說它只是*非常輕便*不可移植而不是非常可怕。真正唯一不可移植的方面是字節序假設。假設'double'是以IEEE格式存儲的IEEE雙精度是一個相當合理的假設。 –
這是高度依賴於平臺的。
無論如何,你有雙倍的最高位是符號位。
如果你的double有8個字節,而你的int有4個字節,並且你在LE系統上,那麼最高位是最後一個字節的最高位,或者是第二個整數。
所以你取第二個整數(你可以寫((int *)&x)[1] &= 0x7fffffff
)並清除它的最高位。
double
一個是8個字節寬,並且具有以下的格式:
您顯示該代碼假定int
是4個字節寬,並且這兩個int
和double
是little-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
到其絕對值。
你應該真的從左到右翻轉那個圖像。 :) – tmyklebu
@tmyklebu那,我的朋友,是endian戰爭是如何開始的。 :) –
「有人可以解決這個問題並解釋嗎?」 - 也許你可以嘗試解釋一下? –
@MitchWheat:也許你可以少一點判斷力。 OP的問題顯然是措辭,甚至解釋了特定的困惑點:抵消1. –
@R:我問了一個有禮貌和合理的問題。你的牛肉是什麼? –