コンピュータのある種の進歩は、電子回路の動作を0と1で表現すればいいというところから始まった。つまりは、2進数上で考えたことがそのまま電子回路に置き換えることができる。ならば、機能面での設計は2進数で考えればいいことになる。そこで、2進数を突き詰めて考えてみよう。 普段使っている10進数は、数量を表すのに、0〜9の数字を使って表現をする。もちろん、0、1、2…と数字の出てくる順序は決められているわけだ。9より大きな数は桁上がりをして、9より1多い数を10と記述する。…などと、この辺りは整数論という数学の分野があって、一部の人には「面白い」と思わせる分野があるので、詳しく知りたい人はそちらをじっくり勉強してもらおう。ただ、整数というある意味では一般人にとって当たり前のものを、ことさらとりたてて論理的にどういうものかを考えるのは実はけっこう難しいものである。深く考えなくてもいいくらいにみんなの頭の中は構成されている。それはそれで効率的なのであるが、コンピュータの動きを追うときに、どうしても、2進数、8進数、16進数というものが出てきてしまうので、やはり10進数以外にも頭が働くようになっていることが望ましいのである。
さて、2進数では、使う数字は0と1だけである(もっとも2通りでいいのなら、AとBや5と9でもいいのだが、10進数のサブセットを使うのは自然な成りゆきだろう)。だから、0、1と数えると、もう1の位の数字がなくなってしまうので、その次は桁上がりして10となる。そして、11。その次はまたまた位が上がって100となる。10進数に比べるとどんどんと桁が上がってしまうのだが、それは仕方ない。ここで、表現している数値が何進数なのかを明確にするために、2進数の場合には、後ろに「B」という文字を追加する。なにもなければ、10進数としよう。となると、1=1B、2=10B、3=11B、4=100B、5=101B、6=110B、7=111B…となるわけだ。 すごく当たり前のことだが、2+3=5である。ここで、10B+11Bを10進数を計算するときのように普通に考えてみよう。最下位は0+1だから1となるが、これはまあいいだろう。そして、下から2番目の位は、1+1だから2…ではなく、10Bになるから、0が残って、1は位が上がる方に加算される。つまり、10B+11B=101Bとなるわけだ。当たり前だが、101Bは5である。つまり、数の計算は、10進数でも、2進数でも同じ結果になるわけだ。現在地球上にある大陸の数を10進数で書けば5だけども、2進数で書けば101Bだというだけのことである。まあでも、ここ段落で書いたことはけっこう難しい。実は、原稿を書きながら間違えていた(笑)。「2進数も10進数と同じだ」とは言ってもその同じができないのが人間である。いずれにしても、夜に眠れないときに物事を2進数で考えれば、すぐに眠ることができるに違いない。(ところで、「下から2番目の位」としたが、10進数的な意味でいえば「10Bの位」と言ってもいいかもしれない。だけど、これは十の位じゃない。十というのは、2×5の数だからだ。10Bの位はさしずめ「イチゼロビーのくらい」としか言い様がないか…などと考えていると、すぐに眠くなる。)
2進数一桁を取り扱えることを「ビット」と呼ぶ。たとえば、電子回路で0か1かを記憶できるものがあれば、それは1ビットだ。また、0か1かを伝送できる経路もやはり1ビットという。たった1ビットでは、何もできそうにないのだが、やはり計算機械として目指して作られたコンピュータだけに、数値計算をできる点を目指したのは当然のことだ。気の早い方は8つ並べて8ビットを1バイトと…と言いたいところだが、もう少しかいつまんで話をしたい。 いずれにしても、1ビットを並べてみれば、0と1しか扱えなかったものが、2ビットだと、0と1と2と3が扱えるようになる。つまり、4通りの情報が扱える。3ビットだと8通り、4ビットだと16通りということになる。これは、数学的な話になるが、ビット数と何通りの状態を使えるかということは、2のビット数乗で求めることができる。つまり、2^3=2×2×2=8ということである。 ここで、10進数に対応する2進数の記述を、ビットの状態と同一であるとみなすことにしよう。こういうことは意外に考えの外にある人がおおいのだが、ちょっと心に留めていただきたい。ここで、1という数字は2進数の1B、6という数字は110Bであるとするということにしたい。極端に言えば、1は101B、2は110Bなどとばらばらに割り当ててもいいのだが、ここでは簡単のために、10進数に対応した2進数の表記をそのままビットに当てはめるとする。当たり前のことのようだが、実はコンピュータの中はこうした「そのまま当てはめる」をやっていないことが多いのである。こうした応用は今後じっくり紹介する。 ところで、世間一般の計算は10進数で行っている。会社の決算で記録的な売上を達成したと思ったら2進数で書いてた…なんてことはありえない(やってはいけませんよ!〜誰もしないって…)。だから、コンピュータの計算を10進数でやるべきだと考えるのはある種の自然な考え方だ。今でも、電卓はそうした考え方で動いているようだが、パソコンは全く異なるやり方になっている。だが、初期のころは「数値計算は10進」というのが基調にあったわけだ。そうすると、10進数ひと桁を表現するには、2^3=8、2^4=16ということで、4ビットあればいいということになる。ここで「4ビット」ということは、すでに機械的に4桁を用意していることを意味している。だから、0は0000B、1は0001B、2は0010B、3は0011B、4は0100B…8は1000B、9は1001Bとなる。数値は先頭の0を省略することが多いが、ビットとして表現するときには、ビット数を明確にするために、頭の0も省略しないことが多い。しかしここで容易に分かるように、2進数で言えば、1010B〜1111Bまでの数値に対応する10進数の値はない。1010Bは10だろうと思うかもしれないけど、4ビットで10進数ひと桁を表現するのから、10は存在しない。つまり、6つほど使わない4ビットの表現が残ってしまうが、これは良しとして、10進数を扱おうというわけである。ならば、たとえば、1億までの計算ができるためには、10進数で言えば、9桁必要だから、4ビットの計算機能を9つ用意すればいいということが言える。こうした考えが初期の計算機の中には存在したのである。
先に言ってしまったが、8ビットのことを1バイトと呼んでおり、8ビットがコンピュータにとって一種のマジックナンバーと化している。もちろん、8が2倍の2倍の2倍という切りのいい感じではあるけど、なぜ8ビットなのだろうか。これはいろいろな側面が考えられるが、1つは文字コードの点がある。文字コードは別の機会に説明するが、今回はこの側面はちょっと排除したい。今は8ビットが主流ではあるが、60年代あたりには、そうした基本的なビット長が9ビットというものもあった。コンピュータでは数字を扱うだけではなくなっており、これも別の機会に説明するが、プログラムを内蔵するようにもなっていたのである。そうしたいろいろな理由から4ビットですべて動かすという考え方にはならず、ビット数は増えていったわけだが、結果的にIBMの大型コンピュータが8ビットであったというのがおそらく現在の8ビットに行く流れの1つではないかと思う(ちょっと元資料の出所が分からないあやふやな記憶なのだが…)。 一方、現在のマイクロプロセッサの起源と言えば、インテルの4004チップだ。嶋正利とテッドホフによる設計で、有名なのはたくさんの桁の計算をやるために4ビットの計算機能を桁の数だけ繰り返すことで、大きな数値までの計算ができるようになるということで、「4ビットアーキテクチャ」というものが作られたのである。しかしながら、このマイクロプロセッサを、当時の大型計算機のアーキテクチャに近付けることをおそらくインテルは考えたのであろう。即座に8ビットのアーキテクチャを設計し、8008、8080、さらに16ビットへと拡張して、8086の登場となる。だが、最初に4ビットだから、拡張したら8ビットとなるという単純なものではないかもしれないが、やはり4ビットを最初に決めたところは大きく影響していると考えられる。 なぜ8ビットかという問いに対する答えは、他にもいろいろな要因を説明しないといけないし、さらに言えば、結論らしきものは大変複雑になると思う。だけど、最初に「2進数」と決めた段階で、コンピュータの中身はすべて2の倍数で完結する運命にあるのじゃないかとも思われる。
ところで久しぶりに本棚にあるZ80のリファレンスを見てみた。日本電気のPC-8001とか、シャープのMZ-80といった往年のマシンで使われていたCPUである。アーキテクチャは8ビットであるが、その中には10進数での計算を行う機能がCPUレベルで組み込まれてる。4ビットで10進計算を行うという時代の流れを引き継いでいるのが分かる。 2進数の世界はまだまだこんなものではない。もう少し、コンピュータの動作に踏み込んで、引き続いて01の世界を体験していただこう。 |