關於c語言中負數位移位操作的漫談


近期有個朋友在程序中使用了對16進制數做負數移位(編譯器是gcc),本人最次產生好奇。所以研究了一些。

對一個數做負數位移位的操作是不規范的,可是是可行的。

詳細樣例:
char tmp = 0x10;
tmp = tmp << -1;
大家猜猜結果是什么。有人猜是tmp左移-1位不就是右移1位嗎?結果是0x01?
非常遺憾。電腦和人腦是不一樣的。結果是0
為什么呢?為了找出原因,本人進行了一些小小的測試。並做出了有根據的結果。

因為知道+0和-0的差別,所以,我首先將tmp << -128(-128就是-0),和猜想的一樣。結果是0x10
而-128的二進制是 1000 000b
繼續,將tmp << -127。結果是0x20,左移了1位
-127的二進制是 1000 0001b
迫不及待,嘗試 tmp << -126。結果是0x40,左移了2位
-126的二進制是 1000 0010b
這時,大家應該和我一樣,看出了端倪,可是先不要說出來,先看看他們以相同的值向右移:
首先將tmp >> -128(-128就是-0),結果是0x10
而-128的二進制是 1000 000b
繼續,將tmp >> -127,結果是0x08,右移了1位
-127的二進制是 1000 0001b
迫不及待。嘗試 tmp >> -126。結果是0x04,右移了2位
-126的二進制是 1000 0010b

這時,大家能夠大膽的的推測了,移位操作中若移動的是一個負數,那么移動的位數以這個負數的二進制形式的低七位決定。
若還有猜疑。繼續測試:
tmp << -255 結果為0x20。-255的二進制為0x1 0000 0001b
tmp << -511 結果為0x20, -511的二進制為0x10 0000 0001b
tmp << -1023 結果為0x20,-1023的二進制為0x100 0000 0001b

如今大家能夠肯定的說: 移位操作中若移動的是一個負數。那么移動的位數以這個負數二進制形式的低七位決定。

如今的longlong型長度貌似最大也僅僅有到64位,若要達到128位。這個編譯器就要改動了。)


在寫完本文后,我在工作中不小心發現了不妥。以上的結果不過只代表了有符號char型的移位規則。所以,以上的結論須要進一步的進行拓展。
以下是拓展后的結論:
當一個數為有符號數時。設這個有符號數的二進制位數為k(比方int型在32位系統中,它的二進制位數為32),那么這個數向左或向右移動n位時,這個數僅僅移動這個n數的二進制形式下低k-1位所指代的那個正數位。
當一個數為無符號數時。 設這個有符號數的二進制位數為k(比方int型在32位系統中,它的二進制位數為32),那么這個數向左或向右移動n位時,這個數僅僅移動這個n數的二進制形式下低k位所指代的那個正數位。

因為本人水平有限,如有錯誤,請指正。本人不勝感激。





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM