為什麼考慮到溢出用減法來比較更好?

閱讀nginx紅黑樹代碼時看到以下一段,在插入節點比較key值時nginx使用了減法作比較並給出了一段注釋,說減法是為了考慮到溢出的情況,我不太明白。

有人能解釋一下嗎?如果能給出具體的例子就更好了,謝謝:)

/*

* Timer values

* 1) are spread in small range, usually several minutes,

* 2) and overflow each 49 days, if milliseconds are stored in 32 bits.

* The comparison takes into account that overflow.

*/

/* node-&>key &< temp-&>key */

p = ((ngx_rbtree_key_int_t) (node-&>key - temp-&>key) &< 0)

? temp-&>left : temp-&>right;


就是bhescaper的意思。。

但是不一定要同步變化 。

就是說,因為我們知道時間間隔是很小的,所以這時候如果發生了溢出(相當於就是循環計算了),還可以保證所謂的a的時間在b的時間之前是正確的。(也就是考慮到一個先溢出了,另一個還沒有溢出的情況)

PS:請注意key應該是unsigned,之後才強轉成int

舉個栗子,如果要直觀感受的話可以找個臨近maxunsignedint和恰好溢出一點點的兩個數字試試:

m就是max unsigned int

a小於b

|a-b|=δ(小於m/2)

a小於m,b大於m

如果直接比較a和b-m(溢出)就會得到,a大於b-m

但是如果比較a-b+m mod m再把最高位標記成符號位,這就會變成負數小於0。

因為δ夠小,這時候我們會知道這個負數不會是因為a離b時間超過m/2(也就是項減之後符號位還是1)導致的。


僅僅是猜測

int a = 2147483647;

int b = 2147483646;

a &> b == true;

a - b &> 0 == true;

++a == -2147483648;

++b == 2147483647;

a &> b == false;

a - b &> 0 == true;

當a和b同步變化時,相減可以抵消溢出。


推薦閱讀:

為什麼中國程序員對待外國人抱怨和對待國人抱怨採取截然不同的態度?
Nginx支持ASP.net嗎?
為什麼mysql,nginx,libev,redis,linux都是用C寫的?
為什麼要執行多個進程,把所有功能都放到一個進程裡面執行會影響性能嗎?

TAG:編程 | C編程語言 | Nginx | 演算法與數據結構 | 紅黑樹 |