C:ビット演算の左シフト演算と右シフト演算

5492 ワード

C:ビット演算の左シフト演算(<>)
Cでは、ビット演算には2つのシフト演算が含まれます.
左シフト演算:<<
右シフト演算:>>
左右シフト演算は,数値が符号なしと符号がある場合に異なる挙動を有する.
符号付き左右変位演算
#include 
#include 
#include 

// signed int  
void si_left_shift(signed int si, int n)
{
    printf("%08X << %d: %08X
"
, si, 4, si << n); } // signed int void si_right_shift(signed int si, int n) { printf("%08X >> %d: %08X
"
, 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:ここでは一度に4 bitシフトして、結果の出力を観察しやすいようにしていますが、4の倍数でなければ計算する必要があります.なぜですか?)
符号なし左右変位演算
#include 
#include 
#include 

// unsigned int  
void ui_left_shift(unsigned int ui, int n)
{
    printf("%08X << %d: %08X
"
, ui, 4, ui << n); } // unsigned int void ui_right_shift(unsigned int ui, int n) { printf("%08X >> %d: %08X
"
, 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を補う.