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

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

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

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

Q&A

解決済

3回答

1962閲覧

C 入力値が大きくなったとき動作しない

suzaria

総合スコア14

C

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

0グッド

0クリップ

投稿2016/04/02 07:30

入力された2つの数字の間にある数字の中で2進数変換してひっくり返したとき、変換する前と変わらないものの個数を求めるプログラムを組んだのですが、入力値が大きくなると正しい答えが出ません。
具体的には1000,5000と入力すると1が出てきたりするのですがどうすればいいのでしょうか。

C

1#include<stdio.h> 2int main(void){ 3 int x,y,z; 4 int a,b,c; 5 int d,e,count=0; 6 7 scanf("%d,%d",&x,&y); 8 for(z=x+1;z<y;z++){ 9 if(z%2!=0){ 10 a=z; 11 b=0; 12 c=1; 13 while(a>0){ 14 b=b+(a%2)*c; 15 a=a/2; 16 c=c*10; 17 } 18 d=b; 19 e=0; 20 while(d>0){ 21 e=e*10+d%10; 22 d=d/10; 23 } 24 if(b==e) count++; 25 } 26 } 27 printf("%d",count); 28}

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

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

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

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

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

guest

回答3

0

こんにちは。

お使いのコンパイラにもよりますが、オーバーフローしていると思います。
例えば、zに4096が入っている時を考えます。
これは、2進数で表記すると、0001 0000 0000 0000となります。(Windowsの電卓でプログラマ・モードを使うと簡単に表示できますよ。)

suzariaさんは、これを変換してbへ入れていますが、その時、10進数で表現した時にまるで2進数であるかのように見えるよう変換されてます。(10進数の各桁が0 or 1となる。) なかなか工夫されてますね。

さて、z=4096の時、10進数で表現するとb=1,000,000,000,000となっています。
このbを再度2進数で表現すると、1110 1000 1101 0100 1010 0101 0001 000 000 000となり、全部で40ビット必要とします。
int型は32ビットしか記録できないコンパイラが多いですので、オーバーフローしている筈です。


C言語は2進数表現をサポートしていませんので、直接2進数で表現しようとするとなかなか面倒です。
学習が目的であれば、2進数を文字列で表現するようなプログラムにすると捗ると思います。
%sで表示できますのでデバッグしやすいですし、結果をstrcmp()で比較できます。もちろん、オーバーフローすることもないです。
文字列領域のバイト数はint型のビット数+1バイトの固定長でできると思います。

投稿2016/04/02 08:08

Chironian

総合スコア23272

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

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

suzaria

2016/04/02 08:54

オーバーフローにも気を付けないといけないのですね... ありがとうございました!
guest

0

ベストアンサー

期待通りの結果にならない原因はChironian さんのご指摘通り、オーバーフローによるものです。

2進数を少し誤解されているようです。int型変数の値は元々2進数で記憶されているので、変換の必要はありません。「2進数表記」で表示させたいということであれば、数値を文字列に変換する、という作業が必要になりますが、ご質問の要件ではその必要はないように思います。

つまり、「2進数変換」は不要で、「ビットの上位と下位をひっくり返す変換」をすれば良いのです。

元の値の最下位ビットを%2で取り出して2で割り、変換先の値は2倍して先ほど取り出した値を足す。これをintのビット数(32)回繰り返せば、ビットをひっくり返すことができます。
ビットをひっくり返した値が作れたら、後はそれを元の値と単純に比較するだけです。

投稿2016/04/02 08:44

catsforepaw

総合スコア5938

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

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

suzaria

2016/04/02 08:55

2進数にしない方法、とてもシンプルで無事計算することができるようになりました。 わかりやすい説明ありがとうございました!
guest

0

すでに回答があるように、オーバーフローしているのが原因とおもいます。
プログラム中では、 数字 15 を 1111(10進) に変換しています。
そのため例えば 4095 は内部では 111111111111 の10進を作ろうとしていて、int の最大数を超えてしまいます。
この 2 進表記見えるような 10 進数への変換をしないコードを書いてみました。

c

1#include<stdio.h> 2// See http://www.harukitchen.com/program/binary.c 3// 2進表記の文字列をつくる 4void binary(char *b, int d) 5{ 6 int i = 0, j = 0, tmp; 7 if (d < 0) return; 8 do { 9 b[i++] = d % 2 + '0'; 10 } while(d >>= 1); 11 i--; 12 13 /* reverse */ 14 while (i > j) { 15 tmp = b[j]; 16 b[j] = b[i]; 17 b[i] = tmp; 18 j++; i--; 19 } 20 21 b[i + j + 1] = '\0'; 22 return; 23} 24 25int main(void) { 26 int x, y, z, z1; 27 int work; 28 int count = 0; 29 30 scanf("%d,%d", &x, &y); 31 for (z = x + 1; z < y; z++) { 32 if (z % 2 != 0) { 33 work = z; 34 z1 = 0; 35 while (work != 0) { 36 z1 = z1 * 2 + work % 2; 37 work /= 2; 38 } 39 if (z == z1) { 40 count++; 41 char buf[1000]; 42 binary(buf, z); 43 printf("%d (%s)\n", z, buf); 44 } 45 } 46 } 47 printf("%d\n",count); 48}

実行例

katoy-MacBook-Pro:tmp katoy$ gcc 1.c katoy-MacBook-Pro:tmp katoy$ ./a.out 0,17 1 (1) 3 (11) 5 (101) 7 (111) 9 (1001) 15 (1111) 6 $ ./a.out 4500,5000 4529 (1000110110001) 4593 (1000111110001) 4617 (1001000001001) 4681 (1001001001001) 4777 (1001010101001) 4841 (1001011101001) 4889 (1001100011001) 4953 (1001101011001) 8

投稿2016/04/02 10:09

katoy

総合スコア22324

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

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

suzaria

2016/04/03 00:50

とてもわかりやすいです! わざわざプログラムを組んでくださり本当にありがとうございました! 参考にさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問