浮動小数点数(ふどうしょうすうてんすう)は、コンピュータにおける実数の近似値の表現方式。
固定小数点数と比較するとさまざまな誤差が発生しやすいが、大きな値や、逆に小さな値を表現するのに向いている。そのため、精度が要求される分野(科学など)で多く用いられている。また、プログラミング言語のほとんどが対応しているということもあり、小数の表現方法としては最も普及している。
固定小数点数の演算と比べると演算速度が遅いため、FPU(浮動小数点数プロセッサ)と呼ばれる、浮動小数点数の演算を高速化するための専用の装置が別途搭載(現在はCPUに内蔵)されている場合が多い。
浮動小数点数の構造
値の表現方法は、たとえば
SI単位系で、キロは10
3、センチは10
-2と表現するのに似ている。
ただし、浮動小数点数では次の3つのデータで数値を表現する。
- 符号部(1ビット)
- 仮数部(符号なし整数)
- 指数部(符号付き整数)
浮動小数点数では、数値の絶対値は(仮数部)×(基数)(指数部)となる。たとえば、0.5を、基数が10の浮動小数点数で表すと0.05×101(0.05e+1)、基数が2だった場合は0.25×21となる。
仮数部に割り当てられたビット数をnとすると、2進数での有効桁数はn+1となる。これは、最上位の桁は必ず1になり、表現する必要がないためである。なお、0を表す場合は符号部、仮数部、指数部のすべてのビットを0にする。
浮動小数点数の表現方法
浮動小数点数の表現方法はいくつかの種類がある。
- IEEE方式(IEEE754。最も広く採用されている標準規格。)
- IBM方式(エクセス64。IBMのメインフレームで使われている、仮数部を16進数で表現するもの)
それぞれ32ビット表現(単精度)と64ビット表現(倍精度)とがある。
IEEE方式(IEEE 754 形式)
IEEE 754 形式の単精度実数では、符号部1ビット・指数部8ビット・仮数部23ビット、倍精度では符号部1ビット・指数部11ビット・仮数部52ビットで表現されている。各部は次のように定義されている。
- 符号部は0を正、1を負とする
- 指数部は2を基数とし、127をバイアスした値で表す
- 仮数部は1以下の2進小数とする。ただし、仮数部=仮数 - 1とする
- IEEE 754 形式で表現する値は (-1)符号部×2指数部-127×(1+仮数部)
IEEE 754 形式の指数部は複雑で、以下のような役割も持つ。
- 指数部が255、仮数部が0以外の時は非数(NaN; Not a Number)を表す
- 指数部が255、仮数部が0のとき、符号部が0のときは正の無限大、符号部が1のときは負の無限大
- 指数部、仮数部ともに0のときは0
※0を0で割ろうとするとNaNになる。また、も、求めるとNaNになる。
IEEE 754 で表現するまでの過程
2.5を 単精度 IEEE 754 で表現するには、次のようになる。
2.5×20
IEEE 754 でも仮数部は1以下でなければならないため、値をシフトし正規化する。
基数は2、コンピュータの内部表現は2進数であるため、シフト量は1ビットである。
このままでは 1.25×21 となり1未満ではないが、仮数部は 仮数 - 1 と決められているため、次のようになる。
0.25×21
指数部は127をバイアスすることが決まっているため
0.25×2128
実際には2進数で表現されているので、2進数に直す。
- 符号部(1ビット):+→0
- 仮数部(23ビット):0.25→01000000000000000000000
- 指数部(8ビット):128→10000000
浮動小数点は 符号部 指数部 仮数部 の順で並べるため
2進値:0 10000000 01000000000000000000000、16進値:40200000
IBM方式(エクセス64 形式)
エクセス64の単精度実数では、符号部1ビット、指数部7ビット、仮数部24ビットで表現されている。各部は次のように定義されている。
- 符号部は0を正、1を負とする
- 指数部は16を基数とし、実際の指数に64を足した(ゲタ履き、バイアス)値で表す
- 仮数部は1以下の2進小数とする
符号部は値の符号を表す。
指数部は-1663~-16-64と16-64~1663の範囲が表現できる。これを下回ればアンダーフロー、上回ればオーバーフローとなる。
エクセス64で表現するまでの過程
1.5をエクセス64で表現するには、次のようになる。
1.5×160
ただし、仮数部は1以下でなければならないため、値をシフトする。
ただし、基数が16で、コンピュータの内部表現は2進数であるため、シフト量は4ビットである(24=16)。さらに、シフトしてになったことを相殺するために16の1乗を求める。
値をシフトすることで表現範囲を広げ、丸め誤差を少なくなるようにしている。この操作を正規化という。
正規化を行った結果は次の通り。
0.09375×161
次に指数部をエクセス64で表現する。ただし、負の指数を表すために64をバイアスしなければならない。
バイアスを行うと、0~127を表現できる指数が、-64~+63を表現できる指数になる(-64 + 64 = 0、63 + 64 = 127)。
よって、今回の例では以下のようになる。
0.09375×1665
実際には2進数で表現されているので、2進数に直す。
- 符号部(1ビット):+→0
- 仮数部(24ビット):0.09375→000110000000000000000000
- 指数部(7ビット):65→1000001
浮動小数点数の並び順は 符号部 指数部 仮数部 であるため、
2進値:0 1000001 000110000000000000000000、16進値:41180000
浮動小数点数の精度
浮動小数点数は、表現の仕方から、固定小数点数と比べると誤差が生じやすい。浮動小数点数では次のような誤差が生じることがある。
- オーバーフロー/アンダーフロー : 演算結果が指数部で表現できる範囲を超える場合があるが、最大値を超えた場合はオーバーフロー、絶対値の最小より小さい場合はアンダーフローという。たとえば、IEEE 754では、指数が2-129である場合、アンダーフローである。
- ケタ落ち : たとえば、ほぼ等しい値同士で減算すると結果が非常に小さくなるため、表現できる範囲に入らなくなってしまう。これがケタ落ちである。
- 情報欠落 : 浮動小数点数値を加算するとき、指数を揃えなければならない。指数は大きい方に揃えるが、このときに非常に小さな値と非常に大きな値との加算を行うと、大きな値の指数に揃えなければならないため、小さな値は仮数部が大きくシフトされ、仮数部の表現範囲からあふれて情報が欠落してしまう。
- 丸め誤差 : 浮動小数点数の内部表現は2進数であるため、各ビットの重みは、...となるが、など、2進数で表せない重みが使われると無限小数となり、途中から切り捨てられるために誤差が出る。たとえば、0.05は2進小数にすると...というように循環小数になる。こういう値は丸め誤差として現れてしまう。この誤差は固定小数点数でも10進数で表現していなければ必ず発生する。
- 打ち切り誤差 : 浮動小数点数、固定小数点数を問わず、無理数を扱おうとするとどこかで演算を打ち切ってしまう。これは、コンピュータが有効桁数で処理しているからであり、避けようがない。
関連項目
外部リンク
コンピュータの仕組み | コンピュータのデータ | プログラミング | 数の表現 | 数値解析
Gleitkommazahl | Floating point | Coma flotante | Liukuluku | Virgule flottante | נקודה צפה | Virgola mobile | 부동소수점 | Drijvendekommagetal | Liczba zmiennoprzecinkowa | Vírgula flutuante | Pohyblivá desatinná čiarka | Flyttal | 浮点数