以下の記事の続きです。
今回は、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'
想定通りの結果になりました。
以下に続きます。