9. コンピュータは情報をどのようにメモリに保持するのか?

コンピュータ上では、すべてがビット列として保存されていることは 御存知だと思います(二進数というのは、一連の小さなオン・ オフのスイッチと考えることができます)。 ここでは、そうしたビットによって、コンピュータ上で扱われる 文字や数字がどのように表されているのかを説明します。

説明に入る前に、まずコンピュータのワードサイズ (word size) について 理解する必要があります。ワードサイズとは、そのコンピュータ上で利用されて いる、情報をやり取りするための単位のことです。技術的に言うと、これは プロセッサのレジスタ (registers) の幅のことであり、レジスタとは、プロセッサ が計算や論理演算を行う際にその情報を格納する場所です。コンピュータには ビットサイズがあると書かれている場合 (たとえば、それらを 32-bit や 64-bit コンピュータなどと呼んでいる場合)、それはコンピュータのワードサイズのこと を言っているわけです。

(386 や 486 および Pentium PC を含む) 大部分のコンピュータは、32 bit の ワードサイズとなっています。古い 286 のマシンは、16 ビットのワードサイズ でした。旧式のメインフレームだと 36 bit ワードのものがよくあります。 いくつかのプロセッサでは (たとえば、旧 DEC 現 Compaq が出している Alpha などは)、64 ビットのワードサイズとなっています。64 bit ワードは、これから 5 年 ほどの間には、もっと一般的なものになるでしょう。Intel は、Pentium シリーズ のチップを "Itanium" と呼ばれる 64 bit チップに置き換えよう計画しているから です。

コンピュータは、メモリを、ゼロからそのマシンのメモリサイズの上限に該当する 値までの番号を振った、一連のワードの並びとして見ています。このメモリサイズの 上限の値というのは、ワードサイズによって決まります。286 などの 旧式のマシン用のプログラムが大容量メモリを管理するのに、かなり無理なこじつけ を使わなければならないのはそのためです。ここではそうした こじつけの仕組みについては述べませんが、年輩のプログラマは、いまだにこれが 原因でうなされていたりします。

9.1. 数字

整数は、プロセッサのワードサイズに応じて、ワードか、もしくはワードのペア によって表現されています。32 bit マシンでは、ワードが最も基本的な整数の 表現単位となっています。

整数の計算は、二進数の計算と似ていますが、実際は少し異なります。 純粋な二進数では、下位ビットから順に 1, 次に 2, そして 4 等を 表しますが、正負の符合付き数字は、2 の補数 (twos-complement) という表記で表されます。最上位ビットは、符合ビット (sign bit) であり、このビットを使って負の値がつくられます。そして、負の数字はすべて 、正の数字のビットを全部逆転させて、それに 1 を加えることで変換可能です。 32 bit マシン上で整数の値の幅が、-2^31 から 2^31 -1 (ここで、^ の 記号は、べき数の演算子を表し、2^3 = 8 です) までしかないのは、そのため です。32 bit 目のビットは、正負符合用に使われるのです。

コンピュータ言語のなかには、符合なし演算 (unsigned arithmetic) ができるものもあります。その場合は、ゼロと正の数だけを使った 通常の二進数演算となります。

大部分のプロセッサやコンピュータ言語のいくつかは、浮動小数点 (floating-point) 数での処理が可能です(この機能は、最近の(PC 用)プロセッサ チップなら、すべてに組み込まれています)。浮動小数点数を使うと、整数よりも 広い範囲の値を扱うことができるだけでなく、分数も表現できるように なります。浮動小数点計算を実現する方法は、様々な種類がありますし、 ここで解説するにはちょっと複雑すぎるのですが、大まかに言うと、 いわゆる「科学的な表記法」といわれるもの、すなわち 1.234 * 10^23 のような 表記法と非常によく似ています。数字をコーディングする際は、 仮数 (mantissa) (すなわち 1.234) と、10 のベキ数としての指数部分 (すなわち 23) とに分離されます。(つまり、ここでの仮数は、小数点以下に 3 桁あるので、 この場合の計算結果は、その数字のあとに 0 が 20 個付くわけです。)

