計算機内の符号(数値・文字コード)の取り扱い

はじめに

コンピュータで文章を扱うことを考えると、コンピュータ発祥の英米では、い わゆる半角英数字記号を表現するだけで用が足りるわけです。しかし、私たち は漢字仮名を扱って日本語を書き、コミュニケーションしたいわけで、その場 合文字コード 、すなわち文字をコードに割り付ける方法 (符号化) の問題が出てくる場合があります。 Windows でオフィス系ソフトだけを使う限りでは、 特に意識せず済むわけです が、UNIX系コンピュータ(サーバー)や、それを基盤として成長してきたイン ターネットを本格的に使い始めると、さまざまな文字コードがあることを意識 せざるを得ないことになります。
実はその他にも、文字コードに関してはいろいろ問題があります。たとえば 「日米で円記号とバックスラッシュが違うのはなぜか?」とか、あるいは、ブ ラウザの設定をいろいろいじったりすると現れる「『文字エンコーディン グ』 が変になっているときに表示されるへんなアルファベットの正体 は?」等がありますが、このような問題を解決するには文字コードに関する体 系的な理解が必要となります。

エンジニア志望の人だけでなく、自分でWeb サイトを立ててビジネスを展開し たい人など、広い意味でインターネットでご飯食べたい(仕事をしたい)人に は必須の知識でしょう。自分のサイトでページに文字化けがあったら、お客さ んは逃げていきますよね?

ここでは、符号の基礎について学びます。

そもそも、符号化とは?

計算機の中において、すべての情報がビット列、すなわち 0/1 の並 び で表現されていることは理解できているとして、それでは、どのよう なビット列を用いて、情報を表現しているのかを考えてみます。

たとえば、学校での成績の記録を考えてみます。仮に合格ないし不合格の みを表現したいのであれば、1ビットで十分であり、たとえば次のような 対応表が使えます。

合否 合格 不合格
ビット列 1 0

もちろん、1が不合格・0が合格でもいいわけです(後述)
それだけではなく、優・良・可・不可 (A,B,C,D) の記録も残したいとすると、 次のように 2ビットのビット列で表現することになります。
成績 不可
ビット列 11 10 01 00

このように、何らかの記号ないし記号の列によって情報を表現することを 符号化 と呼び、割り当てられた記号(記号列)を符号 ないしコード (code) と呼びます。

特に、ビット列(2進数)による符号化のことを2進符号化 と言います。 が、現代のコンピュータの文脈では2進符号化 がほとんどなので、わ ざわざ「2進」 をつけて言う場合は少ないです。

これらは、要するに、何らかの情報に、なんらかのビット列を割り当てる、と いうことで、そのやり方は本来的には 任意 です。例えば↑の例で言 うと、「優(A判定)」に「00」というビット列を割り当てても、そのシステ ムの利用者全体で了解(統一)されていれば全く問題ない、というわけです。 ただ、みんなでてんでんばらばらな割り当てを行うと、お互いに 意志の疎 通(コミュニケーション) が出来ないので、えいやっ、と決めて、特に 問題が無ければそれにみんなで従う、ということにしているのです。

では、数値はどう表現されてるの?

数値、特に整数の符号化は、基本的には 2進数表現に沿っています。m bit で正 の整数のみを表現する場合には、0 から 2m-1 の範囲の数が表現可 能です。たとえば 4bit であれば、次のように 0 から 15 = 24-1 の数が表現できます。

「表現可能」とは、要するに(合格・不合格のように)情報を区別できる(種 類がある)ので、それぞれのビット列にそれぞれの情報を割り当てる、という ことです。
ここで、あらためて2進数について考えてみます。たとえば 4bit (16進数1 桁)であれば、次のように 0 から 15 =24-1 の数(=16通 り)が表現できます(割り当てられています)。
数値 0 1 7 8 14 15
ビット列 0000 0001 0111 1000 1110 1111
4 ビットの場合だと、ビット列は 16 種類しかない→16通りの区別しか出来な い = 17種類以上の区別は出来ない、ということになります。

現在、多くの計算機では処理の単位(ワード)が32bit 単位で用いられていま して、これは0 から 4294967295 = 232-1 の範囲を表現できます。 加減算などの演算の結果、この範囲を外れてしまうと、当然のことながら正し い結果が表現できずに、別の数値になってしまいます。この表現範囲の限界を 越えることをオーバフロー (overflow) と呼びます。

