![]()
6.ビット演算による操作 (2015.2.18)
ビット演算の場合は、整数型の数値をそのまま扱うのでは無く、2進数にして各ビットに対して操作を行います。ビット演算子には
●論理和( | )
●論理積( & )
●排他的論理和( ^ )
●反転( ~ )
●シフト(右シフト >>、左シフト <<)
の5つがあります。
ビット演算では整数を2進数の文字列に変換することが多くあります。それには組み込み関数bin()を使います。ただし、bin()関数は最上位のビットで正(0)負(-1)を表すので注意が必要です。単純に反転したため負の数になってしまうと、期待通りの結果が得られないことになります。この部分のテキストの説明はわかりにくいので補足しておきます。Raspberry Piの場合、整数の基本サイズは32bitなので、4bitごとに区切ると8個の塊になり、実際に行われる計算をイメージすると次のようになります。
a = 1は、
0000 0000 0000 0000 0000 0000 0000 0001
これをビット反転して新しいaにします。
a = ~aは、
1111 1111 1111 1111 1111 1111 1111 1110
bin()関数を使ってbin(a)を実行すると、次の操作が行われます。
0000 0000 0000 0000 0000 0000 0000 0001 ・・・新しいaに対して全ビット反転したもの
0000 0000 0000 0000 0000 0000 0000 0010 ・・・上記に1を足したもの
この計算結果に-符合を付けた文字列-0b10がbin()関数の結果となります。(0bは2進数を表す)
ビット反転した結果が負の数では、想定外の結果になってしまいます。それを避けるためにbin()関数を使う時にaに対してFFHで論理積をとることにします。つまり下位の8bitのみを演算対象にして、上位を無視することで想定した結果を得ようとするわけです。前述と同様に、実際に行われる計算をイメージすると次のようになります。
a = ~aは、
1111 1111 1111 1111 1111 1111 1111 1110
0000 0000 0000 0000 0000 0000 1111 1111 ・・・FFHで下位8bitのみを対象とする
0000 0000 0000 0000 0000 0000 1111 1110 ・・・上の2つを論理積したもの
この計算で得られた文字列0b11111110がbin()関数の結果となります。ビットが正しく反転していることがわかるでしょうか。計算だけだとわかりにくいですが、実際外部機器を制御する段階になれば、こうした操作が必要になることがわかるはずです。
参考までに0を中心とした2進数のデータ(左辺)と10進数の値(右辺)との関係を下図に示します。
0000 0000 0000 0000 0000 0000 0000 0010 : 2
0000 0000 0000 0000 0000 0000 0000 0001 : 1
0000 0000 0000 0000 0000 0000 0000 0000 : 0
1111 1111 1111 1111 1111 1111 1111 1111 : -1
1111 1111 1111 1111 1111 1111 1111 1110 : -2
■シフト演算
ビットを左右に移動する演算をシフト演算と呼びます。
1ビット右シフトの例
>>> a = 0b100
>>> a = a >> 1
>>> bin(a)
'0b10' ・・・0b010となりますが、010の先頭の0は意味が無いので表示されません。
1ビット左シフトの例
>>> a = 0b001
>>> a = a << 1
>>> bin(a)
'0b10' ・・・これも0b010となりますが、010の先頭の0は意味が無いので表示されません。
シフト演算は実際の制御でよく使われるので覚えておきましょう。
![]()