勉強中の初心者ですが、ビット演算なるもので詰まりました
勉強中の初心者ですが、ビット演算なるもので詰まりました
最近C言語の勉強を始めたのですが、ビット演算を使って符号なし10進数xを2進数表示する関数を作るというよくわからない演習問題が出てきました。
入力した10進数を2進数に変えて表示させるということなのですが、
・scanf禁止
・unsignedのビット数は32
・n=sizeof(unsigned)*8
・void print_binary(unsigned x);
という条件を守って作るようです。
参考書は読みましたが、方針も思いつきませんでした。どなたか教えてくださいませんか?
模範解答には、コマンドプロンプトに
255
00000000000000000000000011111111
と表示される。という風に書かれていました。。。
これまではprintfとかif文、プロトタイプ宣言、配列など、本当に初歩のところをやっていました。
入力した10進数を2進数に変えて表示させるということなのですが、
・scanf禁止
・unsignedのビット数は32
・n=sizeof(unsigned)*8
・void print_binary(unsigned x);
という条件を守って作るようです。
参考書は読みましたが、方針も思いつきませんでした。どなたか教えてくださいませんか?
模範解答には、コマンドプロンプトに
255
00000000000000000000000011111111
と表示される。という風に書かれていました。。。
これまではprintfとかif文、プロトタイプ宣言、配列など、本当に初歩のところをやっていました。
Re: 勉強中の初心者ですが、ビット演算なるもので詰まりました
申し訳ありません。いま私が書いているものの状態を載せるのを忘れておりましたので追加致します。
#include <stdio.h>
#define MAXLINE 1000
#define NMAX 3000
int suuchi_u(char s[]);
int getline(char s[], int lim);
main()
{
char line[MAXLINE];
int i,n,data[NMAX];
while(getline(line, MAXLINE)>0)//入力した数字の数が0以上。
{
n=suuchi_u(line);
printf("データ数%d\n",n);
}
}
int suuchi_u(char s[])
{
int n,i;
char line[MAXLINE];
n=0;
for(i=0; '0'<=line[i]&&line[i]<='9'; i++)
{
n=10*n+(line[i]-'0');
}
return n;
}
int getline(char s[], int lim)//数字の入力。
{
int c,i;
lim=NMAX;
for(i=0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
{
s[i]=c;
}
if(c=='\n')
{
s[i]=c;
++i;
}
s[i]='\0';
return i;
}
Re: 勉強中の初心者ですが、ビット演算なるもので詰まりました
>・n=sizeof(unsigned)*8
これは何を言っているのですか?
(nとは 何を表す値?)
これは何を言っているのですか?
(nとは 何を表す値?)
オフトピック
符号なし10進数xを2進数表示する関数
void print_binary(unsigned x)
を作りなさい,という旨の問題なのだと思いますが,
対して,あなたが示したコードというのは
>scanf禁止
とかいう謎ルールに対抗して実装されたと思われる 数値xを入力する部分 のコードであるように思われます.
つまり,主題に関して言えば,「どうでもいい部分」です.
コードを示すのならば,
あなた流の print_binary() は現状どうなっているのか?を示すべきではないでしょうか.
(その他の部分については,「プログラムとして動作するためには」必要でしょうが,
この場で 主題=print_binary()の中身 の話をする分には不要に思います.)
void print_binary(unsigned x)
を作りなさい,という旨の問題なのだと思いますが,
対して,あなたが示したコードというのは
>scanf禁止
とかいう謎ルールに対抗して実装されたと思われる 数値xを入力する部分 のコードであるように思われます.
つまり,主題に関して言えば,「どうでもいい部分」です.
コードを示すのならば,
あなた流の print_binary() は現状どうなっているのか?を示すべきではないでしょうか.
(その他の部分については,「プログラムとして動作するためには」必要でしょうが,
この場で 主題=print_binary()の中身 の話をする分には不要に思います.)
Re: 勉強中の初心者ですが、ビット演算なるもので詰まりました
正しいかどうかは保証の限りにあらず。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define N (10) // 32ビット符号なし整数の最大桁
#define BIT (32)
void print_binary(unsigned x)
{
int n[BIT], i;
printf("%d\n", x);
for (i = 0; i < BIT; i++) {
n[i] = x % 2;
x >>= 1;
}
for (i = BIT - 1; i >= 0; i--) {
printf("%d", n[i]);
}
putchar('\n');
}
int main (void)
{
char s[N + 1];
unsigned x;
int i;
fgets(s, sizeof(s), stdin);
s[strlen(s) - 1] = '\0';
for (x = i = 0; i < N; i++) {
if(isdigit(s[i])) {
x = 10 * x + s[i] - '0';
}
}
print_binary(x);
return 0;
}
Re: 勉強中の初心者ですが、ビット演算なるもので詰まりました
usao様
回答ありがとうございます。n=sizeof(unsigned)*8については申し訳ありませんが私もわかりません。ただ、問題の横に書かれていたので、それをどこかで使うのだろうかと予想しています。
私が書いている部分ですが、scanfが禁止されているので、なんとかして10進数だけでも表示させてみようとしたものでございます。usao様のご指摘の通り、的外れの内容かもしれません。失礼いたしました。
回答ありがとうございます。n=sizeof(unsigned)*8については申し訳ありませんが私もわかりません。ただ、問題の横に書かれていたので、それをどこかで使うのだろうかと予想しています。
私が書いている部分ですが、scanfが禁止されているので、なんとかして10進数だけでも表示させてみようとしたものでございます。usao様のご指摘の通り、的外れの内容かもしれません。失礼いたしました。
Re: 勉強中の初心者ですが、ビット演算なるもので詰まりました
>ビット演算を使って
ということですから,ANDとかORとかを使いましょう,という意味でしょう.
例えばこんな感じで良いのではないでしょうか.
ということですから,ANDとかORとかを使いましょう,という意味でしょう.
例えばこんな感じで良いのではないでしょうか.
Re: 勉強中の初心者ですが、ビット演算なるもので詰まりました
先ほどのアドバイスにあった
#include <string.h>
#include <ctype.h>
はまだ授業でやっていないため、使い方がよくわかりませんでした。。。
#include <string.h>
#include <ctype.h>
はまだ授業でやっていないため、使い方がよくわかりませんでした。。。
Re: 勉強中の初心者ですが、ビット演算なるもので詰まりました
自分が書いた入力ルーチンも貼っておきます。
#include <stdio.h>
/* 文字をそれが表す数値に変換する */
int get_number_from_char(char c) {
char number_list[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
int i;
for (i = 0; i < 10; i++) {
if (number_list[i] == c) return i;
}
return -1;
}
/* 標準入力から非負整数を1個読み込む */
unsigned int read_non_negative_integer(void) {
while (1) {
unsigned int ret = 0; /* 読み込んだ整数 */
int current_char = '\0'; /* 読み込んだ文字 */
int nonempty = 0; /* 入力が空ではなかったというフラグ */
int invalid = 0; /* 不正な文字があったことを表すフラグ */
int overflow = 0; /* 入力がオーバーフローしたことを表すフラグ */
while (1) {
int current_number; /* 読み込んだ文字に対応する数値 */
/* 次の文字を読み込む */
if ((current_char=getchar()) == EOF) {
printf("Unexpected end of input!\n");
return -1;
}
/* 改行なら、今回の入力の終わりとみなす */
if (current_char == '\n') break;
/* 入力の文字を数値に変換する */
current_number = get_number_from_char(current_char);
if (current_number < 0) {
/* 入力が数値ではなかったので、不正 */
invalid = 1;
} else {
unsigned int new_ret;
/* 入力が空ではなかったという情報を保存する */
nonempty = 1;
/* オーバーフローをチェックしながら、入力を反映させる */
new_ret = ret * 10;
if (new_ret / 10 != ret) {
overflow = 1;
} else {
if(new_ret + current_number < new_ret) {
overflow = 1;
} else {
/* オーバーフローしなかったので、retを更新する */
ret = new_ret + current_number;
}
}
}
}
if (invalid) {
/* 不正な文字があった */
printf("The input contains invalid char(s).\n");
} else if (overflow) {
/* 入力がオーバーフローした */
printf("The input is too large.\n");
} else if (!nonempty) {
/* 入力が空だった */
printf("Please input a non-negative integer.\n");
} else {
/* 正しい入力が得られた */
return ret;
}
}
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 勉強中の初心者ですが、ビット演算なるもので詰まりました
みけCAT様
回答ありがとうございます。コンパイルしてみましたが、未解決の外部シンボル~などのエラーがでてしまいました。。。
入力した10進数を2進数表示するこの課題は、私のようなC言語に振れはじめて2か月弱の人間には難しいものなのでしょうかね・・・
回答ありがとうございます。コンパイルしてみましたが、未解決の外部シンボル~などのエラーがでてしまいました。。。
入力した10進数を2進数表示するこの課題は、私のようなC言語に振れはじめて2か月弱の人間には難しいものなのでしょうかね・・・
Re: 勉強中の初心者ですが、ビット演算なるもので詰まりました
>ビット演算を使って
ということですから、ANDとかORとかを使いましょう、という意味でしょう。
例えばこんな感じで良いのではないでしょうか。
なお、print_binary は、
「符号なし10進数 x を 2進数表示する関数」ではありません。
x は、10進数ではないからです。
x の値は、コンピュータの内部表現になっていて、あえて言えば
「表示形式ではない 2進数」です。
print_binary は、それを「表示可能な 2進数文字列」に変換しているだけです。
ということですから、ANDとかORとかを使いましょう、という意味でしょう。
例えばこんな感じで良いのではないでしょうか。
void print_binary(unsigned x)
{
unsigned n = 32;
while (n--) putchar(x>>n & 1 | '0'); // AND も OR も使っています
putchar('\n');
}
int main(void)
{
unsigned x;
if (fscanf(stdin, "%u", &x) == 1) print_binary(x);
return 0;
}
「符号なし10進数 x を 2進数表示する関数」ではありません。
x は、10進数ではないからです。
x の値は、コンピュータの内部表現になっていて、あえて言えば
「表示形式ではない 2進数」です。
print_binary は、それを「表示可能な 2進数文字列」に変換しているだけです。
Re: 勉強中の初心者ですが、ビット演算なるもので詰まりました
こちらではhttps://ideone.com/でコンパイルが通ることを確認しているので、詳しいエラーメッセージを教えてください。ドシロート さんが書きました:みけCAT様
回答ありがとうございます。コンパイルしてみましたが、未解決の外部シンボル~などのエラーがでてしまいました。。。
なお、入力ルーチンしか載せていないので、これだけで「普通」にコンパイルして実行することはできません。
(これ単体をコンパイルしてオブジェクトファイルを作ることは可能なはずです)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)