- 締切済み
2進→10進数
2進数から10進数に変換するプログラムを作りたいんですが #include<stdio.h> main() { int a[8],i=0,ans=0,end; start: printf("2進数を10進数に変換するプログラム\n開始する場合は1を入力終了する場合は0を入力してください。\n"); scanf("%d",&end); if(end==1) { goto s1; } else if(end==0) { goto end; } { s1: for(i=0;i<8;i++) { scanf("%d",&a[i]); } for(i=0;i<8;i++) { a[i]=2^i; } for(i=0;i<8;i++) { ans=ans+a[i]; } printf("二進数"); for(i=8;i<=4;i--) { printf("%d",a[i]); } printf(" "); for(i=4;i<=0;i--) { printf("%d",a[i]); } printf("は%dです。\n",ans); goto start; } end: printf("終了します\n"); } 期待した結果が得られないのですがどこが違っているのか教えていただきたいです、お願いします。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- yama5140
- ベストアンサー率54% (136/250)
>どこが違っているのか教えていただきたいです、 for(i=0;i<8;i++) { scanf("%d",&a[i]); // 0, 1 のみを2進数8桁「下位」から入れる( [ 0 ] から [ 7 ]◆へ) } for(i=0;i<8;i++) { a[i]=a[i]*2^i; // 「べき乗」のつもり(未確認) } for(i=0;i<8;i++) { ans=ans+a[i]; // a[i] には、0, 1, 2, 4, 8, 16, 32, 64, 128 のいずれかが入っている▼ } printf("二進数"); for(i=8;i<=4;i--) // 未入力の [ 8 ]◆から出力 { printf("%d",a[i]); // a[i] には、0, 1 が入っているつもり▲ } コメントをつけてみれば・・、少なくとも「べき乗」部分以外は、他人に教えてもらうまでもないですよね。 「べき乗」部分だって、次に printf() 文を入れ結果を出力すれば、2^i では、べき乗にならないことに気づいたはず。 ☆goto 文を使っていることから、お金を出してC言語を勉強しているわけではなく「遊び」と思いますが、自己解決能力をつけることで、より楽しくC言語を遊べるかと思います。 蛇足 http://wisdom.sakura.ne.jp/programming/c/c11.html のようなページもあります。 プログラムって、どのように書こうが「自由」で、他人にとやかく言われる筋合いのないもの、と思います。 エラーが出たって、はたまた main() 関数が void 型であっても、誰にも迷惑かけないし・・。 (希に「規則で決まっている『から』」なんて言う教条主義的な輩もいるけど、規則破ったって、誰にも迷惑かけない) 重要な「警告」を無視し実行したって、結局は、天にしかツバは吐けない。 ☆ただ、ソースを他人に見せる(答案提出など)となると・・。 ↑知っていて損のない情報かと・・。 ---------------------------------------------------------- ☆下のソースでは、2進数8桁を「文字列」で入力しています。 文字 '0'→ 数字 0 http://e-words.jp/p/r-ascii.html 参照 #include <stdio.h> #include <string.h> int main() { int i, ans, iNext; char a[ 16 ]; // 半分しか使わないけど・・たっぷり用意 while( 1 ){ fprintf( stderr, "--- 2進数を10進数に変換するプログラム ---\n" ); fprintf( stderr, " 継続する場合は 1\n" ); fprintf( stderr, " 終了する場合は 0 を入力\n" ); scanf( "%d", &iNext ); if( 1 != iNext ) return( 0 ); // 正常終了 fprintf( stderr, "8桁の2進数を入力してください。\n" ); scanf( "%s", &a ); if( 8 != strlen( a ) ) return( 1 ); // 異常終了 printf( "二進数 " ); for( i= 0; i < 8; i++ ){ printf( "%c", a[ i ] ); if( 3 == i ) printf( " " ); // 4桁区切りで } for( ans = 0, i = 0; i < 8; i++ ){ if( ( '0' != a[ i ] ) && ( '1' != a[ i ] ) ) return( 2 ); // 異常終了 ans += ( ( a[ i ] - 0x30 ) << ( 7 - i ) ); // ans に加算 } printf( " は、10進数で %d です。\n", ans ); } } 注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
>ああ調べてみたらXORだったんですね^^; >すみません。 >何とかがんばってみます! ヒントだけ。 1を0ビット分、左にシフトすると1です。 1を1ビット分、左にシフトすると2です。 1を2ビット分、左にシフトすると4です。 1を3ビット(ry 式で書くと 1 << 0; 1 << 1; 1 << 2; 1 << (ry と言う訳で、もし、「1 0 0 1 0 0 1 0」というように「上位ビットから順に」入力されたら ans = 0; ans <<= 1;ans |= 1; ans <<= 1;ans |= 0; ans <<= 1;ans |= 0; ans <<= 1;ans |= 1; ans <<= 1;ans |= 0; ans <<= 1;ans |= 0; ans <<= 1;ans |= 1; ans <<= 1;ans |= 0; を計算すればよい。 「2のi乗をa[i]に入れて…」とか「ansにa[i]を足して…」とかって計算は不要。なので配列も不要。 「今、入力されたのが、0なのか1なのか」さえ判れば済むと思いませんか? だって「ansを左に1ビットシフトして、最下位に0か1をオアするビットを作ってあげてから、0か1をオアする」ってのを8回やれば済むんだから。 そうすれば、質問者さんのプログラムのように「入力の時は下位ビットから順に入力して、出力の時に上位下位を逆順で表示」のように上位下位を逆にする必要もない。 もう一つ。 1回、2進数を入力して結果のansを表示した後、start:に戻ってもansを0に戻してませんよ。
- asuncion
- ベストアンサー率33% (2127/6289)
C言語において、演算子 ^ はべき乗の意味ではありません。
- asuncion
- ベストアンサー率33% (2127/6289)
>scanf("%d",&a[i]); 変換前は2進数ですので、ここでは0か1の入力を求めている、 という風な理解でよいでしょうか? >a[i]=2^i; この文の意図するところを、文章で書いてみてください。
補足
>>scanf("%d",&a[i]); 変換前は2進数ですので、ここでは0か1の入力を求めている、 という風な理解でよいでしょうか? はい。その通りです。 >>a[i]=2^i; この文の意図するところを、文章で書いてみてください。 すみませんそこはa[i]=a[i]*2^i;にしたつもりでした。 修正したんですが望んだ結果が得られません。 これは二進数の0,1に2のi乗をかけるといった感じなんですが、間違ってますかね?
補足
ああ調べてみたらXORだったんですね^^; すみません。 何とかがんばってみます! 回答ありがとうございました。