落書きノート

ふと自分が気になった事を書いてます

C言語で問題を解く

7章目に差し掛かって色々試していたのですが、仕様が変わっている?ので、答えと同じ表示にならないですね。それにしてもビット計算難しいですよね。自分で考えて頭がパンクしそうでしたが、なんとか出来ました。答えを見たのもありますが、まあこれぐらいなら許容範囲ですかね…。

解きながら学ぶC言語

解きながら学ぶC言語

// q7-5
#include <stdio.h>

unsigned pow2(unsigned no) {
  unsigned pw = 1;
  while(no--)
    pw *= 2;
  return pw;
}

int main(void) {
  unsigned m_pow, d_pow, l_sht, r_sht;
  unsigned a, n;

  printf("整数Aを入力してください : "); scanf("%u", &a);
  printf("何ビットシフトしますか : "); scanf("%u", &n);

  m_pow = a * pow2(n);
  d_pow = a / pow2(n);

  l_sht = a << n;
  r_sht = a >> n;

  printf("A * (2の%u乗) == %u\n", n, m_pow);
  printf("A / (2の%u乗) == %u\n", n, d_pow);
  printf("A << %u == %u\n", n, l_sht);
  printf("A >> %u == %u\n", n, r_sht);

  if(r_sht == d_pow && l_sht == m_pow)
    printf("符号なし整数%uの左右%uビットシフトは、\n"
           "2の%u乗での乗算や除算と等しいです。\n", a, n, n);
  return 0;
}

// q7-6
#include <stdio.h>

int count_bits(unsigned x) {
  int count = 0;
  while(x) {
    if(x & 1U) count++;
    x >>= 1;
  }
  return count;
}

int int_bits(void) {
  return count_bits(~0U);
}

void print_bits(unsigned x) {
  int i;
  for(i = int_bits() - 1; i >= 0; i--)
    putchar(((x >> i) & 1U) ? '1' : '0');
}

unsigned rrotate(unsigned x, int n) {
  int bits = int_bits();
  n %= bits;
  return (n ? (x >> n) | (x << (bits - n)) : x);
}

unsigned lrotate(unsigned x, int n) {
  int bits = int_bits();
  n %= bits;
  return (n ? (x << n) | (x >> (bits - n)) : x);
}

int main(void) {
  unsigned x,bits;
  printf("非負の整数を入力してください : ");
  scanf("%u", &x);
  printf("何ビット回転しますか : ");
  scanf("%u", &bits);
  printf("\n回転前="); print_bits(x);
  printf("\n右回転="); print_bits(rrotate(x, bits));
  printf("\n左回転="); print_bits(lrotate(x, bits));
  putchar('\n');
  return 0;
}

// q7-7
#include <stdio.h>

int count_bits(unsigned x) {
  int count = 0;
  while(x) {
    if(x & 1U) count++;
    x >>= 1;
  }
  return count;
}

int int_bits(void) {
  return count_bits(~0U);
}

void print_bits(unsigned x) {
  int i;
  for(i = int_bits() - 1; i >= 0; i--)
    putchar(((x >> i) & 1U) ? '1' : '0');
}

unsigned set(unsigned x, int pos) {
  unsigned t = x >> (pos - 1) & 1U;
  return t ? x : x | (1U << (pos - 1));
}

unsigned reset(unsigned x, int pos) {
  unsigned t = x >> (pos - 1) & 1U;
  return t ? x & ~(1U << (pos - 1)) : x;
}

unsigned inverse(unsigned x, int pos) {
  unsigned t = x >> (pos - 1) & 1U;
  return t ? x ^ (t << pos - 1) : x | (1U << pos - 1);
}

int main(void) {
  unsigned x, pos;
  printf("非負の整数xを入力してください : ");
  scanf("%u", &x);
  printf("操作するビット位置posを入力してください : ");
  scanf("%u", &pos);
  print_bits(x);
  putchar('\n');
  print_bits(set(x, pos));
  putchar('\n');
  print_bits(reset(x, pos));
  putchar('\n');
  print_bits(inverse(x, pos));
  putchar('\n');
  return 0;
}