サイトマップ / C言語講座出入り口総目次目次:ビット演算>整数の内部表現

青い直線

整数の内部表現

青い直線

[ビット毎の論理積と論理和]←このソース→[整数の取り得る範囲]

/* ビット反転とビット毎の排他的論理和 */

/* 今回は、ビット反転 (演算子: ~) や、ビット毎の排他的論理和 ( XOR ) ( 演算子: ) について学びます。

ビットを反転させるということは、あるビットが 0 ならば 1 に、1 なら 0 にするということです。ビットを反転させるということを、「 1 の補数を求める」といいます。下記に signed char 型の整数の例を示します。

10進表示 ビットパターン
2 0 0 0 0 0 0 1 0
ビット反転すると
-3 1 1 1 1 1 1 0 1

2 が - 3 になりました。コンピュータでマイナスの値を表すにはどうしているのでしょう。以下に 0 から値を増やした時のビットパターンを示します。

10進表示 ビットパターン
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1
2 0 0 0 0 0 0 1 0
3 0 0 0 0 0 0 1 1
途 中 省 略
126 0 1 1 1 1 1 1 0
127 0 1 1 1 1 1 1 1
-128 1 0 0 0 0 0 0 0
-127 1 0 0 0 0 0 0 1
-126 1 0 0 0 0 0 1 0
途 中 省 略
-3 1 1 1 1 1 1 0 1
-2 1 1 1 1 1 1 1 0
-1 1 1 1 1 1 1 1 1

3 と - 3 のビットパターンを比較してみます。

10進表示 ビットパターン
3 0 0 0 0 0 0 1 1
-3 1 1 1 1 1 1 0 1

3 の各ビットを反転させたものを下記に示します。

10進表示 ビットパターン
~3 1 1 1 1 1 1 0 0

~3 の第 0 ビットを立てたものが、- 3 です。つまり、ビットを反転して、1 を加えれば、マイナスの数になります。この操作のことを、「 2 の補数を求める」といいます。コンピュータはこのような方法で、マイナスの値を内部表現しています。

符号付きの整数は最上位ビット ( MSB ) が1ならばマイナスの値です。符号なし整数は最上位ビットも数を表すのに使います。

ビット毎の排他的論理和

前回はビット毎の論理和と論理積について学びました。これ以外にも、ビット毎の排他的論理和 ( XOR 演算記号:^)があります。ビット毎の排他的論理和とは、1 と 1 なら 0 に、1 と 0 なら 1 に、0 と 0 なら 0 になります。今回のソースプログラムでは、ビットを 0 にするのに使っています。

ソースプログラムの説明

今回のソースプログラムで、ビットパターンを表示する関数がでてきます。短い関数ですが、その中に下記のコードがあります。

    printf("%d", (c >> i) & 0X01);

(c >> i) はi ビット右へシフトさせます。その結果、第 i ビットが第 0 ビットに来ます。0X01 は第 0 ビットのみが 1 なので、論理積を取ることにより、i ビット目を取り出すことができます。

後は、ソースプログラム中のコメントをごらん下さい。プログラムの実行結果も、良く見て下さい。 */

/* ここからソースプログラム */

#include  <stdio.h>

#define BIT1 0X02        /* 第 1 ビットのみ 1 */
#define BIT7 0X80        /* 第 7 ビットのみ 1 */

void ShowBit(signed char c);
void main(void);

  /* ビットパターンを表示する */
void ShowBit(signed char c)
{
    int i;

    for ( i = 7; i >= 0; i--) /* i ビット目を表示する */
        printf("%d", (c >> i) & 0X01);
}

void main(void)
{
    signed char c = 0;
    int i;

    c = ~c;         /* 全ビットを立てる */
    c = c ^ BIT7;   /* 第 7 ビットを 0 にする */
    c = c ^ BIT1;   /* 第 1 ビットを 0 にする */

    for (i = 0; i < 6; i++) {
        ShowBit(c);              /* ビットパターンを表示して */
        printf(": %4d\n", c++);  /* その値も表示 */
    }
}

/* ここまでソースプログラム */

/* 今回はビットパターンを表示する関数がでてきました。これをペーパーテストの時などに、手計算で行うにはどうしたら良いでしょう。下記に示すのは10進数36のビットパターンを求めた例です。

計  算 余り
36 ÷ 2 = 18 0
18 ÷ 2 = 9 0
9 ÷ 2 = 4 1
4 ÷ 2 = 2 0
2 ÷ 2 = 1 0
1 ÷ 2 = 0 1

順次2で割っていき、余りの列の数字を下から順に並べます。

    100100

この場合 8 ビットなので、数字の数が 8 に満たなければ、足りない分頭に 0 を付けます。

    00100100

では、2 進数を 16 進数に変換するにはどうしたら良いでしょう。

2進数 16進数 2進数 16進数
0000 0 1000 8
0001 1 1001 9
0010 2 1010 A
0011 3 1011 B
0100 4 1100 C
0101 5 1101 D
0110 6 1110 E
0111 7 1111 F

4 ビットの数に対する上記の変換をする表を作ります。

次に下の桁から 4 桁ずつ区切ります。

    1101001 -> 110 1001

4 桁に満たなければ、頭に 0 を付けます。

    110 1001 -> 0110 1001

上の表に従って、変換します。

    0110 1001 -> 0X69

16 進数を 2 進数に変換するにも、上の変換表で簡単にできます。 */

[ビット毎の論理積と論理和]←このソース→[整数の取り得る範囲]

青い直線

/* (C) 2000- YFプロ. All Rights Reserved. */    提供:C言語講座−それ自体コンパイルできる教材を使った講座です−

青い直線

サイトマップ / C言語講座出入り口総目次目次:ビット演算>整数の内部表現