コンテンツにスキップ

利用者:ザな

以下は編集のため 2023年の wikipedia内の "浮動小数点数"をコピーして変更したもの

浮動小数点数(ふどうしょうすうてんすう、floating-point number)は、実数コンピュータで演算や記憶するために、有限桁2進数の小数で近似値として扱う方式。[1]

概要[編集]

実数は0以上かつ1以下のような有限の範囲でも、無限個の値(種類)が存在するため、コンピュータでは妥当なビット数で有限個の値(種類)の近似値で扱う必要がある。

実数-1/3は無限小数となるが、有限桁の小数で近似値を表記できる。下の例では10進数での4桁としている。

-1/3
-1 x 0.33333333333333...
-1 x 0.3333 x 100
-1 x 3.333 x 10-1

下の2つの表記は科学記数法(scientific notation)とよばれ、小数点より左側の整数部分を1桁とする。 科学記数法のうち、左側の1桁を0以外(10進表記では1から9)にしたものを、正規化数(normalized number)とよび、 一番下の表記が該当する。

実数-1/3はまた、有限桁2進数の小数でも、近似値で表記できる。下の例では2進数17桁としている。

-1/3
-1 x 0.01010101010101010101010101010101...
-1 x 0.0101010101010101
-1 x (2-2 + 2-4 + 2-6 + 2-8 + 2-10 + 2-12 + 2-14 + 2-16)
-1 x (1/4 + 1/16 + 1/64 + 1/256 + 1/1024 + 1/4096 + 1/16384 + 1/65536)
-0.333328247(近似値の10進数表記)

2進数の小数も科学記数法で表記できる。

-1 x 0.0101010101010101 x 20
-1 x 0.101010101010101 x 2-1
-1 x 1.01010101010101 x 2-2

上記は同じ値を、小数点位置を移動し異なる表記にしているため、浮動小数点と呼ばれる。一番下の表記は、正規化数である。

コンピュータ処理に適した暗黙の基数2について、符号(sign)S、仮数(significand)F、指数(exponent)Eにより、 浮動小数点数は下記の式で表記できる。

(-1)S x F x 2E

有限桁2進数(ビット列)への数値の割当[編集]

現在のコンピュータでは処理の効率化や共通化のため、8bit==1Byteを最小単位とし、その整数倍の8bitや32bit、64bitの処理単位に対して演算や転送、記憶などの命令の対象であるオペランドとしている。

整数の割当[編集]

浮動小数点数の前に、整数の扱いを記す。

8bitであれば0x00(00000000)から0xff(11111111)までの28==256種類があり、符号無整数なら0から(28-1)==255にそれぞれ割り当てる。

00000000 = 0x00 = 0
00000001 = 0x01 = 1
:
11111110 = 0xfe = 254
11111111 = 0xff = 255

8bitで符号付整数なら、最上位ビット0x80を符号ビットとして-27とする。

00000000 = 0x00 = 0
00000001 = 0x01 = 1
:
01111110 = 0x7e = 126
01111111 = 0x7f = 127
10000000 = 0x80 = -128
10000001 = 0x81 = -127
:
11111110 = 0xfe = -2
11111111 = 0xff = -1

