Yamamoto's Laboratory
電子計算機
  第8回
講義ノート 2003年度 電子計算機 (論理回路) 固定および浮動小数点表示

電子計算機固定および浮動小数点表示

コンピューター内部での実数の表現方法を学びます.現代のコンピューターでは,浮動小数点表示が使われます.その具体的な方法を示します.

目次


講義を始める前に

本日の授業のテーマ

本日の授業のテーマは,以下のとおりです.

  1. 固定小数点表示
  2. 不動小数点表示
  3. プログラミング言語と表現方式

本日の授業のゴールは、以下のとおり。

  • 固定小数点表示の意味が理解できる。
  • 不動小数点表示の内容が理解できる。
  • コンパイラー言語で変数の宣言が必要な理由がわかる。

先週の復習

  • 負の数の代表的な表現方法には、(1) 絶対値表現,(2) 1の補数による表現,(3) 2の補数による表現があります。
  • これらのうち、現在のコンピューター内部での負の数の表現は、2の補数が使われています。 たんに、補数と言えば、2の補数のことです。
  • コンピューター内部では、負の数は2の補数による表現を行います。その手順は、以下の通りです。
    1. 負の数の絶対値を2進数で表現して、ビット反転する。
    2. +1 加算
    [例] (-18)10は、コンピューター内部(8ビット表現)では、(11101110)2と表されます(メモリーへの格納状態)。
    例 (-18)10 00010010 18 の 2進数表現
    11101101 ビット反転
    11101110 +1 加算
  • 2の補数を使うと、以下の有利な点があります。
    • 負の数の加算が通常の加算器で出来る。
    • 正の数の減算をする場合、(1) 2の補数に変換して、(2) 加算器による加算で可能となる。減算器を作るより、この方が回路が簡単になる。
    [例] (21-14)10と(14-21)10を加算器(8ビット)を使って計算する。
  • 補数を求める手順 (ビット反転,+1加算) は、コンピューター内部表現では、×(-1) と同じです。
  • コンピューター内部では、正の数は2進数でそのままの表現です。一方、負の数は2の補数を使います。正か負かの判断は、最上位のビットで判断します。最上位のビットが 0 ならば正、1 であれば負です。
  • したがって、最上位のビットが符号を表すため、絶対値は残りのビットで表すことになります。したがって、8ビットの場合、以下の範囲で整数が表現できます。
    最大値 (01111111)2=(27-1)10=(127)10
    最小値 (10000000)2=(-28)10=(-128)10

固定小数点表示

2進数で、小数点の位置を固定した表現です。 一般的に、右端に小数点を固定します。したがって、整数のみを表わすることになります。 負の数は、2の補数をつかいます。例えば、8ビットで(-107)10を表現すると、図1のようになります。計算機内部で、(-107)10は(10010101)と表現されます。

これは、いままで、さんざん学習してきたので、これ以上の説明はしません。

図1: (-107)10の固定小数点

浮動小数点表示

浮動小数点表示とは

浮動小数点表示とは、指数化(例えば、-0.123×10-2)して数値を表現します。これは非常に便利な方法で、自然科学では多くの場合、このように数値を表現します。コンピューターでも同様で、データが整数と指定されない限りこの浮動小数点が用いられます。実際、この仮数部の (-0.123) と指数の (-2) をメモリーに格納します。この方法の長所と短所は、以下の通りです。

長所 決められたビット数内で、非常に小さな数値から大きな数値まで表現可能になる。
短所 桁落ち誤差が発生する場合がある。

浮動小数点表示を学習するために、必要な言葉の意味は、図2の通りです。1年生の数学の授業で学習したはずです。

図2: 指数表現の名称

ここでは、教科書に示されている2通りの方法と、秋田高専の計算機サーバー(なまはげ君)でのC言語での固定小数点表示を示します。

オフセットバイナリを使う方法 (教科書)

教科書にはきっちりと仕様が書かれていません。そこで、補数は使わないで、絶対数表現ということで話を進めます。教科書の不足分を補っているだけで、教科書とは矛盾はしません。

まず例として、

(-0.0390625)10 = (-0.0000101)2 = (-0.0a)16 = (-0.a×10-1)16

を浮動小数点表示することを考えます。10進数のを16進数で正規化しています。正規化というのは、仮数部の整数部をゼロにして、小数点一桁目を 1 — F までの数字で表すことを言います。

正規化後、以下の操作をすれば、浮動小数点表示ができます。

  1. 負の数なので符号ビットは、1 です。
  2. 指数(-1)2 は、10進数で表しても (-1)10です。これを教科書の表2.2にあるオフセットバイナリー方式で、2進数へ変換します。オフセット値は 64 なので、それを加算して、(-1+64)10 = (111111)2となります。指数は、7ビットで表すため、(011111)2と表現します。
  3. 次に仮数部ですが、(0.a)16 = (0.1010)2 です。残りのビットはすべてゼロです。即ち、(0.1010)2 = (0.101000000000000000000000)2 です。

