二進数は情報系の学問やコンピュータを学ぶ上で必要な知識です。2進数を扱うプログラムも書いてしっかり理解を深めましょう。
この記事はC言語演習問題集の問題の回答です。まだ問題読んでないという方は下記記事の「二進数を計算してみよう」をぜひ見てから読んでください。
C言語応用問題集解答例
#include <stdio.h>
int main(void){
int x;
unsigned long b;
int m;
int i;
int j;
int a;
int input;
printf("二進数に変換する数字は?:");
scanf("%d", &x);
if(x > 512 && x < 0){
printf("対応していない入力です\n");
return -1;
}
input = x;
b = 0;
i = 0;
while(x > 0){
m = 1;
for(j = 0; j < i; j++){
m = m * 2;
}
if(x & m){
a = 1;
for(j = 0; j < i; j++){
a = a * 10;
}
b += a;
x -= m;
}
i++;
}
printf("%dを二進数で表すと%luです\n", input, b);
return 0;
}
表示例
スポンサーリンク
解説
2進数の基礎
まず2進数の基礎を復習しましょう。
2進数とは2を基数とした数値であり、数を1と0のみで表現します。
我々が馴染みあるのは10進数で、10を基数とした数値であり、これは0から9の10種類の数で表現されます。
他にも8進数や16進数などが存在し、それぞれ8を基数・16を基数とした数値となります。
基数変換
数値を基数の各冪乗数の数値単位で分解してみましょう。
これだけだと何を言ってるか分かりにくいので10進数の157の実例を用いて説明します。
157は100が1つ、10が5つ、1が7つ足し合わされた数字として考えることができます。
100は10の2乗、10は10の1乗、1は10の0乗であり、それぞれが基数の冪乗数となっています。
これを数式で表すと、
となります。
まるで囲った部分を左から並べると157です。元が10進数の157なので同じ結果になって何をやっているか分かりにくいかもしれませんが、他の進数に変換する場合も同じ考え方で行うことが可能です。
2進数に変換することとを考えましょう。まず基数の各冪乗数単位に分解してみましょう。
157は128が1つ、64が0つ、32が0つ、16が1つ、8が1つ、4が1つ、2が0つ、1が1つ足し合わされた値として考えることができます。
128から1は全て2進数の基数である2の冪乗数になっています。
これを数式で表すと、
となり、まるで囲った部分を左から並べると、10011101となり、10進数の157を2進数に変換した結果になります。
つまり10進数から各進数に変換するためには、各基数の冪乗数がいくつその値に含まれているかを考えれば良いのです。
スポンサーリンク
解答例プログラムの説明
この解答例はこの考え方に従って10進数を2進数に変換するプログラムになっています。
まずこの部分で2の冪乗数を求めています。iは何乗するかを示す値であり、while文で繰り返すたびに1増やしています。
for(j = 0; j < i; j++){
m = m * 2;
}
これにより2のi乗の値が求まります。
次は条件判断により、入力された10進数に2のi乗が含まれているかどうかを判断しています。
if(x & m){
&は左辺が右辺と同じビットが立っているかを判断する演算子です。
2のi乗は必ず1つだけビットが立っている状態であり、&結果が1であれば入力された数字も同じビットが立っている状態であり、2のi乗を含んでいる数字と判断できます。
逆に結果が0であれば、入力された数字に2のi乗が含まれていない事になります。
この判断文により2のi乗が含まれていると判断した場合は、下記で結果となる2進数を格納するbに10のi乗を足し合わせます。
for(j = 0; j < i; j++){
a = a * 10;
}
b += a;
10のi乗を足し合わせているのは単に便宜上の話です。実際やろうとしているのは2進数の右からi桁目を1にセットしていると考えてもらって良いです。
さらに含まれていた2のi乗の値を入力された数字から減算しています。
x -= m;
最終的に入力された数字が0になれば、2の基数へ分解し終わったと考えることができますので、while文を終了し、結果を出力しています。
独り言
割と簡単にプログラムは作れました。ですが、2進数の数を変数に格納しようとしたのが思ったよりよくなかったですね。unsinged long型でもすぐに桁あふれが発生してしまいました。変数に格納するのではなく、随時1か0をprintfするプログラムの方がやっぱりいいですね。
オススメの参考書(PR)
C言語学習中だけど分からないことが多くて挫折しそう...という方には、下記の「スッキリわかるC言語入門」がオススメです!
まず学習を進める上で、参考書は2冊持っておくことをオススメします。この理由は下記の2つです。
- 参考書によって、解説の仕方は異なる
- 読み手によって、理解しやすい解説の仕方は異なる
ある人の説明聞いても理解できなかったけど、他の人からちょっと違った観点での説明を聞いて「あー、そういうことね!」って簡単に理解できた経験をお持ちの方も多いのではないでしょうか?
それと同じで、1冊の参考書を読んで理解できない事も、他の参考書とは異なる内容の解説を読むことで理解できる可能性があります。
なので、参考書は2冊持っておいた方が学習時に挫折しにくいというのが私の考えです。
特に上記の「スッキリわかるC言語入門」は、他の参考書とは違った切り口での解説が豊富で、他の参考書で理解できなかった内容に対して違った観点での解説を読むことができ、オススメです。題名の通り「なぜそうなるのか?」がスッキリ理解できるような解説内容にもなっており、C言語入門書としてもかなり分かりやすい参考書だと思います。
もちろんネット等でも色んな観点からの解説を読むことが出来ますので、分からない点は別の人・別の参考書の解説を読んで解決していきましょう!もちろん私のサイトも参考にしていただけると嬉しいです!
入門用のオススメ参考書は下記ページでも紹介していますので、こちらも是非参考にしていただければと思います。
https://daeudaeu.com/c_reference_book/