ビット、バイト、2進数、16進数

このページで説明すること

このページでは、コンピュータの基礎の基礎、「そもそもどうやって電気で数値を表現するのか?」ということについて説明します。

これを知らなくてもJavaScriptでプログラムを書くことはできないことはないのですが、この手の知識はコンピュータを扱ううえでなんだかんだで必ず出てくる話です。プログラムを書かない人でも、自分のスマホのメモリが何ギガとか、1か月で使用できる通信量が何ギガとかといったことは意識するでしょう。この「ギガ」というのはギガバイトの略で、(だいたい)10億バイト(byte)を意味し、そして1バイトは8ビット(bit)を意味します。このビットとかバイトとかを説明するのがこのページの目的です。

電気で数を表す

コンピュータは電気で計算するので、まずは電気で数を表す必要があります。

電圧で数を表す(たとえば1ボルトなら1、2ボルトなら2とする)という方法もあり、そのような計算機はアナログコンピュータといってかつては使われていたようです(Wikipedia)。アナログコンピュータは、たとえば「3.3443588」のような中途半端な数値も直接的に表現できますが(例に出した1ボルトが1のアナログコンピュータなら、3.3443588ボルトにすればよい)、「隣の部屋で掃除機を使い始めたら電圧が下がって100が99.7になってしまった」ということが起こり得ます。それに対し、今普通に使われているコンピュータは「デジタル」コンピュータです。デジタルコンピュータでは、電圧は固定にして(昔は5ボルトでした)、電気を流せば1、流さなければ0というようにして0と1を表現します。これなら、5ボルトが0ボルトになってしまうような極端な電圧の変動がない限り、正確な計算を行うことができます。0と1の2種類の数字だけ表現できてもしょうがないのでは、と思えるかもしれませんが、0と1の組み合わせでもっと大きな数も表すことができます。そこで登場するのが2進数です。

2進数

我々が普段使っている数値の表現方法は、10進数と呼ばれるもので、0~9の10種類の数字を使い、9にさらに1を足すと次の桁に繰り上がります。2進数は、0~1の2種類の数字を使い、1にさらに1を足すと次の桁に繰り上がります。

0から63までの、10進数と2進数の対応表が以下です。

表1: 10進数と2進数の対応表
10進数2進数10進数2進数10進数2進数10進数2進数
0016100003210000048110000
1117100013310000149110001
21018100103410001050110010
31119100113510001151110011
410020101003610010052110100
510121101013710010153110101
611022101103810011054110110
711123101113910011155110111
8100024110004010100056111000
9100125110014110100157111001
10101026110104210101058111010
11101127110114310101159111011
12110028111004410110060111100
13110129111014510110161111101
14111030111104610111062111110
15111131111114710111163111111

2進数にすると桁は増えますが、0と1だけでどんな数でも(今のところ整数限定ですが)表現できる、ということがわかるでしょう。

10進数なら、右端から、1の位、10の位、100の位、……があって、たとえば123という数値は、それぞれの桁の数字に位の数をかけて足し合わせ、1×100 + 2×10 + 3×1として算出することができます。

図1: 10進数における各桁の数と全体の値

2進数では、桁ごとに値が2倍になるので、右端から1の位、2の位、4の位、8の位、16の位、32の位、64の位……があって、たとえば1111011という数値は、それぞれの桁の数字に位の数をかけて足し合わせ、1×64 + 1×32 + 1×16 + 1×8 + 0×4 + 1×2 + 1×1 = 123のようにして値を算出することができます。

図2: 2進数における各桁の数と全体の値

2進数の1桁のことを、ビット(bit)と呼びます。ビットの取りうる値は0か1かのいずれかです。

コンピュータでは、通常、8ビットをひとつの単位としています。8は2進数なら1000できりがいいこと、8ビットなら0~255の256通りの数が表現できてある程度の用途(英数字の1文字を表すとか)ならこれで足りることが理由だったのだろうと思います。この8ビットのかたまりのことをバイト(byte)と呼びます。

スマホのメモリが何ギガバイトとか、1か月の通信料が何ギガバイトとか言う時の「バイト」は、この8ビットのことです。

0~255までの数値しか表せないのでは困るよ、と思うかもしれませんが、そういう場合は2バイトとか4バイトとかを組にして使います。2バイト(16ビット)なら0~65,535、4バイト(32ビット)なら0~4,294,967,295を表現できます。

メモリとアドレス

現在のコンピュータのメモリ(主記憶)は、ダイナミック※1RAM(ラム)と呼ばれるもので、微小な蓄電器(コンデンサとかキャパシタとか呼びます)の集合体です。この蓄電器の充電の有無で、1か0かを表現します。

私が今、このページを書くのに使っているノートパソコンは、メモリを8ギガバイト積んでいます。これはつまり、だいたい8,000,000×8ビット、つまり64,000,000,000(640億個)のキャパシタが載っている、ということです。このパソコンは2015年に買ったものなので、今となっては8ギガバイトというのは正直しょぼいのですが、それにしたって大変な数だと思います。すごい時代になったものです。

メモリには、8ビット(1バイト)を単位にアドレスが振られています。メモリの内容を読み書きする際は、このアドレスを使って、どこのメモリの内容を読み書きするのかを指定します。

図3: メモリとアドレス

キロ、メガ、ギガ

1キロメートルといえば1000メートルですし、1キログラムといえば1000グラムです。つまり、キロといえば、普通は1000倍を意味します。そして、そのさらに1000倍がメガ、メガのさらに1000倍がギガです。さらにその上はテラ、ペタ、エクサ……と続きます。下に表にしました。

