C:位運算之 左移運算和右移運算
阿新 • • 發佈:2019-01-03
C:位運算之 左移運算(<<)和右移運算(>>)
在C中,位運算包含兩種移位運算:
左移運算:<<
右移運算:>>
左右位移運算,在數值為無符號和有符號情況下具有不同行為。
有符號左右位移運算
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// signed int左移
void si_left_shift(signed int si, int n)
{
printf("%08X << %d: %08X\n" , si, 4, si << n);
}
// signed int右移
void si_right_shift(signed int si, int n)
{
printf("%08X >> %d: %08X\n", si, 4, si >> n);
}
int main()
{
// positive signed int
signed int psi = 0x12345678;
si_left_shift(psi, 4);
si_right_shift(psi, 4);
// negative signed int
signed int nsi = 0xFEDCBA98;
si_left_shift(nsi, 4);
si_right_shift(nsi, 4);
exit(0);
}
編譯 && 執行:
$ gcc -o shift shift.c
$ ./shift
12345678 << 4: 23456780
12345678 >> 4: 01234567
FEDCBA98 << 4: EDCBA980
FEDCBA98 >> 4: FFEDCBA9
對於有符號數:
如果數值非負,左移直接丟棄最高位,在低位補對應個數的0;
如果數值非負,右移直接丟棄最低位,在高位補對應個數的0;
如果數值為負,左移直接丟棄最高位,在低位補對應個數的0;
如果數值為負,右移直接丟棄最低位,在高位補對應個數的1
請特別注意,有符號數值右移,高位補的總是原來的符號位值。
(PS:這裡一次性移位4bit,僅為方便觀察結果輸出,若非4的倍數,還需進行計算,想想為什麼?)
無符號左右位移運算
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// unsigned int左移
void ui_left_shift(unsigned int ui, int n)
{
printf("%08X << %d: %08X\n", ui, 4, ui << n);
}
// unsigned int右移
void ui_right_shift(unsigned int ui, int n)
{
printf("%08X >> %d: %08X\n", ui, 4, ui >> n);
}
int main()
{
unsigned int ui1 = 0x12345678;
ui_left_shift(ui1, 4);
ui_right_shift(ui1, 4);
unsigned int ui2 = 0xFEDCBA98;
ui_left_shift(ui2, 4);
ui_right_shift(ui2, 4);
exit(0);
}
編譯 && 執行:
$ gcc -o shift shift.c
$ ./shift
12345678 << 4: 23456780
12345678 >> 4: 01234567
FEDCBA98 << 4: EDCBA980
FEDCBA98 >> 4: 0FEDCBA9
對於無符號數:
左移直接丟棄最高位,在低位補對應個數的0;
右移直接丟棄最低位,在高位補對應個數的0,即使最高位原來是1;
請特別注意,對於無符號數,不存在正負之分,只有最高位是否為1的區別。
通過對比無符號和有符號數的左右位移結果,我們可知:
1.對於無符號數,不論最高位是否為1,當右移時,高位總是補0;
2.對於有符號數,當右移時,高位總是按位移前最高位值補齊,即,真實的數值符號總是不變的;
3.左移時,不論是否有符號,都丟棄最高位,低位補對應個數的0;