第48章 ビットでいじろう3

 今回も前回の続き、ビット演算について話します。今回はそのうちのNOTとビットシフトについて話したいと思います。


 今回の要点です。


 では、いってみましょう。


 早速NOT(論理否定)についての話に入りましょう。C/C++言語の演算子は ~ で、1つの数値から、1つの演算結果を導き出します。先ずは計算例を見てみましょう。(数値は2進数です。)

~0111=1000

 つまり、全ビットを反転します。これがNOTです。

 青が0、赤が1とすると、こんな感じになります。

~

 これは非常に簡単ですね。


 さて、次はNOTの利用法について話しましょう。

 先ずは、下の計算を見て下さい。

  ~00001000
――――――――――
  11110111
&)01111010
――――――――――
  01110010

 このように、NOTは普通ANDと組み合わせて、特定のビットを0にするときに使います。もちろんAND単独でもできますが、NOTと組み合わせて使う方が便利で分かりやすいときがあります。このNOTとANDを組み合わせた計算を、特にNANDと呼ぶことがあります。


 次はビットシフトです。C/C++言語の演算子は >> と << で、2つの数値から、1つの演算結果を導き出します。cout にもこの演算子を使うので、cout などと組み合わせて使うときは、全体をカッコで囲むようにしましょう。では、先ずは計算例を見てみましょう。(数値は2進数と10進数の混在です。)

  00010101   00010101
<<       3 >>       2
―――――――――― ――――――――――
  10101000   00000101

 つまり、その名の通りビットを右へ左へずらします。これがビットシフトです。ビットの無くなってしまうところは0で埋められ、ビットの溢れてしまうところは切り捨てられてしまいます。

 これも非常に簡単ですね。


 さて、次はビットシフトの利用法について話しましょう。

 先ずは、下の計算を見て下さい。

  00001010 = 10
<<       3
――――――――――
  01010000 = 80

 ビットを左に3ずらすと、値は8倍されました。この8というのは2の3乗です。これは偶然ではなく、こうなるものなのです。ビットを左に3つずらすということは、結局の所(1000)2倍(=8倍)することなのですから。

 10進数で考えるともっとよくわかります。123を左に3つシフトすると123000です。これは元の値を1000(=10の3乗)倍したことになりますね。

 また、ビットを右にずらすと今度は割り算になります。このように、ビットシフトは2の累乗での乗除に用いられます。

 ほかにも、第xビットを作り出すのにも使います。

#define BIT(x)          (1 << (x))

というマクロを作れば、BIT(0) で第0ビットのみが、BIT(4) で第4ビットのみが1になった値を表現することができます。

 また、for 文で

unsigned int i, x = 105054;
for(i = 1; i; i <<=1)
{
    if(x & i)...
    else...
}

のようにすると、第0ビットが1かどうか、第1ビットが1かどうか...と、ビットスキャンを行うことができます。


 これで全てのビット演算子を紹介し終えました。最後に、ビット演算子を使って次の問題を解いてみて下さい。答は第50章で解説します。

44は44、81は84、というように、その数以上の4の倍数のうち最も小さい数を求める式を作って下さい。

 まぁ、とりあえず言っておきますが、別にビット演算子だけしか使っていけないわけではありません。それに、ビット演算子の全てを使うわけではありません。まぁ、頭の体操ということで。


 では今回の要点です。


 次回はビット演算の花形、フラグ処理について話したいと思います。それでは。


第47章 ビットでいじろう2 | 第49章 ビットでフラグ

Last update was done on 2000.1.20

この講座の著作権はロベールが保有しています