固定小数点数(こていしょうすうてんすう、)は、小数点が置かれる桁を固定して表された数のことで、コンピュータ上で小数を表現する方法として使用される形式のひとつである。ある桁数のうちのある場所に小数点が固定されているもの(固定小数点)として扱う方式であるため、表現される仮数部に対して小数点の位置が移動する浮動小数点数の対義語として用いられる。すなわち、「固定-小数点数」ではなく「固定小数点-数」である。

演算自体は整数型と同じ方法で行われ、小数点位置は設計者の意図によって決定される。十進法で言えば、たとえば整数 123 は下から1桁分を小数部分(小数点以下部分)と決めれば 12.3 を表し、下から2桁分を小数部分と決めれば 1.23 を表すことになる。コンピュータ上での演算で広く使用される二進法では、二進整数 1111011(十進法表記: 123)は下から1桁分を小数部分と決めれば 111101.1(十進法表記: 61.5)、下から2桁分を小数部分と決めれば 11110.11(十進法表記: 30.75)となる。以下の文章では、特に断りがない限り二進固定小数点数について述べる。

特徴 浮動小数点数に比べて表現できる値の範囲ははるかに狭いが、情報落ちが起こらない(そもそも情報落ちが起きるような差のある値は表現できない)ことや高速に演算できることが利点に挙げられる。コンピュータグラフィックスで用いられる座標や画素値はある程度値域が限られるため、固定小数点数でも表現することができ浮動小数点数にくらべ高速に計算できるようになる。また、コンパイラなどにおいて、変数を定数で除算するような場合、普通に除算するよりも、除数の逆数を固定小数点の要領で表現したものを乗じてシフトして答えを求めた方が高速であることがあるため、そのような最適化をおこなうことがある。

なお、信号処理を実行するためのデバイスであるデジタルシグナルプロセッサでは、処理対象である信号の振幅の値の範囲が固定小数点的であるので、コストの高い浮動小数点演算のハードウェア (FPU) を搭載せず、固定小数点数が主に用いられる。現代のパソコンにおいては、演算を行うCPUにFPUが付属するものが主流であるため、小数の計算は一般に浮動小数点数を用いるものがほとんどだが、対象とするデータの特性や特に高速化が必要なコーデックなどでは固定小数点を用いることもある。

また、十進法での小数は二進法の小数として表現すると必ずしも有限小数とはならず、誤差を生じる。そのため、貨幣に関する計算のような、小数点以下で必要な桁数は決まっているが、二進法との変換を回避したい場合に、小数点以下の桁数をビット単位ではなく十進法の桁数で決めた固定小数点数も処理に用いられる通貨型 PostgreSQL 9.2.4文書(2014年2月3日閲覧)。。当然のことだが、十進計算が万能で無誤差というわけではない。例えば、3の倍数でない値を3で割る場合、十進計算では解が無限小数になるため、誤差は避けられない。

Q表記(Qフォーマット) Q表記(Qフォーマット)は、固定小数点数の小数部分のビット数を指定する表記法である。例えば、小数部分のビット数が12ビットである場合には、Q12表記もしくはQ12フォーマットと呼ばれる。

例えば、十進数 1.5 は二進法では(添字の2は二進法表記であることを示す)となる。これをQ2表記で表現すると、二進データはとなり、下位2ビットを小数部分と見てと解釈される。Q12表記だと、二進データはとなり、下位12ビットを小数部分と見てと解釈される。

固定小数点演算 固定小数点演算における四則演算においては、加算や減算はそのまま整数同士の加減算として計算できる。しかし、乗算や除算では演算結果の小数点位置が掛けた数の小数点の位置だけずれることになるため、元の小数点位置に戻す場合には乗算では右側(LSB側)へ、除算では左側(MSB側)へシフト演算を行う必要がある。

ここでは例えば、1.5 と 0.5 の加算をQ1表記の固定小数点で行う場合を考えてみる。1.5 と 0.5 の二進表記は各々となので、Q1表記の二進データは各々、である。この二進データを単なる二進整数と見なしてそのまま足してみるととなる。結果のをQ1表記とみなすとで、十進に直せば2.0となる。このように、加算は同じQ表記同士なら整数同士の計算としてそのまま実行することができる。

次に乗算をQ1表記の固定小数点で行う場合を考える。まず 1.5 と 0.5 のQ1表記の二進データであるとを二進整数と見なして単純に掛けてみるととなる。これをQ1表記として解釈すると(十進表記: 1.5)であり、正しい結果の0.75と一致しない。固定小数点同士の乗算では、結果の小数部分のビット数は、掛け合わせる2つの固定小数点数(この例で言えばと)の小数部分のビット数を足したものになる。この例ではQ1表記同士の乗算なので、乗算結果の小数部のビット数は 1ビット + 1ビット = 2ビット となり、乗算結果はQ2表記として解釈する必要がある。結果のをQ2表記として解釈するとで、十進に直せば0.75となり、求める答えが得られたことがわかる。Q2表記で得られた結果をQ1表記に直すには、1ビット右にシフトする必要がある。ただし、nビット右シフトをすれば最下位のnビットは失われる(下位nビットの切り捨てが行われる)ことになる。この例でも、乗算結果を右シフトでQ1表記に直すと最下位ビットが切り捨てられ、値は(十進表記: 0.5)となる。この計算例の場合、Q1ではなく小数部分がもっと長いQ2以上の表記を使えば切り捨ては回避できる。しかし、小数部分のビット数を一つ増やすごとに表現できる値の範囲は半分に減っていくので例えば、8ビット符号付き整数型(負数表現は2の補数)の数を固定小数点数として扱う場合を考える。元の整数型で表現可能な値の範囲は -128 () から 127 () だが、これをQ1表記と見なすと表現可能な範囲は -64 () から 63.5 () になり、Q2表記と見なすと -32 () から 31.75 () になる。8ビットではなく16ビットや32ビットの整数型を使えば表現可能範囲ははるかに広くなるが、小数部分が長くなるごとに範囲が指数関数的に減るのは同じである。、計算に必要な精度と計算で扱う値の範囲を考え、適切な小数部分の長さを選択しなければならない。

また、固定小数点数は浮動小数点数にくらべ表現可能な範囲が狭く、算術オーバーフローや算術アンダーフローが発生しやすい点に注意が必要である。

固定小数点数の精度 固定小数点方式で有効桁数が十分にとれるのは、(符号ビットを除く)最上位桁が1の範囲内だけである。この時の相対誤差は桁数がn桁の時1/2nである。表現しようとする数が0に近づき上位桁が0で埋まる(ないし2の補数表現の負の数であれば1で埋まる)と、有効桁数はそれだけ減るので、その場合に必要な精度を満たしているか注意が必要である。

実数値と固定小数点数値の換算

ある実数を x とし、これを固定小数点数で表した整数を n とする。最下位ビットを実数 L、オフセットを実数 O と定めると、実数 x は固定小数点数で次の数 n となる。ここで、round は四捨五入関数である。

固定小数点数 n から実数 x は次のように求まる。

脚注

注釈

出典

関連項目 コンピュータの数値表現 浮動小数点数 二進化十進表現 (BCD) 誤差、端数処理