以上ですべてのビットが決まったので、コンピューター内部では、図3のように表現されます。

図3: (-0.0390625)10をオフセットバイナリーを使った浮動小数表現

指数符号ビットを使う方法 (教科書)

これも、教科書にはきっちりと仕様が書かれていませんので、補数は使わないで、絶対数表現ということで話を進めます。

ほとんど、先ほどのオフセットバイナリーを使う方法と同じです。異なるのは、指数部がオフセットバイナリではなく、絶対値表現になっていることだけです。先ほどと、同じ問題、(-0.0390625)10の表現を考えます。先ほどの操作の (1) と (3) は全く同じです。(2) は、

(2) 指数 -1 は、負の数なので指数符号ビットは 1 になります。その絶対値の (1)16=(1)2 です。これを6ビットで表すと、(000001)2 です。

となります。これで、すべてのビットが決まったので、コンピューターの内部の表現は、図4のようになります。

図4: (-0.0390625)10を指数符号ビットを使った浮動小数表現

C言語の倍精度実数の表現

IEEE の規格のC言語の倍精度実数型の double の表現について説明します。まず、浮動小数点表示のための正規化を図5に示します。当然、仮数部、指数部とも2進数表現です。仮数部は、符号と 1.XXXX の表現にします。

図5: IEEE規格表現のための規格化

つぎに、これをIEEE規格の浮動小数点に表すことを考えます。まずその規格の仕様は、以下のようになっています。

  • 64ビット(第0ビット – 第63ビット)で、浮動小数を表します。各ビットの構成は、図6の通りです。
  • 最上位の第63ビットが仮数部の符号ビットです。正の場合ゼロで、負の場合 1 になります。
  • 指数は11ビットでオフセットバイナリ方式で表します。11ビットで 0 – 2047 の値になります。ただし、指数部11ビットの値 0 と 2047 は例外処理のために予約されています。11ビットで表現される値からオフセット値 1023 を引くことにより指数の値が -1022 – 1023の範囲になるように定められています。
  • 仮数部は52ビットです。小数点以下を、絶対値で表現します。規格化のための整数部は 1 と分かっているので、このためのビットは割り当てられていません。

図6: IEEE規格表現のための規格化

以上の仕様をもとに、図5で規格化された数を浮動小数点表示します。ほとんどの部分は規格化で分かりますが、指数のみ計算が必要です。指数は、オフセットバイナリーで計算するために、まず10進数で表します。

\begin{align} (-1011)_2=(-8-2-1)_{10}=(-11)_{10}\label{eq:-11} \end{align}

不動小数表示の指数は、この式\eqref{eq:-11}の実際の値に、1023 を加算して求めます。すると、

\begin{align} (-11+1023)_{10}=(1012)_{10}=(1111110100)_{10} \end{align}

となります。

これで、すべて準備が整いました。不動小数点表示は、図7のようになります。実際のコンピューターには、この64ビットは、8ビット(1バイト)毎アドレスが割り当てられたメモリーに格納します。したがって、メモリーの8番地分のデータ領域が必要になります。

図7: IEEE規格の浮動小数点表示の例

プログラム言語と表現方式

初心者がプログラミング言語を学び始めると、変数の宣言に戸惑います。数学を勉強するとき、変数に宣言など使ったことがないからです。また、宣言がなくても、アルゴリズムに不都合がないからです。変数の宣言が無くても、問題がないように思ってしまいます。

変数の宣言がなくても、アルゴリズム上、問題はありません。しかし、コンパイラーにとっては、大きな問題です。コンパイラーがソースプログラムをマシン語に翻訳する場合、その変数を表現するための領域の大きさ(バイト数)と表現方法を決める必要があります。

できるだけ大きな数字が表現できる型、例えば FORTRAN の4倍精度実数型に統一する方法もあります。しかし、そうすると以下のような問題が生じます。

  • 整数どうしの加算や減算、乗算が整数にならない場合が生じる。
  • 大きなメモリー領域が必要になり、資源の無駄になる場合が多い。

これらを、コンパイラー言語では、型宣言によって避けます。効率的なマシン語を作成するために、変数の宣言は絶対に必要となるのです。参考のために、表1, 2にFORTRANとC言語の代表的な宣言を示します。

一方、インタープリンター方式の言語の場合、型の宣言が無い場合があります。例えば、BASIC や Perl のような場合、型宣言は不要です。あらかじめ、データ領域を確保する必要が無く、必要になったら、適当に領域を確保しているためだと思います。詳細は、良くわかりません。

FORTRANの場合の変数の型表現
宣言 バイト数 表現方式
整数 INTEGER 4 固定小数点
実数 REAL 4 浮動小数点
倍精度実数 REAL*8 8 浮動小数点
4倍精度実数 REAL*16 16 浮動小数点
C言語の場合の変数の型表現(秋田高専の計算サーバー)
宣言 バイト数 表現方式
整数 int 4 固定小数点
実数 float 4 浮動小数点
倍精度実数 double 8 浮動小数点
拡張倍精度実数 log double 8 浮動小数点


no counter