ここではビット演算子を使ってみましょう。
ビット演算では変数や数値を2進数としてあつかい、様々な処理をおこなうことができます。
普段私たちが目にするのは10進数だけなので馴染みがないかもしれませんが、コンピュータ内の数値は0と1の組み合わせによって構成されています。
そのため、2進数はコンピュータとの相性がよく、プログラムにビット演算子を用いることで処理速度の向上などのメリットが得られます。
が、難しいようであれば、C言語に慣れるまでは取り組まなくても大丈夫だと思います。
動かしてみよう
色々なビット演算子の実行結果を表示するサンプルコードを用意しました。
実行ボタンを押して、実行してみてください。
実行できましたか。
処理のイメージがわかないようであれば、変数x, a の値を色々かえてみて実行してみてください。
では、解説に進みましょう。
解説
ビット演算子とその意味を下表に示します。
ビット演算 | 意味 |
---|---|
x << a | x を a だけ左シフト |
x >> a | x を a だけ右シフト |
x & a | x と a の論理積 |
x | a | x と a の論理和 |
x ^ a | x と a の排他的論理和 |
~x | x のビット反転 |
それぞれの動作について詳しくみてみましょう。
以降の説明ではサンプルコードと同じく、x=10,a=2 と仮定して説明します。
なお、10を2進数で表現すると 0000 1010 です。(xは32bitなのですが、便宜上8bit分の表記としています。)
x << a
上記の左シフト演算では、 0000 1010 を2つ左へずらします。
ずらした際、上位2bitは破棄され、下位2bitは0で埋められます。
0000 1010 ↓2つ左へずらす
0010 1000
左シフトには 2のa乗を掛ける という効果があります。
上記の2進数を10進数に戻すと、x=10 に 2の2乗=4 を掛けた 40 になっていることが、サンプルコードの出力結果からわかると思います。
x >> a
上記の右シフト演算では、 0000 1010 を2つ右へずらします。
ずらした際、上位2bitは0または1で埋められ、下位2bitは破棄されます。
0000 1010 ↓2つ右へずらす
0000 0010
左シフトには 2のa乗で割る という効果があります。
上記の2進数を10進数に戻すと、x=10 に 2の2乗=4 で割った 2 になっていることが、サンプルコードの出力結果からわかると思います。(10/4 = 2.5 ですが、小数点以下は切り捨てです。)
コンパイラが算術シフトと論理シフトのどちらを実現しているかで動作が変わります。
使用前にコンパイラのマニュアルを参照するように注意してください。
x & a
上記演算では、x と a のビット単位での論理積をとります。
0000 1010
0000 0010
—————-
0000 0010
0000 0010 を10進数に戻すと、2 になります。
x | a
上記演算では、x と a のビット単位での論理和をとります。
0000 1010
0000 0010
—————-
0010 1010
0000 1010 を10進数に戻すと、10 になります。
x | a
上記演算では、x と a のビット単位での排他的論理和をとります。
0000 1010
0000 0010
—————-
0000 1000
0000 1000 を10進数に戻すと、8 になります。
~x
上記演算では、x のビットを反転させます。
0000 1010
—————-
1111 0101
1111 0101 を10進数に戻すと、245 になります。(符号無しの場合)
まとめ
まとめです。
- ビット演算子を用いることで、ビットごとの演算をおこなわせることができます。
- ビット演算子は2進数と相性が良いです。
- 右シフト演算の挙動は環境により異なるため、特に注意が必要です。
以上です。
ではまた。