2013-04-26 82 views
3

我正在閱讀https://github.com/antirez/redis的redis源代碼。爲什麼不使用VAL的補碼而不是(-VAL -1)

我看到了這樣的宏在SRC/ziplist.c

#define INT24_MAX 0x7fffff 

#define INT24_MIN (-INT24_MAX - 1) 

爲什麼不這樣做呢?

#define INT24_MIN (~INT24_MAX) 
+1

'〜'會給你警告,它可能會改變符號'操作符操作值提升爲int(可能意外的結果)' – 2013-04-26 05:29:01

+1

閱讀本文[C不是操作符爲什麼會收到警告](http:// stackoverflow.com/questions/15838249/c-not-operator-why-do-i-get-a-warning)可能會對您有所幫助 – 2013-04-26 05:35:58

+0

即使添加-Wall和gcc4.8,我也無法重現警告。它與編譯器相關嗎? – ArkChar 2013-04-26 05:44:41

回答

5

更好的問題可能是您爲什麼認爲(~INT24_MAX)好於(-INT24_MAX - 1)

在二進制補碼機上,您從兩個表達式中獲得相同的結果,並且它們的計算速度與其他計算速度一樣快(對於32位目標,編譯器會在編譯時將它們都減少到0xff800000 )。然而,在我看來,表達式(-INT24_MAX - 1)對數值概念進行了建模,即最小值比最大值的否定更好一個。

這可能沒有太大的重要性,但表達式(~INT24_MAX)不是更好的客觀方式,我會主張它可能不會那麼好。

基本上,(-INT24_MAX - 1)可能是編碼器碰巧想到的(也許因爲正如我提到的那樣,它模擬了數字意圖),並且沒有理由使用別的東西。

+0

啊,我明白了。當我第一次看到這個時,我正在考慮補充代碼,甚至對它被命名爲「MIN」的原因感到困惑。謝謝! – ArkChar 2013-04-26 07:57:49

5

假設,int爲32位,可容納0x7fffff,則~0x7fffff將是~0x007fffff或所有位被反轉後,0xff800000

如果負整數使用2的補碼錶示形式,則該位模式表示負值-0x7fffff-1

如果他們使用1的補碼錶示,那麼這個模式代表負值-0x7fffff

如果它們使用符號幅度表示,則該模式表示取值-0x7f800000

如您所見,~0x7fffff的值將取決於負整數的表示形式和可容納值0x7fffff的類型的大小。

如果你想編寫可移植的C代碼,你應該避免這種情況。

相關問題