極端な場合、手の指で数を数えることを考えてください(1進数といえるか も)。この場合、10までしか数えられないですよね?5+6を考えると…指 が足らなくなります。これがオーバフロー なわけです。

4 ビットの場合で考えなおすと、ビット列は 16 種類しかない→16通りの区別 しか出来ない = 17種類以上の区別は出来ない、ということだったので、0-15 の 16 種類の数値にそれぞれ 0000-1111 のビット列を割り振ったら、16 以上 の数は割り当てられない(言ってみれば、容量が足りなくて器から 溢れ て しまう)→数えられない、ということです。この限界を越えることが すなわちオーバフロー=桁溢れ です。

ちなみに、もし仮に 0000-1111 に 0, 10, 20, ... ,150 を割り振った場合 (事前に決めておけば可能)では、最大で 150 まで数えることは可能です、が、 その場合は 1 とか 2 は表現できない(割り当てられていない=10の倍数しか 数えられない)です。繰返しですが、 4ビットでは16種類しか区別できな い 、ということを再認識してください。
さて一方、負の整数は、どうように表現すれば良いでしょうか? 日常生活 では「- 1」のように「-(マイナス記号)」を用います。しかし、これでは 「0」「1」以外の記号が必要になり、2進符号化には直接利用できません。 そこで、通常は2の補数 表現と呼ばれる方法を用いて負の整数 を表します。これは、加減算などの演算にあたって、負の数値を正の数値 と同様の方法で扱えるためです。

2の補数の作り方ですが、単純にいうと、マイナスの数は、プラスの数の各ビッ トを反転(0なら1、1なら0に)した上で、1を加えます。例えば 4ビット で考えて、「-2」は、「2」が0010 なので、反転させると 1101 で、1 を足した 1110 が2の補数表現となります。

2の補数表現を用いると、 m bit では -2m-1 から 2m-1-1 の範囲の数を表現できます。この場合、正の整数を表す際の 2m-1 から 2m-1 の2進符号を-2m-1 から -1 の表現に用います。たとえば 4bit の場合であれば、次のように -8 = 23 から 7 = 23-1 が表現されます。

数値 -8 -7 -1 0 1 7
ビット列 1000 1001 1111 0000 0001 0111

この場合、例えば10進数での「5-3」はどう処理されるかということを考 えてみます。「5-3」は「5+(-3)」であり、「5」は 0101、「-3」 は1101 です。よって、この2数を加えると

  0101
 +1101
------
 10010
となり、5ビット目(オーバーフロー)は表現範囲の外なので無視すると 0010 となって、確かに「2」となっています。
いずれにしても、4 ビットの場合だと、ビット列は 16 種類しかない→16通り の区別しか出来ない = 17種類以上の区別は出来ない、ということを再度確認し てください。
32bit の場合には、 -2147483648 = -231 から 2147483647 = 231-1 の範囲の数が表現可能です。2の補数表現でオーバ フローが起きると、どうなるでしょうか?この表の場合には、7に1が加わる と -8 に、逆に-8から1が引かれると (+)7 になってしまい ます。つまり、正の数値は負の数値に、負の数値は正の数値に化けてしまいま す。
これも一種のオーバーフローです。
絶対値の大きな数値や小数点以下の数値を表現する場合には、 浮動小数点表現(あるいは実数 表現)と呼ばれる符号化を用います。

いよいよ、文字

ということで、当然といえば当然ですが、計算機内では文字情報も符号化 されています。この符号化の方式は、JIS (Japan Industrial Standard: 日本工業規格)やANSI (American National Standard Institute)、ISO (International Organization for Standardization) などで規格として 定められています。

一般に文字の符号化は、「文字」と「数値」の対として与えられます。ある規 格において、仮名、漢字などのうち、どの文字を対象にするかをまず決めない と符号化する対象がわからないということで、符号化を定めている文字全体の 集合を文字集合(文字セット, character set) と呼び規定します。また、この文字 に対応する数値のことを文字コード (character code) と呼びます。たとえば、 Unicode は、世界の主な文字を文字集合として 16bitの文字コード を定めたもので、現在ではISO 10646 という規格の一部になっています (UCS-2)。またこれを拡張しして4バイトコードにした UCS-4 というのもあり ます。さらに、同じUnicode と同じ文字集合を対象にした 別のコード (符号化) として UTF-8, UTF-16 などがあります。

