C:ビット演算の左シフト演算と右シフト演算
C:ビット演算の左シフト演算(<>)
Cでは、ビット演算には2つのシフト演算が含まれます.
左シフト演算:<<
右シフト演算:>>
左右シフト演算は,数値が符号なしと符号がある場合に異なる挙動を有する.
符号付き左右変位演算
コンパイル&実行:
シンボル数:
数値が負でない場合、左シフトは直接最高位を捨て、低位で対応個数の0を補う.数値が負でない場合、右シフトは直接最低位を捨て、高位で対応個数の0を補う.数値が負の場合、左シフトは最高位を直接捨て、低位で対応個数の0を補う.数値が負の場合、右シフトは直接最低位を捨て、高位で対応個数の1を補う.
特に注意してください.記号の数値が右にシフトし、高位補正は常に元の記号ビット値です.
(PS:ここでは一度に4 bitシフトして、結果の出力を観察しやすいようにしていますが、4の倍数でなければ計算する必要があります.なぜですか?)
符号なし左右変位演算
コンパイル&実行:
符号なしの場合:
左シフトは最高位を直接捨て、低位で対応個数の0を補う.右シフトは直接最低位を捨てて、高位で対応個数の0を補って、最高位がもとは1であっても;
特に、符号数なしでは正負の区別はなく、最高位が1であるかどうかの違いのみに注意してください.
符号なしと符号数のある左右の変位結果を比較することにより,
1.符号のない数については、最高位が1であるかどうかにかかわらず、右に移動すると、高位は常に0を補う.2.符号数がある場合、右にシフトすると、高位は常にシフト前の最高ビット値で補正され、すなわち、真の数値記号は常に変化しない.3.左シフトの場合、符号があるかどうかにかかわらず、最上位を捨て、下位は対応個数の0を補う.
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を補う.