サーチ…


前書き

ビット単位の操作は、ビットレベルでバイナリ文字列を変更します。これらの操作は非常に基本的であり、プロセッサーによって直接サポートされています。これらの操作は、デバイスドライバ、低レベルのグラフィックス、暗号化、およびネットワーク通信の操作に必要です。この節では、Pythonのビット演算子に関する有益な知識と例を提供します。

構文

  • x << y#ビット単位の左シフト

  • x >> y#ビット単位の右シフト

  • x&y#ビット単位のAND

  • x | y#ビットOR

  • 〜x#Bitwise NOT

  • x ^ y#ビット単位のXOR

ビット単位AND

&演算子はバイナリANDを実行し、 両方のオペランドにビットが存在する場合、そのビットがコピーされます。つまり、

# 0 & 0 = 0
# 0 & 1 = 0
# 1 & 0 = 0
# 1 & 1 = 1

# 60 = 0b111100
# 30 = 0b011110
60 & 30
# Out: 28
# 28 = 0b11100

bin(60 & 30)
# Out: 0b11100

ビット単位OR

|演算子はバイナリ "or"を実行します。この場合、どちらのオペランドにもビットがコピーされます。つまり、

# 0 | 0 = 0
# 0 | 1 = 1 
# 1 | 0 = 1
# 1 | 1 = 1

# 60 = 0b111100 
# 30 = 0b011110
60 | 30
# Out: 62
# 62 = 0b111110

bin(60 | 30)
# Out: 0b111110

ビット単位の排他的論理和(排他的論理和)

^演算子は、バイナリ1がコピーされるバイナリXORを実行します。バイナリ1は、それがちょうど1つのオペランドの値である場合にのみコピーされます。これを示す別の方法は、オペランドが異なる場合にのみ結果が1なることです。例としては、

# 0 ^ 0 = 0
# 0 ^ 1 = 1
# 1 ^ 0 = 1
# 1 ^ 1 = 0

# 60 = 0b111100
# 30 = 0b011110
60 ^ 30
# Out: 34
# 34 = 0b100010

bin(60 ^ 30)
# Out: 0b100010

ビット単位の左シフト

<<演算子は、左のオペランドの値が右のオペランドによって与えられたビット数だけ左に移動するビット単位の「左シフト」を実行します。

# 2 = 0b10
2 << 2
# Out: 8
# 8 = 0b1000

bin(2 << 2)
# Out: 0b1000

1左ビットシフトを実行することは、 2を乗算することと等価である。

7 << 1
# Out: 14

n左ビットシフトを実行することは、 2**nによる乗算と等価である。

3 << 4
# Out: 48

ビット単位の右シフト

>>演算子は、ビットごとの "右シフト"を実行します。ここで、左のオペランドの値は、右のオペランドによって与えられたビット数だけ右に移動します。

# 8 = 0b1000
8 >> 2
# Out: 2
# 2 = 0b10

bin(8 >> 2)
# Out: 0b10

1右ビットシフトを実行することは、 2による整数除算に相当します。

36 >> 1
# Out: 18

15 >> 1
# Out: 7

n右ビットシフトを実行することは、整数除算を2**nと等価にします。

48 >> 4
# Out: 3

59 >> 3
# Out: 7

ビット単位NOT

~演算子は、数値のすべてのビットを反転します。コンピュータは符号付き数値表現を使用しているため、負の2進数を符号化する2の補数表記を使用します。この場合、負の数値は先行ゼロ(0)ではなく先頭の1になります。

これは、8ビットを使用して2の補数を表す場合、 0000 0000から0111 1111までのパターンを0から127までの数字を表すように扱い、 1xxx xxxxは負の数を表すように予約することを意味します。

8ビットの2の補数

ビット符号なし値 2の補数の値
0000 0000 0 0
0000 0001 1 1
0000 0010 2 2
0111 1110 126 126
0111 1111 127 127
1000 0000 128 -128
1000 0001 129 -127
1000 0010 130 -126
1111 1110 254 -2
1111 1111 255 -1

これは、本質的に、 1010 0110(128 * 1) + (64 * 0) + (32 * 1) + (16 * 0) + (8 * 0) + (4 * 1) + (2 * 1) + (1 * 0) (128 * 1) - (64 * 0) - (32 * 1) - (16 * 0) - (8 * 0) - (4 * 1) - (2 * 1) - (1 * 0) (128 * 1) + (64 * 0) + (32 * 1) + (16 * 0) + (8 * 0) + (4 * 1) + (2 * 1) + (1 * 0) )の2の補数の値を持つ(128 * 1) - (64 * 0) - (32 * 1) - (16 * 0) - (8 * 0) - (4 * 1) - (2 * 1) - (1 * 0)

このようにして、負の数は-128( 1000 0000 )になります。ゼロ(0)は0000 0000 、マイナス1(-1)は1111 1111と表されます。

しかし一般的に、これは~n = -n - 1意味します。

# 0 = 0b0000 0000
~0
# Out: -1
# -1 = 0b1111 1111
    
# 1 = 0b0000 0001
~1
# Out: -2
# -2 = 1111 1110

# 2 = 0b0000 0010
~2
# Out: -3
# -3 = 0b1111 1101

# 123 = 0b0111 1011
~123
# Out: -124
# -124 = 0b1000 0100

要約することができ、正の数に適用されたときに、この操作の全体的な影響に注意してください

~n -> -|n+1|

そして、負の数に適用すると、対応する効果は次のようになります。

~-n -> |n-1|

次の例はこの最後のルールを示しています...

# -0 = 0b0000 0000
~-0
# Out: -1 
# -1 = 0b1111 1111
# 0 is the obvious exception to this rule, as -0 == 0 always
    
# -1 = 0b1000 0001
~-1
# Out: 0
# 0 = 0b0000 0000

# -2 = 0b1111 1110
~-2
# Out: 1
# 1 = 0b0000 0001

# -123 = 0b1111 1011
~-123
# Out: 122
# 122 = 0b0111 1010

埋め込み操作

すべてのビット演算子( ~を除く)は独自のインプレースバージョンを持っています

a = 0b001
a &= 0b010 
# a = 0b000

a = 0b001
a |= 0b010 
# a = 0b011

a = 0b001
a <<= 2 
# a = 0b100

a = 0b100
a >>= 2 
# a = 0b001

a = 0b101
a ^= 0b011 
# a = 0b110


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow