質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

2回答

3708閲覧

C言語 ビット単位の論理演算

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2016/07/04 14:31

編集2016/07/04 14:56

このコードの内容が全くもって理解できません。
どなたか一から説明してくだされば幸いです。

include<stdio.h>はこの質問のテンプレートではおかしくなるので省略しています。

int count_bits
int_bits
void_print_bits

これらの関数の内部で何が行われているのかがよくわからないです。
ビット単位の論理演算自体の結果はわかるのですが、それをどうやって演算しているのか?がわかりません。

/*--- 整数x中のセットされたビット数を返す ---*/ int count_bits(unsigned x) { int bits = 0; while (x) { if (x & 1U) bits++; x >>= 1; } return bits; } /*--- unsigned型のビット数を返す ---*/ int int_bits(void) { return count_bits(~0U); } /*--- unsigned型のビット内容を表示 ---*/ void print_bits(unsigned x) { int i; for (i = int_bits() - 1; i >= 0; i--) putchar(((x >> i) & 1U) ? '1' : '0'); } int main(void) { unsigned a, b; printf("非負の整数を二つ入力してください。¥n"); printf("a : "); scanf("%u", &a); printf("b : "); scanf("%u", &b); printf("\na = "); print_bits(a); printf("\nb = "); print_bits(b); printf("\na & b = "); print_bits(a & b); /* aとbの論理積 */ printf("\na | b = "); print_bits(a | b); /* aとbの論理和 */ printf("\na ^ b = "); print_bits(a ^ b); /* aとbの排他的論理和 */ printf("\n~a = "); print_bits(~a); /* aの1の補数 */ printf("\n~b = "); print_bits(~b); /* bの1の補数 */ putchar('\n'); return 0; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Mr_Roboto

2016/07/04 14:37

こんばんは、初めての質問ですね、よろしくお願いします。 コードは、コードブロックで囲って頂けると読みやすくなります。 編集画面の </>というボタンです。(再編集してみてください) 質問するときのヒント https://teratail.com/help/question-tips を読んでいなければ読んでみてくださいね。 一からの説明は誰もしてくれません、できるところまで自分で頑張らないと丸投げフラグを付けられてしまいます ^_^; 全くといっても変数の宣言くらいはわかりますよね? なので、どこまで理解できるか書いた方が、良い回答を得られると思いますよ ^^
Zuishin

2016/07/04 14:43

私もあまり質問をしないので質問画面に </> があるものと思い込んでいましたが、無いんですね。左下の markdown というところをまず押してみてください。
Zuishin

2016/07/04 14:45

すいません、上の方にありました。余計なことを言いました。
guest

回答2

0

まず、Cにおいてwhileやifなどの条件文に数値が来た場合は、「0 = false」「0以外 = true」とお考えください。

  • count_bits

引数xと1とのビット積を取ります。これが0でなければbitsに1加えます。つまり、xを2進数で表した時に一番右のビットが1であればbitsが加算されます。
そしてその後xを1ビット右にシフトします。もともと一番右にあるビットは消えます。
これをxが0になるまで繰り返すことにより、xを2進数で表した際の「1」の個数を数えることができます。

  • int_bits

0Uは符号なし整数の0を意味します。全ビットが0の数になります。
その前に~を付けることで全ビット反転します。つまり全ビットが1の数になります。
この1の個数をcount_bitsで数えることで、符号なし整数が何ビット使っているかを調べられるわけです。

  • print_bits

for文では、int_bitsにより得られるビット数だけ繰り返しを行うことを示しています。
count_bitsの時と同じ要領で与えられた数のビットを順に調べ、1か0かを出力していきます。
ただしcount_bitsの時と違うのは、xの右ではなく左から順に調べていくという点です。

投稿2016/07/04 15:23

swordone

総合スコア20651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

  • int count_bits(unsigned x)

シフト演算子「>>」がポイントです。
x >>= 1x = x >> 1と同じで、xを右に1ビットシフトする、という意味です。

x == 1011 と仮定すると、
1回目のwhile … x != 0 なので、やる
x == 1011, bits == 0
x & 1U == 0001 なので bits++ (bits==1)
x >>= 1 つまり x = x >> 1、x == 0101になる
2回目のwhile … x != 0 なので、やる
x == 0101, bits == 1
x & 1U == 0001 なので bits++ (bits==2)
x >>= 1 して x == 0010
3回目のwhile … x != 0 なので、やる
x == 0010, bits == 2
x & 1U == 0000 なので bits++ しない (bits==2)
x >>= 1 して x == 0001
4回目のwhile … x != 0 なので、やる
x == 0001, bits == 2
x & 1U == 0001 なので bits++ (bits==3)
x >>= 1 1 して x == 0000
5回目のwhile … x == 0 なので、やらない
bits(3)を返す。

以上のように、与えられたxのセットされたビット数(1の数)を返します。

  • int int_bits(void)

否定演算子「~」がポイントです。

~0U(0の否定)、つまり 全ビットが1 な値をcount_bitsのxに与える。
したがって、unsigned のビット数が数えられ、戻り値として返ります。

  • void print_bits(unsigned x)

シフト演算子「>>」の応用です。
b >> nは、bをnビット右シフトする、という意味です。
仮に 4bit だとすると、for (i = 3; i >= 0; i--)となり、
x >> 3, x >> 2, x >> 1, x >> 0のように、一番左の桁から順に
putchar(1なら'1'を、0なら'0'を表示)を繰り返します。

投稿2016/07/04 23:35

tnd-.-b

総合スコア247

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問