第9章 演習問題 解答例

9.4 ビット演算子

a9-4-1.c

任意の2つのuint16_t 型で表すことのできる整数値を入力し、AND、OR、XORを求めて表示してください。ただし、わかりやすいように16進数で表示してください。なお、printf とscanfの10進数変換指定には"%hu"、16進数変換指定には"%#x"を記述します。

/* a9-4-1.c */
#include <stdio.h>
#include <stdint.h>

int main(void)
{
    uint16_t a, b;

    printf("0 〜 %u の整数を2つ入力してください。\n", UINT16_MAX);
    printf("> ");
    scanf("%hu", &a);
    printf("> ");
    scanf("%hu", &b);

    printf("%hu(%#x) AND %hu(%#x) = %#x\n", a, a, b, b, a & b);
    printf("%hu(%#x) OR  %hu(%#x) = %#x\n", a, a, b, b, a | b);
    printf("%hu(%#x) XOR %hu(%#x) = %#x\n", a, a, b, b, a ^ b);

    return 0;
}

入力するのはuint16_t型の整数なので、0〜UINT16_MAXを入力範囲としています。

[Back]

a9-4-2.c

任意のuint32_t型で表すことのできる整数値を入力し、そのビットパターンを表示する関数を作成してください。

 関数名 show_bit
 仮引数 uint32_t dt:ビットパターンを表示する変数
 返却値 なし
/* a9-4-2.c */
#include <stdio.h>
#include <limits.h>
#include <stdint.h>

void show_bit(uint32_t dt);

int main(void)
{
    uint32_t a;

    printf("0 〜 %#x の16進数を入力してください。> ", UINT32_MAX);
    scanf("%x", &a);

    show_bit(a);

    return 0;
}

/*** ビット表示関数 ***/
/*(仮引数)dt:表示データ */
void show_bit(uint32_t dt)
{
    int i, len;

    len = (int)sizeof(dt) * CHAR_BIT;

    printf("%#010x ---> ", dt);
    for (i = len - 1; i >= 0; i--){
        putchar((dt >> i & 1U) ? '1' : '0' );
    }
    putchar('\n');
}

CHAR_BITは1バイトのビット数を表すマクロで、<limits.h>で定義されています。
show_bit関数は、各ビットを最下位までシフトし、1でANDを求めることによりビットのON/OFFを判定しています。1でANDを求めると最下位ビットだけを残してほかのビットを0にすることができます。なお、この判定には、条件演算子(P.158)を使用しています。
また、printfの書式指定"%#010x"は、先頭に0xを付け、それも含んで10桁、10桁に足りない場合には0を詰める指定です(P.94参照)。

[Back]

a9-4-3.c

任意のuint32_t型で表すことのできる整数値を入力し、そのビットパターンを左右反転する関数を作成してください。なお、演習1 で作成したshow_bit 関数を用いてビットパターンを表示してください。

 関数名 reverse_bit
 仮引数 uint32_t:ビットパターンを左右反転する変数
 返却値 uint32_t :左右反転した値
/* a9-4-3.c */
#include <stdio.h>
#include <limits.h>
#include <stdint.h>

uint32_t reverse_bit(uint32_t dt);
void show_bit(uint32_t dt);

int main(void)
{
    uint32_t a, b;

    printf("0 〜 %#x の16進数を入力してください。> ", UINT32_MAX);
    scanf("%x", &a);
    show_bit(a);
    b = reverse_bit(a);
    show_bit(b);

    return 0;
}
/*** ビット反転関数 ***/
/*(仮引数)dt:データ (返却値)反転データ */
uint32_t reverse_bit(uint32_t dt)
{
    uint32_t mask = 1U, bit, rb = 0U;
    int i, len;

    len = (int)sizeof(dt) * CHAR_BIT;
    mask <<= len - 1;

    for (i = 0; i < len; i++) {
        bit = (dt & mask) ? 1U : 0U;
        bit <<= i;
        rb |= bit;
        mask >>= 1;
    }
    return rb;
}

/*** ビット表示関数 ***/
/*(仮引数)dt:表示データ */
void show_bit(uint32_t dt)
{
    int i, len;

    len = (int)sizeof(dt) * CHAR_BIT;

    printf("%#010x ---> ", dt);
    for (i = len - 1; i >= 0; i--){
        putchar((dt >> i & 1U) ? '1' : '0' );
    }
    putchar('\n');
}

reverse_bitでは次のようにして左右ビットを反転しています。

1. マスク値(mask)にMSBが1のデータを作成。
2. maskを用いて対象ビットを作業用変数bitに取り出す。
3. bitを左右対称になるまでシフトする。
4. bitを返却用変数rbにビットORを求めて設定する。
5. maskを右へ1ビットシフトする。
6. 2〜5をMSBからLSBまで繰り返す。

※ LSB(最下位ビット):Least Significant Bit
  MSB(最上位ビット):Most Significant Bit

解説図

[Back]


Copyright© 2021 Tomoko Sugawara. All Rights Reserved.