【番外編】ICT環境における数値情報の表現
このstepでは、数値情報がパソコンやインターネットなどICT環境の中ではどのように表現されているかを学ぶ。これらは講座の最終ステップではなく、準備段階である。受講生の方々の学習経験や予備知識のレベルをみながら、必要に応じて講座に組み入れていく。
学校数学の「数」とICTの「数」
コンピュータは、膨大な手間がかかる計算を高速に実行するための計算機として誕生した。現在でも、科学技術や経済など数値計算を要求する分野はたくさんある。
一方、ビジネスにおけるICT利用ではテキスト(文字)情報の処理が主である。また、美術・音楽などの芸術分野や、地学などの科学分野では、画像情報や音声情報を処理するニーズもある。コンピュータの進歩につれ、対象分野が数値情報から、文字情報、画像情報、音声情報などに拡大してきたのである。
だが、もっとも基底のレベル、つまりCPU(中央処理装置)が処理するレベルでは、コンピュータは依然として「計算」しかしていない。つまり、CPUにとっては、文字や画像、音声の処理も、すべて「計算」なのである。これは、私たちのあらゆる体験や認識が、脳内では神経細胞(ニューロン)の発火になってしまうのと似ている。
計算のためには、まず扱う対象の「数」自体を表現しなくてはならない。そこで、ICTの世界では、共通に利用できる数の表現が決められており、多くは日本工業規格(JIS)や国際標準規格(ISOやIEEE、ASCIIなど)として定義されている。
注意が必要なのは、私たちが学校数学で習う「数」と、ICT環境で定義された「数」は違うことである。これらの対応を図1に示す。
図1: 学校数学の「数」とICTの「数」の対応
学校で習う数には自然数、整数、分数、小数、複素数など、さまざまな種類があるが、ICT環境ではこれらを
に3分類する。ICTの「数」は数学の「数」よりも種類が少なく、簡単である。
その代わり、ICTでは上記それぞれの数を格納する記憶容量(メモリサイズ)を意識しなくてはならない。それを含めると、ICTにおける数値は、以下のような種類に分類できる。
- yes/no 1 bit(0または1)
- 整数 1, 2, 4 BYTE(表現できる数の範囲が異なる)
- 浮動小数点数 2, 4, 8 BYTE(表現できる数の範囲と精度が異なる)※1
- 半精度浮動小数点数(FP16) 2 BYTE
- 単精度浮動小数点数(FP32) 4 BYTE
- 倍精度浮動小数点数(FP64) 8 BYTE
- 4倍精度浮動小数点数(FP128) 16 BYTE
1 浮動小数点数については、IEEE754という国際標準規格で定められている。
2進数(binary number)
コンピュータでは、数値も、文字・画像・音声などの情報も、最終的にはすべて2進数で表現される。
私たちが普段使っている10進数が、0から9までの10種類の数字を用いる数の表記法であるように、2進数は、0と1の2種類の数字を用いる表記法である。コンピュータのようなデジタル機器では、
- スイッチのオン/オフ
- 回路に電流が流れている/いない
- 端子の電圧が高い/低い
- 磁気ディスクのある位置が磁化されている/いない
- 光ディスクのある位置がレーザー光を反射する/しない
のような2通りの物理状態を区別するのがもっとも単純な処理なので、2進数は電子回路で数を表すのに最適な方法といえる。
通常の10進数による表記と区別するために、数学では、2進数の表記には、「10012」のような添え字をつけるが、この講座資料を含め、ICT系の解説文では省略されることが多い。
たとえば、10進数と2進数の対応を示せば、
である。
2 10進数以外の数字を「ヒャクイチ」などと読まないこと。「イチレイイチ」または「イチゼロイチ」と読む。
ちなみに、デジタル情報の最小単位はビット(bit)だが、これは「情報工学の父」と呼ばれるクロード・シャノンが名付けた、「2進数の1桁(binary digit)」を表す造語である。
16進数と8進数、基数変換
2進数は、コンピュータ内での表現と1対1対応しているが、10進数の100や50000といった比較的小さな数を表わすのにさえ、以下のように多くの桁数を必要とするのが欠点である。コンピュータの解説書を書いたり設計する場合を考えれば明らかだろう。
- 100 = 1100100
- 50000 = 1100001101010000
そこで、2進数の4桁を1桁にまとめた16進数(hexadecimal number)や、3桁を1桁にまとめた8進数(octal number)として表記する場合が多い。2進数同様、数の右下の添え字で基数(2,16,8など)を表すこともあるが、ICT分野ではその代わりに、
- 16進数の場合は数字の頭に0xの2文字をつける。例:0x8e52
- 8進数の場合は数字の頭に数字の0をつける。例:057
8進数の各桁は数字の0~7までを使えばよいが、16進数では16種類の数字が必要なため、0~9だけでは足りない。そこで、9の後にA~F(a~f)の6種類の数字があるものとして表記する。つまり、
- 100 = 1100100 = 0x64 = 0144
- 50000 = 1100001101010000 = 0xC350 = 0141520
となる。この等式は、数の表記を変えているだけで、数学的には恒等式にすぎない。この操作を基数変換という。
だから、16進数表記に現れるA~F(そしてx)は文字ではない。また、8進数や16進数は、あくまで2進数を短く表記する便宜上の工夫に過ぎず、コンピュータ内ではすべてのデータを2進数で表現している。
演習:基数変換
10進数⇔2、8、16進数の基数変換に慣れるため、いくつか問題を解いてみよう。この作業には、図2に示す対応表を利用するとよい。これは、16進数の1桁が、他の進法のいくつにあたるかを示している。
図2: 各基数の対応表
また、1BYTEの数値を置数できる、図3に示す枠を書いておくと便利である。これは後述する1BYTEの符号なし整数の構造であり、それぞれの枠には0または1の数字が入る。枠下の数字は、各桁の「位」を表す。またMSBは最上位ビット(Most Significant Bit)、LSBは最下位ビット(Least Significant Bit)を表す。
図3: 1BYTEの構造を表す置数枠
10進数から2, 8, 16進数への変換
つぎの10進数を1 BYTEの2進数、8進数、および16進数で表現しなさい。
- 56
- 23
- 34
2, 16進数から10進数への変換
つぎの2進数、および16進数を 10進数で表現せよ。
- 00100111
- 11110001
- 0x3F
Windowsのユーティリティ(アクセサリ)の1つである電卓アプリをプログラマ電卓モードで使うと、2,8,10,16進数間の基数変換や、四則演算などが簡単にできる。
bit、Byte、その他情報量の単位
ICTでは8bitの情報をひとまとめにして1Byteと呼び、1Bと表記する。たとえば【番外編】ICT環境における文字情報の表現で扱う文字コード(ASCIIコード、Shift-JISコードなど)は、それぞれ1文字につき1Bまたは2Bの情報であり、一般に2桁または4桁の16進数で表記される。
Bに定数倍を表す接頭辞をつけることで、より大きな情報量の単位が作られる。ファイルのサイズや、記憶装置/メディアの容量などは、これらの単位で表現される。
- 1KB(キロバイトまたはケーバイト) 1024(210) BYTE
- 1MB(メガバイト) 1048576(220) BYTE
- 1GB(ギガバイト) 1073741824(230) BYTE
- 1TB(テラバイト) 240 BYTE
- 1PB(ペタバイト) 250 BYTE
などの単位が使われている。
ただし、これらの値は慣用値で、KやMやGという接頭辞が、普通の単位系(KG、KMなど)と同様の1000(103)倍ごとでないことが、昔から混乱の元であった。そこで国際電気標準会議(IEC)は1998年に上記の値をそれぞれ
- 1Kib(キビバイト)
- 1Mib(メビバイト)
- 1Gib(ギビバイト)
- 1Tib(テビバイト)
- 1Pib(ペビバイト)
などと呼称を改め(2進接頭辞方式という)、以前の呼称は1000(103)倍の開きに戻すことを提案したが、すでに広く流通している単位の意味を変更するのは現実的でなかったと見え、現在にいたるも広まってはいない。
その他、主に英語圏では、
- 1WORD(ワード) 2BYTE
- 1DWORD(ダブルワード) 4BYTE
- 1QWORD(クワッドワード) 8BYTE
などの単位も、よく使われる。
符号なし整数の表現
さて、ようやく整数の表現を説明する準備が整った※3。前述のように、ICT環境には自然数という概念はなく、自然数に0を加えた符号なし整数が用いられる。
数学における「整数」には、値の上限や下限がないが、有限のメモリ領域に数を記憶しなければならないICTでは、必ず上限と下限がある。後述する浮動小数点数では、それに加えて精度の制限もある。制限の程度は、数を記憶しているメモリサイズ(BYTE数)によって決まる。
「符号なし整数」は、あるサイズの記憶領域に、前述の2進数をそのまま格納したものである。一般に、1、2、4BYTEの整数型が区別される。1 bitの数値を記憶する「yes/no型」も、符号なし整数型の1種と考えられる。
1BYTE(= 8bit)の符号なし整数では、0~255までの整数を表現できる。図3に示した置数枠を見れば明らかだろう。「符号なし整数」といった数の種類と、格納するBYTE数をセットにしてデータ型(data type)と呼ぶ。
3 「さっきまでのはなんだったの?」と思うかもしれないが、さっきまでのは2, 8, 16進数、基数変換と情報量の単位の説明だった。
演習
2BYTEや4BYTEの符号なし整数では、どんな範囲の値が表現できるか? Windowsの「プログラマ電卓」で計算してみよう。
符号つき整数の表現
日常生活と同様、ICTでも、負の数を表現する必要は頻繁に発生する。人数や体重の増減、赤字など。紙の上ではマイナス(-)符号をつけるだけだが、ICTでは1と0だけで負数も表現しなければならないので工夫が要る。その工夫が補数だ。補数には、1の補数と2の補数があり、ICTでは2の補数で負数を表現する。
- 1の補数
- 正数の各ビットを反転(negate)したもの。
- 2の補数
- 1の補数に1を加えたもの。また、正数のビット数nより1桁多く、最上位ビットが1、残りがすべて0であるような数値(n = 8なら 100000000 )から、正数を引いた数。計算結果の最上位桁ビット(n + 1ビット目)は無視してよい。
演習
- 35の符号なし整数表現を求めよ。格納されるビット数n = 16とする。
- 1の補数を求めよ。
- 2の補数を求めよ。上述の2通りの方法が一致するのを確認すること。
- 35と、3で求めた-35を足し、0になることを確認せよ。最上位桁(17桁目)は無視してよい。
2の補数を用いて正負の整数を表現すると、
- 最上位ビットが0 → 正数
- 最上位ビットが1 → 負数
となるので、結果的に最上位ビットを符号ビットとして扱える。しかし、符号つき整数は、符号なし整数の左端に符号ビットを並べたものではない※4。このような補数表現を用いる理由はなんだろうか。
「A+B」という加算において、AとBの符号には4通りの組み合わせがある。もし負数表現として「符号ビット+符号なし整数」を使うと、この4通りの場合分けが必要となり、演算速度が何倍も遅くなってしまう。演習で確かめたように、「2の補数」を使えば、場合分けをせずにそのまま足せばよいので、はるかに高速に演算できる。
ただし、同じバイト数の符号なし整数に比べて、符号つき整数では表せる正数の範囲は約半分になる。当然、減った分は負数に割り当てられる。0を間に挟んでいるので、正数と負数の個数は1つだけずれる。たとえば1バイトの符号つき整数は、-128~127の値を表現できる。負数の方が1つ多いのは、0が正数として扱われているからだ。
4 これさえ理解できれば、符号付き整数は卒業といってもよい。
演習
2バイトや4バイトの符号つき整数では、どんな範囲の値が表現できるか? Windowsの「プログラマ電卓」で計算してみよう。
その他の表現形式
このほか、金融や経済分野では、10進数の表記に近い整数や浮動小数点数の表現形式(2進化10進数:BCD=Binary Coded Decimal)も利用されている。これは、たとえば利子計算などの時、10進数の計算では生じない誤差の発生を防ぐためである※5。一般のICTではあまり使われないので、この講座では省略する。
5 なにしろ、10進数の0.1は、2進数で表すと、0.000110011001100110011...のように無限小数になるのだ。
浮動小数点数
このstepの最後に、ICTにおける小数の表現、つまり浮動小数点数(floating point nunber)を学ぼう。なかなか一筋縄ではいかないが、演習を通じてイメージだけでもつかめれば、十分である。
浮動小数点数とは、前述の符号つき整数を拡張し、数値をつぎの3つの部分で表現したものである。
精度や有効数字といった、誤差に関する厳密な扱いを要求する科学技術分野では、このような表現方法は以前から使われてきた。科学的表記法(Scientific Notation)というものである。これはもちろん10進数表記だが、たとえば、
- 光速は2.99792458×108[m/秒.]
- アヴォガドロ定数は6.022×1023[個/mol]
である。
演習
上記の光速と、アヴォガドロ定数について、それぞれ符号、仮数部、指数部を答えよ。また、有効数字は何桁か。
浮動小数点数の表現は、IEEE754という国際標準規格で定義されており、ICTの各分野、たとえばプログラミング言語やデータベース、CPUの命令セットなどはこの規格に準拠している。この規格には、
- 半精度浮動小数点数(FP16) 2BYTE(符号部1bit、指数部5bit、仮数部10bit)
- 単精度浮動小数点数(FP32) 4BYTE(符号部1bit、指数部8bit、仮数部23bit)
- 倍精度浮動小数点数(FP64) 8BYTE(符号部1bit、指数部11bit、仮数部52bit)
などの種類がある※6。
6 4倍精度浮動小数点数も定義されているが、ここでは説明を省略する。半精度浮動小数点数(FP16)は、2008年版で新たに加えられたもので、背景には、GPUによるグラフィックス処理やニューラルネットワークの学習では、精度よりも処理性能が重視されるということがある。一般の数値計算向きには精度が低すぎて使えない。なにしろ10進数にして約3桁分の精度しかないのだ。
図4に、単精度浮動小数点数の構造を示す。
図4:単精度浮動小数点数の構造
各部の定義を示す。
- 符号ビット
- 符号つき整数と同様に0:正数、1:負数
- 仮数部
- 2を基数として整数部が1桁(つまり1)になるように値をシフトし、1を引いて正規化した数の 2進数表現(ケチ表現)
- 指数部
- 真の指数に半精度の場合は15、単精度の場合は127、倍精度の場合は1023を加えた値。指数部としての範囲は1~30、1~254、1~2046に制限される。つまり、真の指数の範囲は、-14~+15、-126~+127、-1022~+1023である
全体として、つぎの値を表現していることになる。
- 半精度
- (1-2*符号部)×2^(指数部-15)×(1+仮数部)
- 単精度
- (1-2*符号部)×2^(指数部-127)×(1+仮数部)
- 倍精度
- (1-2*符号部)×2^(指数部-1023)×(1+仮数部)
ただし、指数部はさらに複雑で、以下のような役割も持つ(単精度と仮定して説明する)。
- 指数部が255、仮数部が0以外の時は非数(NaN; Not a Number)を表す。 たとえば0を0で除算すると、結果はNaNになる。
- 指数部が255、仮数部が0のとき、符号部によって+∞か-∞(正負の「無限大」)。 たとえば1 / 0 = +∞、-1 / 0 = -∞になる。
- 指数部、仮数部ともに0のとき、符号部によって+0か-0。
- 指数部が0、仮数部が0以外のとき、非正規化数。これは、正規化して表現できないほど絶対値が小さい数の表現で、たとえば単精度の場合、「(1-2*符号部)×2^(-126)×(0+仮数部)」を表している。
このような複雑な定義になったのは、限られたバイト数で表現範囲を少しでも広げ、誤差を少なくする工夫をこれでもかと盛り込んだためである。
演習
-18.25の単精度浮動小数点数表現を求めよ。図4の枠内に各桁の数を書き込むと便利である。