欧米で用いられるアルファベットは文字の種類が少ないため、少ないビット数で 文字を表現できます。この英数字(アルファベットと数字)の文字コードとしてよ く用いられるのが、ANSIの制定したASCII (American Standard Code for Information Interchange)です。ASCII では 7bit の文字コードを規定しています(後述)。ただし計算機内部では、(主とし てハードウェア的な制約から)通常は、8bit = 1Byte を使って文字を表現しま す。 一方、漢字の表現方法としては、JISコード [ISO-2022-JP] EUCコード [EUC-JP] シフトJISコード (SJISコード, Shift_JIS) という異なる3つの方式が広く使われています。これら の方式で、漢字は概ね2Byte で表現されます(後述)。

ちなみにASCII の文字集合は、それぞれの文字の形も簡単です。そのため、 ディスプレイに表示される際やプリンタに印刷される際には、縦横比が 2:1 の、縦に細長い字体が多く用いられます。このような字体の文字を俗 に半角文字 と言います。これに対して、漢字などの文字は文字 の形が複雑なため、一般に縦横比が 1:1 の字体が用いられます。このよ うな字体の文字を俗に全角文字 と言います。これらはあくまで も俗称 である、つまり本来、符号化と文字の大きさに直接 の関係は無い ということを覚えておいてください。

具体例:ASCII文字

下の表は、ASCII文字コード表(16進数)と呼ばれ るもので、それぞれの文字コード(数値)がどの文字に対応するかを表していま す。左端の数字(0〜7)は、7bitコードの上位の3bitの16進数表現であり、上端 の数字(0〜F)は下位の4bitを表します。つまり、文字コード 28(16)=40(10)は「(」、41(16)= 65(10)は「A」、69(16)=105(10)は「i」 に対応していることがわかります。

下位 4 ビット(16進数表記)
0 1 2 3 4 5 6 7 8 9 A B C D E F
上位 3 ビット(16進) 0 nul soh stx etx eot enq ack bel bs ht nl vt np cr so si
1 dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us
2 sp ! " # $ % & ' ( ) * + , - . /
3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
4 @ A B C D E F G H I J K L M N O
5 P Q R S T U V W X Y Z [ \ ] ^ _
6 ` a b c d e f g h i j k l m n o
7 p q r s t u v w x y z { | } ~ del

00(16)から1F(16)は、制御コード(control code , JIS 用語では 制御文字集合 )と呼ばれます。それ以外 の普通の文字は(画面に表示できる、という意味なのだと思われますが) 図形文字集合 と呼びます。
図形文字というと●とか▲とかハートマークとか罫線とかを思い浮かべるか もしれませんが、そうではなくて、制御文字に対して、アルファベット・数 字・記号などの目に見える形をもった普通の文字のことです。空白は制御文 字とも図形文字ともみなすことができます。
制御コードと「del」(7F(16))は、他の文字とは多少異なります。 たとえば、「bs」(08(16))はバックスペースキー、「esc」 (1B(16))はエスケープキー、「del」(7F(16))はデリー トキーに相当する文字コードです。また「sp」(20(16))は、空白文 字を意味しています。

5c (\) は、本当の ASCII では「\」(バックスラッシュ)の半角なのですが、 JIS を設定するときにここをなぜか \ に入れ替えてしまって、 日本語環境のASCII コード部分が本家 ASCII と互換性が無 く なってしまっています。ちなみに、あとは 7e (~ = tilde) も  ̄(オー バーライン)の半角に入れ替わってますが、こちらは実害は少なそうです(同 じものとみなしても、ほぼ大丈夫)

具体例2:漢字仮名と文字コード


漢字仮名については、 文字コー ドの話 がよくまとまってると思いますので、興味ある方々はぜひご一読をお勧めしま す。

前田としゆき / maechan@hannan-u.ac.jp

講義用スタイル
印刷用スタイル (開いてから、ページを再度更新してください)