Python チュートリアル: XOR 演算子 (^)、AND 演算子 (&)、OR 演算子 (|)、逆演算子 (~)、右シフト演算子 (>>)、符号なし右シフト演算子 (>> >)

1. XOR の意味

排他的 OR 演算は、一般的な論理和とは異なります。排他的 OR 演算子の値は、2 つのオペランドの一方の値が真で、もう一方の値が真でない場合にのみ真になります。命題に変換すると、「2 つの値は異なる。」または「存在し、1 つだけが真である。」記号は、XOR または EOR または ⊕ (プログラミング言語で一般的に使用される ^) です。

数学における or の意味: 要素が集合 A または集合 B にある、またはベン図は次のとおりです:
ここに画像の説明を挿入
異なるまたは共存できないため、A ^ B のベン図は次のとおりです:
ここに画像の説明を挿入
については同じA ^ B ^ C ベン図:
ここに画像の説明を挿入
XOR 演算 {\displaystyle A\oplus B}A\oplus B の真理値表は次のとおりです。F は偽、T は真を意味します。

B
T T
T T
T T
B
0 0 0
1 1 1
1 0 1
1 1 0

任意の数値 XOR 自体 = 自身を 0 に設定

2. XOR の性質: 交換法則と結合法則を満たす

  • 交換法則: A ^ B = B ^ A;
  • 結合性: A ^ (B ^ C) = (A ^ B) ^ C;
  • 同一性法則: X^0 = X;
  • ゼロ法に戻る: X ^ X = 0;
  • 自反:A ^ B ^ B = A ^ 0 = A;
  • 任意の X: X ^ (-1) = ~X;
  • A ^ B = C が成立する場合、A ^ B = C、B ^ C = A;

3. XOR 適用

1001個の要素を含む配列に1から1000を配置し、1つの要素だけが繰り返され、繰り返される数を見つけます。補助記憶領域を使用できず、配列の各要素に一度しかアクセスできないことが必要です。

  • 解決策 1: これらの 1001 個の要素の合計から 1+2+...+1000 を引くと、結果の値が繰り返されます (データが大きすぎるとオーバーフローしやすくなります)。

  • 解決策 2: XOR

すべての 1001 の数値を XOR して得られた値は、過剰なデータ オーバーフローの状況を回避するために、12...^1000 の結果と再び XOR されます。

まず、XOR 演算は交換法則と結合法則、つまり a^b = ba, (ab)^c = a(bc) を満たします。繰り返される数を n とします。

