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

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

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

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

Q&A

解決済

1回答

1374閲覧

範囲指定のビットの変換について

kamecha

総合スコア41

C

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

0グッド

0クリップ

投稿2017/09/09 12:21

編集2017/09/09 12:42

###前提
c言語の勉強中の高校生です。書籍で勉強しているのですが、演習問題の答え等がないため質問することが多数あると思いますが、どうかよろしくお願いします。

###問題
符号なし整数xの第posビットから第pos + n- 1ビットまでのn個のビットを、1にした値を返す関数set_n,0にした値を返す関数reset_n,反転した値を返す関数inverse_nを作成せよ。

lang

1unsigned set_n(unsigned x, int pos, int n){/*...*/} 2unsigned reset_n(unsigned x, int pos, int n){/*...*/} 3unsigned inverse_n(unsigned x, int pos, int n){/*...*/}

###該当のソースコード

lang

1unsigned set_n (unsigned x, int pos, int n){ 2 int y = 0; //第posビットから pos + n - 1ビットまで1のビット 3 int i = 1U; 4 int t; 5 if(pos != 0){ 6 for(t = 0; t < pos + n - 1; t++){ 7 i <<= pos + t; 8 y = y | i; 9 i = 1U; 10 } 11 }else{ 12 for(t = 0; t < n; t++){ 13 i <<= t; 14 y = y | i; 15 i = 1U; 16 } 17 } 18 19 return x | y; 20} 21 22 23unsigned reset_n(unsigned x, int pos, int n){ 24 int y = 0; //第posビットから pos + n - 1ビットまで1のビット 25 int i = 1U; 26 int t; 27 if(pos != 0){ 28 for(t = 0; t < pos + n - 1; t++){ 29 i <<= pos + t; 30 y = y | i; 31 i = 1U; 32 } 33 }else{ 34 for(t = 0; t < n; t++){ 35 i <<= t; 36 y = y | i; 37 i = 1U; 38 } 39 } 40 41 if(x & y){ 42 return x ^ y; 43 }else{ 44 return x; 45 } 46} 47

###疑問点
関数set_nは正常に動作したのですが、関数reset_nは動作が不安定です。
特に第0ビットから始めようとすると意図しない結果が出てしまいます。
そのため、このコードのどこが間違っているのかを知りたいです。

また、関数inverse_nは、分からないため具体的なコードを教えていただきたいです。

###補足情報
書籍:新明解©言語 入門編
演習7-5

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

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

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

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

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

Stripe

2017/09/09 12:34

set_n()のコードも掲載してください。set_n()が出来れば、reset_n()やinverse_n()も出来るはずなんですが。
guest

回答1

0

ベストアンサー

こんにちは。

解説するより答えを示した方が早そうなので。

C

1#include <stdio.h> 2 3unsigned make_mask(int pos, int n) 4{ 5 unsigned ret=0; 6 for (int i=pos; i < (pos+n); ++i) 7 ret |= (1<<i); 8 return ret; 9} 10 11unsigned set_n(unsigned x, int pos, int n) 12{ 13 unsigned mask = make_mask(pos, n); 14 return (x | mask); 15} 16 17unsigned reset_n(unsigned x, int pos, int n) 18{ 19 unsigned mask = make_mask(pos, n); 20 return (x & ~mask); 21} 22 23unsigned inverse_n(unsigned x, int pos, int n) 24{ 25 unsigned mask = make_mask(pos, n); 26 return (x ^ mask); 27} 28 29int main() 30{ 31 unsigned x=0x1234; 32 int pos=4; 33 int n=4; 34 printf("set_n =0x%x\n", set_n(x, pos, n)); 35 printf("reset_n =0x%x\n", reset_n(x, pos, n)); 36 printf("inverse_n=0x%x\n", inverse_n(x, pos, n)); 37 38 return 0; 39}

指定ビットをリセットするには「リセットしたいビットが1の数値」を反転して論理積をとれば良いです。

^排他的論理和です。
0と排他的論理和を取った時は元のビットが変化しませんが、1と排他的論理和を取ると元のビットが反転します。

頑張ってください。

投稿2017/09/09 12:40

Chironian

総合スコア23272

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

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

kamecha

2017/09/09 12:56

ということは、 関数make_maskは自分にとって int y = 0; //第posビットから pos + n - 1ビットまで1のビット int i = 1U; int t; if(pos != 0){ for(t = 0; t < pos + n - 1; t++){ i <<= pos + t; y = y | i; i = 1U; } }else{ for(t = 0; t < n; t++){ i <<= t; y = y | i; i = 1U; } } にあたる、ということですか? また、この問題の解釈として第posビットに0を代入して、第nビットに1を代入すると 最下位ビットのみが1のビットができると言う事なのでしょうか。
Chironian

2017/09/09 13:26 編集

> にあたる、ということですか? 構造的にはその通りと思います。 make_maskは、第posビットから第pos + n- 1ビットまでが1で、その他のビットが0の符号なし整数を作っています。 > また、この問題の解釈として第posビットに0を代入して、第nビットに1を代入すると 最下位ビットのみが1のビットができると言う事なのでしょうか。 意味が分かりません。「最下位ビットのみが1のビット」って何の話でしょうか? 問題文を見る限り、最下位ビットを特別扱いする条件はないように見えます。 実は、nonbirikameさんのソースは良く見ていません。他の人のソースを読むのは意外に根性が必要なのですよ。 今回の場合、定形問題なので答えを示した方が楽なので、申し訳ないのですが答えを提示しました。 何が間違っていたのかnonbirikameさんご自身で発見されることを期待しています。 頑張ってください。
kamecha

2017/09/09 13:39

ありがとうございます! 少々変な質問をしてすみませんでした。(その質問については、自己解決したので大丈夫です) これからもしっかりと勉強していきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問