9.2. 文字

文字は、通常、ASCII (American Standard Code for Information Interchange) と呼ばれるコーディングにしたがった 7 bit の並びとして表現されます。 現在のマシンでは、128 個の ASCII 文字のそれぞれが、オクテット (octet) もしくは 8-bit のバイト (byte) の下位 7 bit を使って表されています。オクテットは、 メモリのワード単位にまとめられるので、たとえば 6 字の文字列の場合、 多くとも 2 メモリワード分の場所しか取りません。この ASCII 文字のコード表を 見るには、Unix プロンプト上で `man 7 ascii' と打ってください。

とはいえ、上記の段落は、ふたつの点で誤解を招くかもしれません。まず、 ひとつ目は、やや細かいことですが、オクテットという用語です。 これは、正式には間違ってはいませんが、実際にはほとんど使われていません。 大部分の人は、オクテットを バイト(byte) と呼び、バイトを 8 bit 長であると考えています。厳密にいうと、バイトと いう用語は、もっと一般的な意味を持っています。たとえば、以前は 36-bit マシンで 9-bit バイトといった言い方もなされていたのです(もうこうした使い方は決して なされないとは思うのですが)。

ふたつ目のより重要な問題は、 全世界で ASCII 文字が使われているわけではないということです。 事実、多くの国では、ASCII を使っていません。ASCII は、アメリカ英語の場合には 問題ないのですが、他の言語の利用者が必要とするアクセント付きの文字や特殊な 記号の付いた文字の多くが欠落しているからです。英国英語ですら、ポンド記号 が欠けていることから、ASCII 文字では問題が生じてしまうのです。

この問題を解決しようとする試みは、過去にいくつもなされてきました。 それらはすべて、ASCII では使われていない最上位 bit を使うという ものであり、それによって 256 文字セットをもうひとつ作ってしまおう というものです、それらのうち、もっとも広く利用されているのが Latin-1 と呼ばれるものです(正式には、ISO 8859-1 と呼ばれています)。これは、 Linux, HTML および X でのデフォルトの文字セットとなっています。 Microsoft Windows は、Latin-1 に手を加え、正式な Latin-1 では 歴史的な理由から空欄とされている箇所に左右の二重引用記号などを 追加しています。(これが、トラブルを引き起こす原因になっている という事件の解説は、demoroniser のページを御覧ください。)

Latin-1 は、英語、フランス語、ドイツ語、スペイン語、イタリア語、オランダ語、 ノルウェー語、スウェーデン語、デンマーク語といった西ヨーロッパの言語を 扱うものです。しかし、Latin-1 は、どれひとつの言語においても満足のゆく出来 ではないために、その結果として、Latin-2 から Latin-9 までの一連の文字セット が生まれ、これらを使って、ギリシャ語、アラビア語、ヘブライ語、エスペラント語、 セルビア・クロアチア語なども扱っています。詳しくは、ISO alphabet soup のページを御覧ください。

究極の解決策が、Unicode (および、その双子の兄弟である ISO/IEC 10646-1:1993) と呼ばれる膨大な標準規格です。Unicode は、冒頭の 256 箇所については Latin-1 とまったく同じです。それ以降の 16 bit 空間には、ギリシャ、キリル、アルメニア、 ヘブライ、アラビア、デヴァナーガリー(訳注:サンスクリット・ヒンディーその他を 含む現代インド諸語)、ベンガル、グルムキー(訳注:パンジャブ地方の文字)、 グジャラート、オーリヤ(訳注:インドの Orissa 州)、 タミル、トゥルグ、カンナダ(訳注:インドの Mysore 州)、マラヤーナム(訳注: インド南西)、タイ、ラオス、グルジア、チベット、 日本仮名、現代韓国のハングル完全版、中国・日本・韓国の表意文字 (漢字) の 統一セットといった文字コードが含まれています。詳しくは、 Unicode ホームページ を御覧ください。