3-6 2進数

ちょっと話は変わりますが、コンピュータでは避けて通れない2進数やビット(bit)、バイト(byte)などの話をしたいと思います。ご存じの方は飛ばしてください。

10進数と2進数

私たちが普段使用している数字は10進数です。その他の2進数などは何が違うのでしょうか。
順番に見ていきましょう。

10進数

私たちが普段使用しているのは10進数です。
10進数では
数値が10になったら桁が1つ上がります。
数値が100になったら桁が2つ上がります。

例えば 10進数の105は
1 ⇒ 3桁目は10の2乗を表しているので 100 の数値の桁
0 ⇒ 2桁目は10の1乗を表しているので 10 の数値の桁
5 ⇒ 1桁目は10の0乗を表しているので 1 の数値の桁
を表していますので、
10進数の105は
100×1 + 10×0 + 1×5 → 125 (10進数)
ということを表しています。

10進数では、1桁に入る数値は0~9ですね。
10進数は10で桁が進むので、10進数なのです

2進数

前記の10進数に対して、2進数では、1桁に入る数値は0~1です。
1桁に2は入れられないので、2進数は2で桁が進むのです
ですから2進数では
数値が2になったら桁が1つ上がります。これは10進数の10に相当します。
数値が4になったら桁が2つ上がります。これは10進数の100に相当します。

例えば 2進数の101ならば
1 ⇒ 3桁目は2の2乗を表しているので 4 の数値の桁
0 ⇒ 2桁目は2の1乗を表しているので 2 の数値の桁
1 ⇒ 1桁目は2の0乗を表しているので 1 の数値の桁
を表していますので
2進数の101は
4×1 + 2×0 + 1×1 → 5 (10進数)
ということを表しています。

ビット(bit)とバイト(byte)

コンピュータの話ではビット、バイトという言葉が頻繁にでてきます。
この説明です。
1ビット(bit)はコンピュータが扱う最小単位で、2進数の1桁を表します。
上図では2進数4桁の領域なので、4bitです。
そして、ビットが8個集まると1バイト(Byte)と呼びます。
1Byte = 8bit です。

8進数

8進数では1桁に入る数値は0~7です。
1桁に8は入れられないので、8進数は8で桁が進むのです

ですから8進数では
数値が8になったら桁が1つ上がります。これは10進数の10に相当します。
数値が16になったら桁が2つ上がります。これは10進数の100に相当します。

例えば 8進数の207ならば
2 ⇒ 3桁目は8の2乗を表しているので 64 の数値の桁
0 ⇒ 2桁目は8の1乗を表しているので 8 の数値の桁
7 ⇒ 1桁目は8の0乗を表しているので 1 の数値の桁
を表していますので
2進数の207は
64×2 + 8×0 + 1×7 → 135 (10進数)
ということを表しています。

16進数

16進数では、1桁に入る数値は0~15です。
ところが、10~15は1桁で書けません。
そのため、10~15はアルファベットの、a~fで表します。
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
を以下のように表現します。
1,2,3,4,5,6,7,8,9,a,b,c,d,e,f
そして、
1桁に16は入れられないので、16進数は16で桁が進むのです

ですから16進数では
数値が16(fの次)になったら桁が1つ上がります。これは10進数の10に相当します。
数値が256になったら桁が2つ上がります。これは10進数の100に相当します。

2 ⇒ 3桁目は16の2乗を表しているので 256 の数値の桁
0 ⇒ 2桁目は16の1乗を表しているので 16 の数値の桁
b ⇒ 1桁目は16の0乗を表しているので 1 の数値の桁
を表していますので
16進数の20bは、bは11のことなので
256×2 + 16×0 + 1×b
= 256×2 + 16×0 + 1×11 → 523 (10進数)
ということを表しています。

10進数と2進数、8進数、16進数のまとめ

20までの2進数~16進数を比較してみます。

10進数2進数8進数16進数
1000000010101
2000000100202
3000000110303
4000001000404
5000001010505
6000001100606
7000001110707
8000010001008
9000010011109
1000001010120a
1100001011130b
1200001100140c
1300001101150d
1400001110160e
1500001111170f
16000100002010
17000100012111
18000100102212
19000100112313
20000101002414

上記の表の印刷プログラムを参考に載せておきます。
尚、2進数のprintfの書式はありませんので、自作する必要があります。
この部分は、シフト演算を学習するまでは理解できませんので気にしないでください。

しかし通常は以下の方法で、8進数のプリントを手動で簡単に2進数に変換できます。
2進数の1桁は1bitで表せますが、
8進数の1桁は7までなので、3bitで表せます。( 8進数 7 = 2進数 111)
ということは、
8進数の207は
それぞれの桁を3bitの2進数で表すと、2進数に変換したことになります。
3桁目 2(8進数) → 010 (2進数)
2桁目 0(8進数) → 000 (2進数)
1桁目 7(8進数) → 111 (2進数)
→010000111
確認してみてください。

うん? と思ったら10進数の説明とよ~く、見比べてくださいね。
コンピュータ内では2進数が使われます。
電気が通っていれば1で、通ってなければ0という2値で表せるからです。

表の印刷プログラム

#include <stdio.h>

void bin_print(int, int , char[]);

/*********************************************
 * サンプルプログラム                        *
 *********************************************/
int main()
{
 	int dec; 
 	int keta=8; 
	char binc[keta];

	printf("10進数	2進数	  8進数	16進数\n");
	for (int i=1; i<=20; i++) {
		bin_print(i, keta, binc);
		printf("%2d      %s  %02o    %02x\n", i, binc, i, i);
	}
	return 0;
}

void bin_print(int dec, int keta, char binc[])
{
/*********************************************
 * 整数を2進数の文字列に変換する             *
 * (INPUT)   dec   入力値の10進数            *
 * (INPUT)   keta  2進数に変換する桁数       *
 * (OUTPUT)  binc  2進数の文字列             *
 *********************************************/
    unsigned char cw;

    for (int i=0; i<keta; i++) {
		cw = (dec >> i) & 0x01;
		binc[(keta-1)-i] = (cw > 0) ? '1' : '0';
    }
    binc[keta] = 0x0;
    return;
}
実行結果
10進数  2進数     8進数 16進数
 1      00000001  01    01
 2      00000010  02    02
 3      00000011  03    03
 4      00000100  04    04
 5      00000101  05    05
 6      00000110  06    06
 7      00000111  07    07
 8      00001000  10    08
 9      00001001  11    09
10      00001010  12    0a
11      00001011  13    0b
12      00001100  14    0c
13      00001101  15    0d
14      00001110  16    0e
15      00001111  17    0f
16      00010000  20    10
17      00010001  21    11
18      00010010  22    12
19      00010011  23    13
20      00010100  24    14

printfの使い方をよく見てくださいね。
できれば、コピペして実行や変更をしてみてください。
慣れが、上達の秘訣です。

コメント

タイトルとURLをコピーしました