上記の符号付整数は、2の補数(two's complement)表現といい、処理の効率化などから標準的なものである。 過去には、符号ビットと絶対値、1の補数表現などが存在した。

浮動小数点数の割当[編集]

浮動小数点数は、符号(sign)S、仮数(significand)F、指数(exponent)Eにより表現できる。

(-1)S x F x 2E

このS、F、Eの3組を適当な長さのビット列に割当てる必要がある。

上記は現在の標準規格であるIEEE_754の倍精度浮動小数点数64bitである。 最上位のビット63には、符号ビットとしてSを割当てる。 下位のビット0からビット51までの52ビットで仮数を表現する。仮数Fは正規化した場合に、小数点より左の最上位1ビットが必ず1になるため、これを省略し小数点以下の52ビットを仮数部fに割当てる。 すなわち、仮数Fと仮数部fとは以下の関係になる。

F = 1 + f

残りのビット52からビット62の11ビットで、指数部eに割当てる。 最上位に符号ビット、次に指数部、下位に仮数部というIEEE 754の割当て順序は、 できるだけ整数の表現と近いものにして 整数の大小比較命令などを、浮動小数点数にも利用しやすくすることを狙っている。 指数部を2の補数表現とすると、(符号なし整数で見た場合に)負の値が正の値より大きく見えるため、不適当である。 そのため1番大きな正の指数をall 1のビット列で表し、1番小さい負の指数をall 0のビット列で表す。これをゲタばき表現(biased representation)とよび、指数部から引く定数をゲタ(bias)とよぶ。IEEE 754の倍精度浮動小数点数のゲタは、1023=(210-1)である。

IEEE 754 倍精度浮動小数点数
符号部 指数部 仮数 内容
0/1 0 0 ±0
0/1 0 ≠0 ±不正規化数
0/1 1-2046 任意 ±浮動小数点数
0/1 2047(0x7ff) 0 ±無限大
0/1 2047(0x7ff) ≠0 NaN(非数)

浮動小数点数の構造[編集]

浮動小数点数では次のデータで数値を表現する。

  • 仮数
    • (仮数の)符号
    • (値が0ではない場合、1以上で基数未満の、または、1以下の)仮数の絶対値
  • 基数(1より大きい整数)
  • 指数(符号付き整数)

現在広く使われている表現方法ではいずれも基数を固定しており、明示的に符号化しないため、実際に符号化されるのは、次の3つである。

  • 符号部(1ビット
  • 仮数部(符号なし整数)
  • 指数部(符号付き整数)

浮動小数点数では、数値の絶対値は(仮数部)×(基数)(指数部)となる。たとえば、0.5を浮動小数点数で表すと、基数が10の場合は5.0×10−15.0e-1)、基数が2の場合は1.0 × 2−1となる。

2進法正規化をすると、最上位ビットは常に1になるので、これを表さず常に1があるものとみなす省略が可能で、省略した表現をケチ表現などと言う。この省略を使うと、仮数部に割り当てたビット数がnであれば、有効桁数はn+1となる。

0を表す場合は符号部、仮数部、指数部のすべてのビットを0とすると都合が良いことからそのようにされることが多い。またその場合は+0.0で、浮動小数点では他に符号部が負をあらわし他が0の−0.0という0もあることがある。たとえば正の数を負の無限大で割ったり、負の数を正の無限大で割ったりすると−0.0になる。

浮動小数点数のフォーマット[編集]

浮動小数点数のフォーマットには、以下で説明するものや、イクセス64 など多数ある。

  • IEEE方式(IEEE 754。最も広く採用されている標準規格
  • IBM方式(IBMのメインフレームおよびそれを模倣した各社の互換マシンで使われていた。指数部を基数16で表現するのが特徴)
  • 指数部と仮数部を可変とする方式(これは研究用の面が強い。以下の該当する節で詳述)

IEEE方式(IEEE 754 形式)[編集]

単精度浮動小数点数型式
sign:符号部、exponent:指数部、fraction:仮数部
倍精度浮動小数点数型式

IEEE 754 形式の

  • 半精度浮動小数点数では、符号部 1 ビット ・ 指数部 5 ビット ・ 仮数部 10 ビット
  • 単精度浮動小数点数では、符号部 1 ビット ・ 指数部 8 ビット ・ 仮数部 23 ビット
  • 倍精度浮動小数点数では、符号部 1 ビット ・ 指数部 11 ビット ・ 仮数部 52 ビット
  • 四倍精度浮動小数点数では、符号部 1 ビット ・ 指数部 15 ビット ・ 仮数部 112 ビット

で表現されている。各部は次のように定義されている。

  • 符号部は、 0 を正、1 を負とする
  • 仮数部は、整数部分が 1 であるような2進小数の小数部分(ケチ表現)を表す
  • 指数部は、符号なし2進整数とし、半精度では 15、単精度では 127、倍精度では 1023、四倍精度では 16383 のゲタを履かせたゲタ履き表現で表す

つまり、IEEE 754 形式で表現する値は

半精度の場合: (−1)符号部 × 2指数部 − 15 ×(1 + 仮数部)
単精度の場合: (−1)符号部 × 2指数部 − 127 ×(1 + 仮数部)
倍精度の場合: (−1)符号部 × 2指数部 − 1023 ×(1 + 仮数部)
四倍精度の場合: (−1)符号部 × 2指数部 − 16383 ×(1 + 仮数部)

である。

ただし、IEEE 754 形式の指数部は複雑で、以下のような役割も持つ。

  • 通常の浮動小数点数(正規化数)を表現するのは、指数部が単精度で 254 ~ 1(127 ~ −126)、倍精度で 2046 ~ 1(1023 ~ −1022)の範囲のときである
  • 指数部が、単精度の場合 255(128)、倍精度の場合 2047(1024)のとき:
    仮数部が 0 以外の場合は、非数(NaN; Not a Number)を表す
    仮数部が 0 の場合は、符号部が 0 のときは正の無限大、符号部が 1 のときは負の無限大を表す
  • 指数部が 0(単精度の場合 −127、倍精度の場合 −1023)のとき:
    非正規化数
  • 指数部、仮数部ともに 0 のときは ±0 を表す

0 を 0 で割ろうとすると NaN になる。また、 も、求めるとNaNになる。

IEEE 754 で表現するまでの過程[編集]

2.5を例にとると、

  • 仮数の符号は、+
  • 仮数の絶対値は、2.5
  • IEEE 754の基数は、2で固定(簡単のため、以下では省略)
  • 指数は、0

であることから、まず次のように考える。

(−1)0 × 2.5 × 20

仮数部は1未満でなければならないため、仮数の値2.5を(この例では右へ)シフトし正規化する。基数は2、コンピュータの内部表現は2進法であるため、シフト量は1ビットである。さらに、右シフトして12になったことを相殺するため、指数に1を加える(もし左シフトなら、指数から1を引く)。 値をシフトすることで表現範囲を広げ、丸め誤差を少なくなるようにしている。この操作を正規化という。正規化は基数の±1乗を繰り返し求めればよい。

このままでは (−1)0 × 1.25 × 21 となり、仮数の絶対値は1未満ではないが、仮数部は 仮数 − 1 と決められているため、次のようになる。

(−1)0 × (1 + 0.25) × 21
  • 符号部は、0
  • 仮数部は、0.25
  • 指数は、1

指数部は、指数に127をバイアスすることが決まっているため

(−1)0 × (1 + 0.25) × 2(128 − 127)
  • 符号部は、0
  • 仮数部は、0.25
  • 指数部は、128

2進法では、

  • 符号部(1ビット):+ → 0
  • 仮数部(23ビット):0.25 → 01000000000000000000000
  • 指数部(8ビット):128 → 10000000

浮動小数点は、最上位ビットから符号部、指数部、仮数部の順に符号化するため

2進値:01000000001000000000000000000000、16進値:40200000
  1. ^ デイビッド・パターソン_(計算機科学者)ジョン・ヘネシーコンピュータの構成と設計 第5版