つまり 1 ^ 2 ^ ... ^ n ^ n ^ ... ^ 1000 = 1 ^ 2 ^ ... ^ 1000 ^ (n ^ n) = 1 ^ 2 ^ ... ^ 1000 ^ 0 = 1 ^ 2 ^ ... ^ 1000 (つまり、繰り返し数 n を除くすべての数の排他的論理和のシーケンスで。

1 ^ 2 ^ ... ^ 1000 (数列に n は含まれない) の結果を T とすると、1 ^ 2 ^ ... ^ 1000 (n は数列に含まれる) の結果は T^n 、T ^ (T ^ n) = n。
変形:配列にはいくつかの整数が格納されており、1 つの数字が奇数回出現し、残りの数字が偶数回出現する場合、奇数回出現する数字を見つけます。

解決策は、上記の解決策 2 と同じです。
2 つの数値が等しいかどうかをすばやく比較する

a == b a^b == 0

メモリを追加せずに 2 つの数値の値を交換する

a ^= b;

b ^= a;

a ^= b;

チェックと復元、RAID5

チェックサム回復は主に XOR 機能を使用します: IF a ^ b = c THEN a ^ c = b 、データは2つの部分に分割されてディスクAとディスクBにそれぞれ書き込まれ、A ^ Bの結果はディスクCに書き込まれ、Aのデータが読み取られると、AのデータはB ^ Cを介して処理できますAディスクに障害が発生した場合、AディスクのデータもB ^ Cを介して回復できることを確認してください.
XOR を使用して特定のビットを反転する

10100001 の 6 番目のビットを反転します。答え: この数値と 00100000 に対してビット単位の XOR 演算を実行できます; 10100001 ^ 00100000 =
10000001

たとえば、{1, 2, 3, 4, 5, 3, 2, 4, 5} から 1 つの数値を検索するには: 1

1^2^3^4^5^3^2^4^5 = 1

上記のXOR演算の特徴により、以下のような使い方ができ、便利で直感的な操作性に加え、演算性能も優れています。
変数を 0 にリセット

変数 15 があるとします。バイナリ表現は 0000 1111 です。

0000 1111 ^ 0000 1111 = 0000 0000

a = 0000 1111

a = a ^ a

結論: 変数自体との XOR 演算により、変数が 0 にリセットされる可能性があります。
指定位置を反転

変数 15 があり、バイナリ表現が 0000 1111 で、3 番目、4 番目、8 番目のビットが逆になっているとします。

0000 1111 ^ 1000 1100 = 1000 0011

結論:指定した反転ビットが1で、それ以外のビットが0の変数をXOR演算することで、指定した位置を反転させることができます。

反転後の結果は、元の指定された反転変数と XOR され、変数を復元できます。

1000 0011 ^ 1000 1100 = 0000 111115

暗号化と復号化

変数 15 があり、バイナリ表現が 0000 1111 で、コドンが 0101 0101 であるとします。

暗号化: 0000 1111 ^ 0101 0101 = 0101 1010

暗号化後の結果は 90 です。

暗号化された結果と復号化するコドンの XOR

0101 1010 ^ 0101 0101 = 0000 1111

復号化後の結果は 15 です。

バイナリー交換

a = 15 (0000 1111)、b = 23 (0001 0111) という 2 つの変数があるとします。2 つの変数を交換します。

1、a = a ^ b = 0000 1111 ^ 0001 0111 = 0001 1000

2、b = b ^ a = 0001 0111 ^ 0001 1000 = 0000 1111(15)

3、a = a ^ b = 0001 1000 ^ 0000 1111 = 0001 0111(23)

結論: バイナリ交換は、実際には暗号化と復号化の特性を利用しています。

1. a と b の XOR。結果 x は、a と b が相互にコドンとして暗号化されていると見なすことができます。

2. x を b (元の値) と XOR します。つまり、b をコドンとして使用し、a を復元して b に割り当てることができます。

3. x と b (この時点では a) の XOR、つまりコドンとして b (この時点では a) を使用するため、復元された値は元の b であり、a に割り当てられます。交換終了です。

2 つの値が等しいかどうかを確認する

変数自体で XOR 演算を使用すると、変数を 0 にリセットできます。

  • 仮定: a = 0000 1111、b = 0000 1111、その後 a ^ b == 0

  • 仮定: a = 0000 1111、b = 0000 0001、a^b != 0

結論: 2 つの変数が等しい場合、XOR の結果は 0 です。

4. ビット AND 演算子 (&)

演算に含まれる 2 つのデータは、2 進数に従って「AND」演算が実行されます。

演算規則: 0&0=0; 0&1=0; 1&0=0; 1&1=1;

つまり、2 つのビットが同時に「1」の場合、結果は「1」になり、それ以外の場合は 0 になります。

例: 3&5 は 0000 0011& 0000 0101 = 00000001 したがって、3&5 の値は 1 です。

さらに、負の数は、補数コードの形式でビットごとの AND 演算に参加します。

AND 演算の特別な用途:

(1)クリアした。セルをクリアしたい場合、そのバイナリ ビットがすべて 0 であっても、ビットがすべてゼロの値と AND を実行すると、結果はゼロになります。

(2) 数値の指定ビットを取る

方法: X が取得するビットに対応する数値を見つけます。数値の対応するビットは 1 で、残りのビットは 0 です。数値と X を「AND」して、X の指定されたビットを取得できます。 .

例: X=10101110 とします。

X の下位 4 ビットを取得し、X & 0000 1111 = 00001110 を使用して取得します。

また、X の 2、4、および 6 ビットを取得するためにも使用できます。

5. ビット OR 演算子 (|)

演算に関与する 2 つのオブジェクトに対して、バイナリ ビットに従って「or」演算が実行されます。

操作規則: 0|0=0; 0|1=1; 1|0=1; 1|1=1;

つまり、操作に参加している 2 つのオブジェクトのいずれかが 1 である限り、その値は 1 です。

例: 3|5 is 00000011 | 0000 0101 = 00000111 したがって、3|5 は 7 の価値があります。

さらに、負の数は補数形式でビットごとの OR 演算に参加します。

「OR」特殊機能:

(1) データの特定の位置を 1 に設定するためによく使用されます。

方法: 1 に設定される X のビットに対応する数を見つけます。その数の対応するビットは 1 で、残りのビットは 0 です。この数値は X に相当するか、X の特定のビットを 1 に設定できます。

例: X=10100000 の下位 4 ビットを 1 に設定し、X | 0000 1111 = 1010 1111 を使用して取得します。

6. 否定演算子 (~)

操作に関与するデータは、バイナリ ビットに従って「反転」されます。

操作規則: ~1=0; ~0=1;

つまり、2 進数をビットごとに反転すること、つまり、0 を 1 に、1 を 0 に変更することです。

数値の最下位ビットをゼロにするには、a&~1 のように表すことができます。

1の値は111111111111110で、「AND」操作を押すと、最下位ビットは0でなければなりません。"" 演算子は、算術演算子、関係演算子、論理演算子、およびその他の演算子よりも優先順位が高いためです。

左シフト演算子 (<<) は、
オペランドのすべてのバイナリ ビットを数ビット左にシフトします (左側のバイナリ ビットは破棄され、右側に 0 が追加されます)。

例: a = a<< 2 は、a のバイナリ ビットを左に 2 ビット シフトし、右を 0 で埋めます。

1 ビット左シフト後 a = a *2;

左にシフトするときに破棄される上位ビットに 1 が含まれていない場合、左にシフトされる各ビットは、数値を 2 倍することと同じです。

7. 右シフト演算子 (>>)

数値のすべての 2 進数は数ビット右にシフトされ、正の数値は左側に 0 で埋められ、負の数値は左側に 1 で埋められ、右側は破棄されます。

オペランドの各右シフトは、数値を 2 で除算することと同じです。

例: a = a>> 2 a のバイナリ ビットを 2 ビット右にシフトし、

0 の左補数または 1 の補数は、シフトされた数値が正か負かによって異なります。

この演算子は、expression2 で指定されたビット数だけ、expression1 のすべてのビットを右にシフトします。式 1 の符号ビットは、右シフト後に左の空きビットを埋めるために使用されます。右にシフトアウトされたビットは破棄されます。

たとえば、次のコードが評価されると、temp の値は -4 になります。

-14 (つまり、2 進数で 11110010) を 2 ビット右にシフトすると、-4 (つまり、2 進数で 11111100) に等しくなります。

var temp = -14 >> 2

符号なし右シフト演算子 (>>>)

        运算符把 expression1 的各个位向右移expression2 指定的位数。右移后左边空出的位用零来填充。移出右边的位被丢弃。

例: var temp = -14 >>> 2

変数 temp の値は -14 (つまり、2 進数で 11111111 11111111 1111111111110010) で、右に 2 桁シフトすると 1073741820 (つまり、2 進数で 00111111 11111111 111111111111100) になります。

8. 複合代入演算子

ビット単位の演算子を代入演算子と組み合わせて、次のような新しい複合代入演算子を形成します。

&= 例: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 つのデータがビット操作の対象となる場合、システムはそれらを右に揃えてからビット操作を実行します。

C言語ではlong型が4バイト、int型が2バイトを占めることが知られていますが、long型のデータに対してAND演算を行うと、 int 型データ、右端揃え 最後に、左端の不足位置を以下の 3 つの状況に応じて補います。

(1) 整数データが​​正数の場合、左側に 0 を 16 個追加します。

(2) 整数データが​​負の場合、左に 16 個の 1 を追加します。

(3) 整数データが​​符号なしの数値の場合、左側に 0 が 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 を計算します。

おすすめ

転載: blog.csdn.net/Python_222/article/details/128919921