ガイド | 最新のコンピューターからのすべてのデータは、バイナリ形式でデバイスに保存されます。つまり、0と1の2つの状態で、コンピューターがバイナリデータに対して実行する計算(+、-、*、/)はすべてビット演算と呼ばれます。つまり、符号ビットが計算に関与します。 |
1.ビット演算の概要
最新のコンピューターからのすべてのデータは、バイナリ形式でデバイスに保存されます。つまり、0と1の2つの状態で、コンピューターがバイナリデータに対して実行する計算(+、-、*、/)はすべてビット演算と呼ばれます。つまり、符号ビットが計算に関与します。
言う理由はありません。次のコード行のように、CPUが計算を実行する方法を確認するための簡単な例を見てみましょう。
int a = 35;
int b = 47;
int c = a + b;
2つの数値の合計を計算します。コンピューターはすべて2進数で操作されるため、上記で指定したint変数は、追加される前にマシンで2進数に変換されます。
35: 0 0 1 0 0 0 1 1
47: 0 0 1 0 1 1 1 1
————————————————————
82: 0 1 0 1 0 0 1 0
したがって、コードで(+、-、*、/)演算子を直接使用する場合と比較して、ビット演算を適切に使用すると、マシンでのコードの実行効率を大幅に向上させることができます。
2.ビット演算の概要
シンボル | 説明 | アルゴリズム |
---|---|---|
& | 対 | 両方のビットが1の場合、結果は1になります。 |
| | または | 両方のビットが0の場合、結果は0になります。 |
^ | XOR | 同じ2ビットは0で、差は1です。 |
〜 | ネゲート | 0は1になり、1は0になります |
<< | 左にシフト | すべてのバイナリビットは数ビット左にシフトされ、上位ビットは破棄され、下位ビットは0で埋められます。 |
>> | 右シフト | すべての2進ビットは数ビット右にシフトされます。符号なし数値、ゼロの上位ビット、および符号付き数値の場合、各コンパイラの処理方法は異なります。符号ビットを補完するもの(右シフト)と0を補完するもの(算術右シフト)があります。論理右シフト) |
3.ビットごとのAND演算子(&)#
定義:操作に関与する2つのデータは、バイナリビットでAND演算されます。
運用ルール:
0&0=0 0&1=0 1&0=0 1&1=1
概要:両方のビットが同時に1の場合、結果は1になります。それ以外の場合、結果は0になります。
例:3&5は0000 0011&0000 0101 = 0000 0001を意味するため、3&5の値は1です。
注:負の数は、補数の形でビット単位のAND演算に参加します。
AND操作の目的:
1)クリア
ユニットをクリアしたい場合、そのすべてのバイナリビットが0であっても、ビットがすべてゼロの値とAND演算されている限り、結果はゼロになります。
2)番号の指定された場所を取る
たとえば、数値X = 1010 1110の下位4ビットを取得するには、別の数値Yを見つけ、Yの下位4ビットを1に設定し、残りのビットを0に設定するだけです。つまり、Y = 00001111です。 、次にXとYのビットごとのAND演算を実行します(X&Y = 0000 1110)指定されたXの位置を取得できます。
3)パリティを決定します
最下位ビットが0であるか1であるかに基づいて決定される限り、0は偶数であり、1は奇数です。したがって、if(a%2 == 0)の代わりにif((a&1)== 0)を使用して、aが偶数かどうかを判断できます。
4.ビットごとのOR演算子(|)
定義:操作に参加している2つのオブジェクトは、バイナリビットに従って「または」操作の対象になります。
運用ルール:
0|0=0 0|1=1 1|0=1 1|1=1
概要:操作に参加している2つのオブジェクトの1つが1である限り、その値は1です。
例:3 | 5は00000011 | 0000 0101 = 0000 0111であるため、3 | 5の値は7です。
注:負の数は、補数の形でビット単位のOR演算に参加します。
OR演算の目的:
1)データの一部のビットを1に設定するためによく使用されます
たとえば、数値X = 1010 1110の下位4ビットを1に設定した場合、別の数値Yを見つけるだけで、Yの下位4ビットを1に設定し、残りのビットを0、つまりYに設定するだけで済みます。 = 0000 1111、次にXとYを押します。ビットOR演算(X | Y = 1010 1111)を取得できます。
5. XOR演算子(^)
定義:演算に関与する2つのデータは、バイナリビットに従って「排他的論理和」演算の対象になります。
運用ルール:
0^0=0 0^1=1 1^0=1 1^1=0
概要:計算に参加している2つのオブジェクトの場合、対応する2つのビットが同じであれば、それは0であり、差は1です。
XORのいくつかのプロパティ:
- 可換法
- 結合法則(a ^ b)^ c == a ^(b ^ c)
- 任意の数xについて、x ^ x = 0、x ^ 0 = x
- 自反性: a^b^b=a^0=a;
排他的論理和演算の目的:
1)指定されたビットを反転します
たとえば、数値X = 1010 1110の下位4ビットを反転するには、別の数値Yを見つけ、Yの下位4ビットを1に設定し、残りのビットを0に設定するだけです。つまり、Y = 00001111です。 、次にXとYをXORして計算します(X ^ Y = 1010 0001)。
2)0のXORの値は変更されません
例:1010 1110 ^ 0000 0000 = 1010 1110
3)2つの番号を交換します
インスタンス
void Swap(int &a, int &b){
if (a != b){
a ^= b;
b ^= a;
a ^= b;
}
}
6.否定演算子(〜)
定義:計算に関与するデータは、バイナリで「反転」されます。
運用ルール:
~1=0
~0=1
概要:2進数をビットごとに反転します。つまり、0が1になり、1が0になります。
排他的論理和演算の目的:
1)数値の最下位ビットをゼロにする
aの最下位ビットを0とします。これは、a&〜1として表すことができます。〜1の値は1111 1111 1111 1110であり、「AND」操作を押すと、最下位ビットは0でなければなりません。「〜」演算子は、算術演算子、関係演算子、論理演算子、およびその他の演算子よりも優先されるためです。
7.左シフト演算子(<<)定義:オペランドのすべてのバイナリビットを数ビット左にシフトします(左側のバイナリビットは破棄され、右側は0で埋められます)。a = 1010 1110、a = a << 2 aの2進数を2ビット左にシフトし、右に0を追加します。つまり、a = 10111000です。左シフト時に破棄される上位ビットに1が含まれていない場合、各左シフトは数値に2を掛けることに相当します。8.右シフト演算子(>>)
定義:数値のすべての2進数を数ビット右にシフトし、正の数の場合は左に0を追加し、負の数の場合は左に1を追加し、右を破棄します。
次に例を示します。a= a >> 2シフトされた数値が正か負かに応じて、aの2進ビットを右に2桁シフトし、左に0を追加するか、左に1を追加します。
オペランドを1ビット右にシフトすることは、数値を2で除算することと同じです。
10.複合代入演算子
ビット単位の演算子は、代入演算子と組み合わされて、新しい複合代入演算子を形成します。
&= 例:a&=b 相当于 a=a&b
|= 例:a|=b 相当于 a=a|b
>>= 例:a>>=b 相当于 a=a>>b
<<= 例:a<<=b 相当于 a=a<<b
^= 例:a^=b 相当于 a=a^b
操作規則:前述の複合代入演算子の操作規則と同様です。
異なる長さのデータがビット演算の対象となる:異なる長さの2つのデータがビット演算の対象となる場合、システムは2つを右に揃えてから、ビット演算を実行します。
「AND演算」を例にとると、次のように説明できます。C言語では、long型が4バイト、int型が2バイトを占めることがわかっています。long型データとint型データが「AND」の場合、その後、左端の不足ビットは、以下の3つの状況で補われます。
- 整数データが正の場合は、左側に16個のゼロを追加します。
- 整数データが負の場合は、左側に16個追加します。
- シェーピングデータが符号なしの数値の場合は、左側に16個のゼロを追加します。
例:long a = 123; int b = 1; a&bを計算します。
例:long a = 123; int b = -1; a&bを計算します。
例:long a = 123; unsigned intb = 1; a&bを計算します。Linuxはこのように学ぶ必要があります