浮動小数点数
コンピュータ上で実数を扱うときには 浮動小数点数 が用いられます。 32bit の浮動小数点数を単精度(single あるいは float)、64bit の浮動小数点数を倍精度(double)と呼ばれます。 また、16bit の半精度、128bit の 4 倍精度や、精度が可変長である多倍長精度が用いられることもあります。
浮動小数点数は符号部と指数部、仮数部を持ちます。 その 3 つの部分を決められた精度の bit 列に格納します。 符号部を 、指数部を 、仮数部を とすると、実数 は以下のように表されます。
、、 をそれぞれ符号化し、bit 列に格納する必要があります。 それらをどのように格納するかには数多くの方法が考えられるため、一般的なコンピュータで採用されている標準的な規格が存在します。
IEEE 754
多くのコンピュータでは、浮動小数点数の規格として IEEE 754 が採用されています。 以下では単精度の浮動小数点数について説明していきます。
IEEE 754 形式では、単精度(32bit)の浮動小数点数は 8bit の指数部 と 23bit の仮数部 を持ちます。 と 、 の関係は以下のようになります。
すなわち、 が 1 のとき指数部は-126 となります。
実数を表す上で の有効な範囲は 1 から 254 までです。 が 0 のときと 255 のときは後述する特殊な数の表現に使用されます。
特殊な数の表現
コンピュータで数値計算を行う上では、正負の無限大 や計算不可能な未定義の値 NaN(Not a Number) を扱う必要があります。 例えば は未定義の値 NaN となります。 また、IEEE 754 の正規化の都合により、0 は特別な表現が必要です。
IEEE 754 では、これらの特殊な数を以下のように表現することが定められています。
数 | 指数部 | 仮数部 |
---|---|---|
0 | 0 | 0 |
255 | 0 | |
NaN | 255 | 非 0 |
負の無限大 や -0.0 は と 0.0 の符号部をそれぞれマイナスにすることによって表現します。
JavaScript による確認
JavaScript では、ArrayBuffer と DataView によって、同一ビット列を Float32 や Uint32 等の異なる数値型として解釈することができます。 これを用いて、0.75 がビット列としてどのように表現されるか確認してみましょう。
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setFloat32(0, 0.75);
const bits = view.getUint32(0);
console.log(bits.toString(2).padStart(32, "0"));
実行結果は以下のようになります。
00111111010000000000000000000000
IEEE 754 の形式と一致していることが確認できます。