目次
サンプル・プログラム
ビットとバイト
1ビットは、0と1の2種類の値を表すことができる。
2ビット(2進数2桁)なら、00, 01, 10, 11の4種類の値を表すことができる。
3ビット(2進数3桁)なら、000, 001, 010‥‥111の8種類の値を表すことができる。
一般に2進数N桁は、 \( 2^N \) 種類の値を表すことができる。
8ビットを 1 バイト(byte)と呼ぶ。
1バイトは8ビットだから、 \( 2^8=256 \)種類の値を表すことができる。
2進数と10進数の変換
18を2で割り、商の9を下の段に書き、剰余の0を右に書く。
9を2で割り、商の4を下の段に書き、剰余の1を右に書く。
これを繰り返し、下から順に並べる。
つまり \( 18_{(10)}=010010_{(2)} \) となる。
\( 010010_{(2)}=2^5 \times 0 + 2^4 \times 1 + 2^3 \times 0 + 2^2 \times 0 + 2^1 \times 1 + 2^0 \times 0 = 18_{(10)} \)
と計算する。
10進数と2進数、8進数、16進数
2進数表記は \( 0b \) または \( 0B \) ではじめる。b は binary(2進数)の頭文字だ。前述のように、コンピュータ内部ではデータは2進数として保持されていることから、そうしたハードウェア寄りの場面で2進数を使うことは多い。
8進数表記は \( 0o \) または \( 0O \) ではじめる。数字の先頭が \( 0 \)(ゼロ)の時にも8進数と解釈されるので注意すること。o は octal(8進数)の頭文字だ。現在、プログラミングで8進数表記を使うことは滅多にないのだが、かつてのメインフレームでは、今と違ってデータの長さが36ビットであったため、それを区切りよく表現できる8進数が使われたという歴史的経緯があり、仕様に残っている。
16進数表記は \( 0x \) または \( 0X \) ではじめる。x は hexa(16進数)から x をとっている。前述のように1バイトは8ビットであるから、16進数の1桁で表現することができ都合がいい。文字コードなどバイト列を表記するときには、16進がよく使われる。
76: //2進数表記と加算
77: let bin1 = 0b1111000;
78: let bin2 = 0b11;
79: let bin1s = '0b' + bin1.toString(2); //bin1を文字列にする
80: let bin2s = '0b' + bin2.toString(2); //bin2を文字列にする
81: let dec = bin1 + bin2;
変数の内部では2進数で保持されるのだが、これを表示しようとすると原則として10進数で表示するため、toStringメソッドを使って2進数に変換してやる。メソッドについては「5.2 プロパティ、メソッド、イベントハンドラ」で解説するが、ここではNumber型の変数に .toString(N) を付けると、Nで指定した進数の文字列として変換してくれると覚えておこう。なお、toStringメソッドは頭に \( 0x \) を付けてくれないので、これはプログラム側で付けるようにした。
変数 bin1 と bin2 の加算は、普通の演算式を書けばよい。
87: //8進数表記と減算
88: let oct1 = 0o2333;
89: let oct2 = 0o11;
90: let oct1s = '0o' + oct1.toString(8); //oct1を文字列にする
91: let oct2s = '0o' + oct2.toString(8); //oct2を文字列にする
92: dec = oct1 - oct2;
98: //16進数表記と乗算
99: let hex1 = 0xB2B;
100: let hex2 = 0x13;
101: let hex1s = '0x' + hex1.toString(16).toUpperCase(); //hex1を文字列にする
102: let hex2s = '0x' + hex2.toString(16).toUpperCase(); //hex2を文字列にする
103: dec = hex1 * hex2;
16進数の文字列に変換するのに toStringメソッドを利用するのも同じだが、アルファベットを小文字で返すので、読みやすいように toUpperCaseメソッドを使って大文字に変換してやる。少しややこしいのだが、hex1.toString(16) はString型の変数になっており、このString型の変数に .toUpperCase() を付けると、英小文字を大文字に変換してくれる。
乗算は、普通の演算式を書けばよい。
ちなみに、上表「10進数と2進数、8進数、16進数の対比表」は、手書きで作るのが面倒だったので(誤記したくなかったし)、 JavaScript を使って表示している。興味をお持ちの方は、この記事のソースを読んでみていただきたい。
2のべき乗
べき乗 | 10進数 |
---|---|
1 | 2 |
2 | 4 |
3 | 8 |
4 | 16 |
8 | 256 |
10 | 1,024 |
12 | 4,096 |
14 | 16,384 |
16 | 65,536 |
キロ、メガ、ギガ
4004とセットで発表されたメモリ 4002 は320ビット(32バイト)のデータを記憶することができた。
メモリICは、内部に電位を蓄えることでデータを保持する。この回路が小さくなればなるほど、同じ大きさのICでより多くのデータを保持することができるようになる。
インテルは、CPUより早くメモリICを開発しており、1969年(昭和44年)には256ビットの 1101 を、1970年(昭和45年)10月には1024ビットの 1103 を発売した。これが大成功となった。1971年(昭和46年)にはNECが1024ビットのメモリICを開発史、1973年(昭和48年)にはMOSTEKが4096ビットのDRAM(メモリICの一種)を開発する。その後、DRAMの容量は倍々ゲームで大きくなってゆく。
メモリ容量の桁数はあっという間に大きくなっていった。4096ビット=512バイトであるが、8で割っただけでは追いつかない。そこで、3桁区切りでカンマを付ける10進数のように、2の10乗で割り算し、SI単位系の接頭辞を付けることにした。
\( 4096 \div 2^{10} = 4 \)、つまり 4096ビット=4Kビット のように表記するようになった。
ここで注意してほしいのは、10進数と異なり1000倍毎ではなく、1024倍毎に接頭辞が付くということ。もう1つは、ビットとバイトの読み間違えに注意すること。4096ビット=4Kビット=0.5Kバイト となる。
大きさ | 名 称 | 記号 | 意 味 | 値 | |
---|---|---|---|---|---|
250 | ペタ | peta | P | ギリシャ語のpenta、5の意味。 | 1,125,899,906,842,624 |
240 | テラ | tera | T | ギリシャ語のteras、怪物(monster)の意味。 | 1,099,511,627,776 |
230 | ギガ | giga | G | ギリシャ語のgigas、巨人(giant)の意味 | 1,073,741,824 |
220 | メガ | mega | M | ギリシャ語のmegas、大きい(great)の意味 | 1,048,576 |
210 | キロ | kilo | K | ギリシャ語のchilioi、1000の意味 | 1,024 |
接頭辞の一覧表を作成する
77: <script>
78: //ページのロード時に実行
79: window.onload = function() {
80: //配列
81: let prefix = [
82: [10, 'Kilo'],
83: [20, 'Mega'],
84: [30, 'Giga'],
85: [40, 'Tera'],
86: [50, 'Peta'],
87: ];
88:
89: //<table>タグを代入する変数
90: let ss = '<caption>接頭辞</caption>';
91: ss += '<tr><th>大きさ</th><th>名称</th><th>値</th></tr>';
92:
93: //計算で値を求める
94: for (let i = 0; i< prefix.length; i++) {
95: let n = Math.pow(2, prefix[i][0]);
96: ss += '<tr><td class="index">2<sup>' + prefix[i][0].toString(10) + '</sup></td>';
97: ss += '<td class="center">' + prefix[i][1] + '</td>';
98: ss += '<td class="right">' + n.toLocaleString() + '</td></tr>';
99: }
100:
101: //結果を表示
102: document.getElementById('prefix').innerHTML = ss;
103: }
104: </script>
コラム:算数とN進数
小学生にプログラミングを学ばせるなら、その前に、基本的なデータの扱いを算数の時間に盛り込み、暗算で、ある程度のデータ変換ができるような基礎力を身に付けるようにしてはどうだろうか。
さらにRAW画像になると――メーカーによって異なるが、たとえば14ビットRAW画像なら―― \( 14bit^3 = 1,6384^3 = 4,398,046,511,104 \)(約4兆3980億)色と計算できる。これは自宅の液晶ディスプレイで表現できない色数だから、現像で工夫をしなければならないという流れになる。
ICT機器を常に携行している子どもたちの世代こそ、自然に2進数の計算結果が頭に思い浮かぶような能力を身につけてほしい。
コラム:メインフレーム
1946年(昭和21年)に完成した史上初の実用コンピュータ「ENIAC」は、36ビットを1つの単位(ワード)として計算することができた。
ENIAC の開発者たちが、商用向けとして1951年(昭和26年)に完成させた UNIVACは最初のメインフレームとされており、ENIAC の設計を受け継ぎ、36ビットが1ワードだった。
メインフレームは、大型電算機、汎用機とも呼ばれ、1960年代から1980年代にかけ、企業や政府などの基幹業務処理に用いられた。現代のパソコンやスマホに比べたら、計算能力も記憶容量も貧弱なものだったが、オフィスの一角を占有し、重量も数トンあった。ただ、現在のサーバPCのように莫大な熱を放出する物ではなかったので、サーバルームのように冷房をキンキンにかけた部屋ではなく、一般的な事務スペースに設置できた。
1970年代に入ると、パソコンの販売が始まる。当初は、System/360 が扱う最小単位の8ビット(1バイト)を処理する非力なものだったが、瞬く間に16ビット、32ビットとモデルチェンジし、メインフレームと遜色のないデータ処理能力を獲得し、その市場を奪っていった。
21世紀に入り、政府や金融系の一部の基幹業務系にメインフレームが残っているが、それも近いうちにパソコンに取って代わられるだろう。
また、2進数⇔10進数の相互変換も筆算でできるようにしておこう。