ビット演算、シフト演算について

最終更新日:2004-10-08.

今回は、ビット演算、シフト演算についてちょっと。

・ビット演算

複数の変数の内容をビット単位で判断することができます。
ビット演算子には以下のようなものがあります。
「&」、「|」、「^」。

・ビット

ビットは0または1の情報を格納し、表現することができます。

・バイト

8ビットごとに区切ってまとめたものが1バイトとなります。

1バイトは正の整数でいうと、0から255までの256個の情報を
表すことができます。

10進数と2進数の対応を簡単に書くと以下のようになります。
(一部分のみ。)

10進数 2進数
0 00000000
1 00000001
2 00000010
3 00000011
4 00000100
8 00001000
16 00010000
32 00100000
64 01000000
128 10000000
255 11111111

・論理積

これは「&」を使う。
両方のビットを見て、共に1ならば1となり、それ以外は0となる。

・論理和

これは「|」を使う。
両方のビットを見て、共に1、またはどちらかが1ならば1となり、
それ以外(共に0)ならば0となる。

・排他的論理和

これは「^」を使う。
両方のビットを見て、どちらかが1、他方が0ならば1となり、
それ以外(共に0または1)ならば0となる。

例えば。

char a, b, c;
a=2;
b=3;

c=a&b;

上記のcは2となる。

c=a|b;

上記のcは3となる。

c=a^b;

上記のcは1となる。

・シフト演算

これは、値を倍増したり、半減するようなときに便利です。
ビットの情報を左または右へ移動します。
シフト演算子には以下のようなものがあります。
「>>」、「<<」。

現在のビットの内容を、右へ1つ移動するには
「>>1」とします。
また、ビットの内容を左へ1つ移動するには
「<<1」とします。

例えば。

char a, b;
a=4;

10進数の4を2進数に直すと00000100ですね。

b=a>>1;

上記のbは2となります。

b=a<<1;

上記のbは8となります。

では、ソースにしてみましょう。
+------------------------------------------------------------+
/* filename=no020-1.c */
/* include */
#include <stdio.h>
#include <machine.h>
/* main */
int main()
{
char a, b, c;
a=2;
b=3;
c=a&b;
printf("a=%d, b=%d, c=%d\n", a, b, c);
c=a|b;
printf("a=%d, b=%d, c=%d\n", a, b, c);
c=a^b;
printf("a=%d, b=%d, c=%d\n", a, b, c);
a=4;
b=a>>1;
c=a<<1;
printf("a=%d, b=%d, c=%d\n", a, b, c);
return 0;/* 終了 */
}
+------------------------------------------------------------+

上記のソースをコンパイルして実行すると以下のように表示されました。
a=2, b=3, c=2
a=2, b=3, c=3
a=2, b=3, c=1
a=4, b=2, c=8

今回の最後に、10進数を2進数に変換して表示するものを作ってみましょう。

では、ソースにしてみましょう。
+------------------------------------------------------------+
/* filename=no020-2.c */
/* include */
#include <stdio.h>
#include <stdlib.h>
/* 関数プロトタイプ宣言 */
void sub(int);
/* main */
int main(int argc, char **argv)
{
int i;
if( argc==1 ){
printf("0から255までの数値を指定してください。\n");
exit(1);
}
i=atoi(argv[1]);
if( (i<0) || (i>255) ){
printf("0から255までの数値を指定してください。\n");
exit(1);
}
sub(i);
return 0;/* 終了 */
}
/* 数値を2進数で表示 */
void sub(int i)
{
int j=1;
unsigned char c;/* 符号無し */
unsigned char d=128;
c=(char)i;/* 型変換 */
while( j<9 ){
printf("%d", c/d);
c*=2;
j++;
}
return;/* 戻る */
}
+------------------------------------------------------------+

+------------------------------------------------------------+
/* filename=no020-3.c */
/* include */
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
/* 関数プロトタイプ宣言 */
void sub(int);
/* main */
int main(int argc, char **argv)
{
int i;
if( argc==1 ){
printf("0から255までの数値を指定してください。\n");
exit(1);
}
i=atoi(argv[1]);
if( (i<0) || (i>255) ){
printf("0から255までの数値を指定してください。\n");
exit(1);
}
sub(i);
return 0;/* 終了 */
}
/* 数値を2進数で表示 */
void sub(int i)
{
int j=1;
unsigned char c;/* 符号無し */
unsigned char d;
c=(char)i;/* 型変換 */
while( j<9 ){
d=c>>7;
printf("%d", d);
c=c<<1;
j++;
}
return;/* 戻る */
}
+------------------------------------------------------------+

戻る