以下の記事の続きです。
今回は、bit演算でn番目のbitを0にします。
簡略化のため、n番目は0から始まると考えます。
ビットの反転
演算子~ は、0と1を逆にする、つまりビットを反転する演算子です。
>>> ~0 -1 >>> ~1 -2
~0が-1、~1が-2という結果になりました。
Pythonでは上の桁は全て0と考えてその数字を反転するので、上の桁が1で埋められていると考えるからです。
よって、0を反転した数字は、111…1111となり、2の補数による表現で、-1を表します。
bn ... b2 b1 b0
0 : 0 ... 0 0 0
~0 : 1 ... 1 1 1
bn ... b2 b1 b0
1 : 0 ... 0 0 1
~1 : 1 ... 1 1 0
左シフトと反転の組み合わせ
左シフトと反転を組み合わせることで、特定のbitだけが0の数字を作ることができます。
1 << 0 : 0 0 0 0 0 0 0 1 1 << 1 : 0 0 0 0 0 0 1 0 1 << 2 : 0 0 0 0 0 1 0 0 ~(1 << 0) : 1 1 1 1 1 1 1 0 ~(1 << 1) : 1 1 1 1 1 1 0 1 ~(1 << 2) : 1 1 1 1 1 0 1 1
n番目のbitを0にする
1をn左シフトし反転させたものと&を取ることで、n番目のbitを0にすることができます。
0番目のbitを0にする
~(1 << 0) = 1 1 0
b2 b1 b0
5 : 1 0 1
1 1 0 &
-------
1 0 0
1番目のbitを0にする
~(1 << 1) = 1 0 1
b2 b1 b0
5 : 1 0 1
1 0 1 &
-------
1 0 1
2番目のbitを0にする
~(1 << 2) = 0 1 1
b2 b1 b0
5 : 1 0 1
0 1 1 &
-------
0 0 1
関数にまとめる
関数にまとめ、実行してみます。
>>> def unset_nth_bit(num: int , n: int): ... return num & ~(1 << n) ... >>> bin(unset_nth_bit(5, 0)) '0b100' >>> bin(unset_nth_bit(5, 1)) '0b101' >>> bin(unset_nth_bit(5, 2)) '0b1'
想定通りの結果になりました。
以下に続きます。