C++におけるビット演算のまとめ

3004 ワード

1)ビット演算
ビット演算とは、バイナリに変換された数字を各ビットで0、1の演算を行い、演算には5つの演算が含まれます:(&)、または(|)、異或(^)、左シフト(<)、右シフト(>>).
次の表に示します.
 
と(&)
0 & 0 =0
1 & 0 = 0
0 & 1 = 1
1 & 1 = 1
または(|)
0 | 0 = 0
1 | 0 = 1
0 | 1 = 1
1 | 1 = 1
異或(^)
0 ^ 0 = 0
1 ^ 0 = 1
0 ^ 1 = 1
1 ^ 1 =0
左シフト(<)
0001 1001 << 2 = 0110 0100 1000 1010 << 3 = 0101 0000
右に移動(>>>)
0000 1010 >> 2 =  0000 0010 1000 1010 >> 3 = 1111 0001
左に移動:
左シフト演算子m<右に移動:
右シフト演算子m>>nは、mをnビット右シフトすることを表す.nビットを右にシフトすると、一番右のnビットは破棄されます.しかし、左シフトとは異なり、右シフト時の一番左のnビット処理:数字が符号なしの数値であれば、0で一番左のnビットを埋める.数字が記号付きの数値である場合、左のnビットを数字の記号ビットで埋めます.上記の表の:1000,1010>>3=1111,0001です.
この5つの演算子はいずれも両目オペレータであり,もう1つの単目オペレータ~は逆を表す.すなわち,~1=0,~0=1である.
ビット演算子は整数データにのみ使用でき、他のタイプのデータに対してビット操作コンパイラがエラーを報告します.
ビット演算子の優先度は低いので、演算順序を保証するためにカッコをできるだけ使用します.
2.ビット演算子の一般的なテクニック
1)判断パリティ
整数のパリティは,最下位が0であるか1であるかによって判断できる.例えば整数nはif((n&1)==0)で判断でき,if(n%2==0)で判断するよりもパリティ効率が高い.
2)データ交換
void swap(int &a, int &b)
{
    if (a != b)
    {
        a ^= b;//a=(a^b);

        b ^= a;//^       ,b^(a^b)=b^b^a

        a ^= b;//a=(a^b)^a
    }
}

1つの数と自分の異和の結果が0であり、任意の数と0の異和は変わらないため、第2のステップではb^=aはb=b^b^a=aに等価であり、すなわちbはaの値を付与される.
3)変換記号
正の整数は負の整数、負の整数は正の整数となり、元の数のバイナリを逆にして1を足すだけです.例:
-11と11については、次の変換方法で-11を11に変更することができる.
1111 0101(バイナリ)逆->0000 1010(バイナリ)プラス1->0000 1011(バイナリ)
同じように11を-11に変えることができます
0000 1011(バイナリ)取反->0000 0100(バイナリ)プラス1->1111 0101(バイナリ)
3.ビット演算応用
1)段差交換
16ビットの符号なし整数を与えます.この2進数の上位8位を「高位」、下位8位を「低位」と呼ぶ.今、プログラムを書いて、その高低を交換します.例えば、数34520は、バイナリで表される.
      10000110 11011000
その高低位を交換し,新しいバイナリ数を得た.
      11011000 10000110
それは十進法の55430です.
この問題はビット操作で解決するのが非常に便利で、x=34520=10000010111011000(バイナリ)とすると、xは符号数がないため、右シフト時に論理右シフトすなわち高位補0が実行されるため、x右シフト8ビットは10000000 100000110を得ることになる.xが8ビット左に移動すると11000億円が得られる.x>>8とx<<8の2つの数相を有するか、または110110001000000110が得られることが分かった.
2)1つの整数が2であるか否かを判断する整数次数
整数が2の整数次数である場合、そのバイナリ識別には必ず1ビットのみが1であり、他のすべてのビットは0である.
ソリューション:
この整数を1から減算してから自分と演算すると、この整数の中で唯一の1が0になります.だから0に等しいかどうかを判断すればいい.