表2: 国際単位系(SI)の接頭辞
名前 記号 大きさ
キロk103
メガM106
ギガG109
テラT1012
ペタP1015
エクサE1018
ゼタZ1021
ヨタY1024

なので、1ギガバイトといえば1000×1000×1000で10億バイト――と単純に言ってしまえないのがこの業界の面倒くさいところです。

1000というのは、人間にとっては「切りのいい」数字ですが、2進数を使うコンピュータにとってはあまり切りのいい数字ではありません(10進数の1000を2進数で表せば、1111101000です)。そこで、メモリの容量などは、1キロバイトといえば通常1024バイトを意味します。10進数の1024は、2進数なら10000000000で切りがよいからです。

コンピュータではメモリのアドレスを示すのにも2進数を使います。たとえばアドレスを示すのに16ビット使うとすると、表現可能なアドレスは0から(2進数の)1111111111111111までで、これは10進数なら0~65,535までの65,536通りとなります。普通の数え方なら65,536は「約65キロバイト」でしょうが、65,536は1,024×64なので、メモリの容量としては、これを64キロバイトと数えます。

メガやギガも話は同じで、メガはキロの1024倍、ギガはメガの1024倍です。何年か前までは、「32ビットパソコン」が主流で、これはメモリのアドレスを32ビットで表現していました。これで表現できるアドレスは0~4,294,967,295で、これが4ギガバイトです。「32ビットのPCにはメモリは4Gバイト以上積めない」というのはそういう意味です。いまどきはアドレスを64ビットで表現する64ビットパソコンが普通なので、これなら264バイト、ざっと1680万テラバイトのアドレスを表現できます(とはいえ、実際の64ビットパソコンでは、回路の節約のためそこまで多くのメモリは積めません。現状ではその必要もないでしょう)。

――面倒なのは、メモリの容量はこのように1024倍単位で表記するのに対し、ハードディスクの容量などは、カタログスペック上は1000倍単位で表記することもある、ということです。ただし、Windows上で容量を確認すると1024倍単位で表示されるので、「カタログより容量が少ない! サギでは?」という話になったりするわけです。

さすがに1,000倍ごとの単位と1,024倍ごとの単位とを同じキロバイト、メガバイト、ギガバイトと呼んでいたのでは紛らわしいので、1998年にIEC(国際電気標準会議)が1,204倍ごとの単位を表す新たな接頭辞を決めました。キロバイト(KB)の代わりにキビバイト(KiB)、メガバイト(MB)の代わりにメビバイト(MiB)を使うというものです。

表3: IEC(国際電気標準会議)が決めた2進接頭辞
名前 記号 大きさ
キビ(kibi)Ki210
メビ(mebi)Mi220
ギビ(gibi)Gi230
テビ(tebi)Ti240
ペピ(pebi)Pi250
エクスビ(exbi)Ei260
ゼビ(zebi)Zi270
ヨビ(yobi)Yi280

たとえば1000倍を示す「キロ」(kilo)から先頭の2文字を借りて、それに2進数(binary)を示す「bi」を付けて1024倍を示す接頭辞が「キビ」(kibi)です。記号としては略して「Ki」を使います。

しかし、これが決められてから20年以上が経ちましたが、あまり普及していないようです。

16進数

ここまで書いてきたように、コンピュータは内部的には2進数を使います。ただ、2進数は、人間にとっては桁数が多すぎて扱いにくいものです。

といって、2進数を毎回10進数に読み替えるのは、暗算でやるのはなかなか大変です。そこで登場するのが16進数です。

2進数を10進数に読み替えるのが大変なのは、2進数と10進数では桁上がりのタイミングが異なるためです。2進数の「111001」は、32+16+8+1ですが、この計算では桁上がりのある足し算を何度かしなければいけません。桁数が増えればもっと大変でしょう。その点、16は2進数で「10000」なので、ひと桁で0~15までの16種類の数を示す16進数なら、2進数を4桁ずつ区切って変換すればすみます。

「ひと桁で0~15までの16種類の数を示す」といっても、通常使う数字は0~9しかないので、アルファベットのA~Fを使って10~15の値を示します。

たとえば「11010011」という2進数を16進数に変換すると、下図のように、D3になります。

図4: 2進数から16進数へ

0から63までの、10進数、2進数、16進数の対応表を以下に載せておきます。

表4: 10進数、2進数、16進数の対応表
10進数2進数16進数10進数2進数16進数10進数2進数16進数10進数2進数16進数
00016100001032100000204811000030
11117100011133100001214911000131
210218100101234100010225011001032
311319100111335100011235111001133
4100420101001436100100245211010034
5101521101011537100101255311010135
6110622101101638100110265411011036
7111723101111739100111275511011137
81000824110001840101000285611100038
91001925110011941101001295711100139
101010A26110101A421010102A581110103A
111011B27110111B431010112B591110113B
121100C28111001C441011002C601111003C
131101D29111011D451011012D611111013D
141110E30111101E461011102E621111103E
151111F31111111F471011112F631111113F

数値を16進数で表記する際は、それが16進数であることを示すために頭に「0x」を付けることがあります。つまり「0xD3」のように表記します。これは元はC言語の表記法なのですが、本ページのように人間が読むための文章でも結構使われますので覚えておくとよいでしょう。

公開日: 2021/06/20



次のページ | ひとつ上のページに戻る | トップページに戻る