「規格 - 浮動小数点数」の版間の差分

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
12行目: 12行目:
例えば、0.1を浮動小数点数で表すと、0.1<sub>(10)</sub> = 0.000110011001100110011...<sub>(2)</sub>と無限に続くが、コンピュータ内部では有限桁で丸められるため、<br>
例えば、0.1を浮動小数点数で表すと、0.1<sub>(10)</sub> = 0.000110011001100110011...<sub>(2)</sub>と無限に続くが、コンピュータ内部では有限桁で丸められるため、<br>
真値ではなく、近似値で表現することになる。<br>
真値ではなく、近似値で表現することになる。<br>
<br><br>
== IEEE 754 ===
==== 例: 10進数をIEEE754形式にする ====
以下の例では、<math>9.875_{(10)}</math> をIEEE754形式の浮動小数点に変換している。<br>
<br>
# 10進数を2進数に基数変換する
#: まず、<math>9.875</math> を2進数に基数変換する。
#: 整数部分の <math>9_{(10)}</math> は、2進数で <math>1001_{(2)}</math>、小数部分の <math>0.875_{(10)}</math> は2進数で <math>0.111_{(2)}</math> となる。
#: この2つ合わせると、<math>9.875_{(10)}</math> は <math>1001.111_{(2)}</math> となる。
#: <br>
# 2進数を指数表記にする。(正規化)
#: <math>1001.111_{(2)}</math> を指数表記にする。
#: 指数表記では、仮数が10未満の小数を含む数にする。
#: つまり、<math>1.M</math> という形に正規化する。
#: これを、ケチ表現と呼ぶ。
#: <br>
#: したがって、仮数を <math>2^{3}</math> した <math>1.001111 \times 2^{3}</math> という形になる。
#: <br>
# 浮動小数点数のビットに格納する
#: 指数表記から浮動小数点数に格納する数に変換する。
#: <br>
#:* 仮数部
#:*: <math>1.001111 \times 2^{3}</math> は正であるため、IEEE754形式の仮数部は <math>0</math> となる。
#:* 指数部
#:*: <math>1.001111 \times 2^{3}</math> の指数は <math>3_{(10)}</math> であるため、(8ビットの)2進数にすると <math>00000011</math> となる。
#:*: さらに、指数に <math>01111111_{(2)} \, \, = 127_{(10)}</math> を加算すると、<math>10000010</math> となる。
#:* 仮数部
#:*: 上記で求めた仮数 <math>1.001111</math> の小数点以下の数 <math>001111</math> を仮数部の先頭から格納する。
#:*: <math>001111</math> 以降の数は <math>0</math> でパディングする。
#: <br>
# 変換完了
#: これにより、<math>9.875_{(10)}</math> をIEEE754形式の32ビットの浮動小数点数にした値は <math>01000001000111100000000000000000_{(2)}</math> となる。
<br><br>
<br><br>



2024年6月21日 (金) 20:17時点における版

概要

浮動小数点数とは、実数の表現方法の1つであり、2進数の有限桁数で表された数値である。(対義語は、固定小数点数)
小数点の位置を変えて表現するため、浮動(動く)の小数点と呼ばれる。

固定小数点数は、小数点の位置を固定して表現される。

以下に、浮動小数点数の例を示す。

1.5(10) = 1.1(2)
3.25(10) = 11.01(2)


> 理論的には小数が無限に続く値でも、その内の有限個の桁数でその値を表す。
例えば、0.1を浮動小数点数で表すと、0.1(10) = 0.000110011001100110011...(2)と無限に続くが、コンピュータ内部では有限桁で丸められるため、
真値ではなく、近似値で表現することになる。


IEEE 754 =

例: 10進数をIEEE754形式にする

以下の例では、 をIEEE754形式の浮動小数点に変換している。

  1. 10進数を2進数に基数変換する
    まず、 を2進数に基数変換する。
    整数部分の は、2進数で 、小数部分の は2進数で となる。
    この2つ合わせると、 となる。

  2. 2進数を指数表記にする。(正規化)
    を指数表記にする。
    指数表記では、仮数が10未満の小数を含む数にする。
    つまり、 という形に正規化する。
    これを、ケチ表現と呼ぶ。

    したがって、仮数を した という形になる。

  3. 浮動小数点数のビットに格納する
    指数表記から浮動小数点数に格納する数に変換する。

    • 仮数部
      は正であるため、IEEE754形式の仮数部は となる。
    • 指数部
      の指数は であるため、(8ビットの)2進数にすると となる。
      さらに、指数に を加算すると、 となる。
    • 仮数部
      上記で求めた仮数 の小数点以下の数 を仮数部の先頭から格納する。
      以降の数は でパディングする。

  4. 変換完了
    これにより、 をIEEE754形式の32ビットの浮動小数点数にした値は となる。



浮動小数点数の構造

単精度浮動小数点数(float型)

単精度浮動小数点数(float型)は、4バイトのサイズを持ち、符号部(1bit)、指数部(8bit)、仮数部(23bit)で表す。

指数部は、-127のバイアスが掛かる。
仮数部は、仮数の小数点以下を表す。すなわち、仮数は仮数部の先頭に1(ケチ表現)を付加したものとなる。

単精度浮動小数点数(float型)の表す値 = (-1)符号部 × 2(指数部 - 127) × 1.仮数部


単精度浮動小数点数(float型)の精度(有効桁数)は、2進数では24(=23 + 1)桁、10進数では約7桁となる。
指数部も有限であるため、単精度浮動小数点数(float型)で表すことのできる実数の絶対値は、以下の範囲に限られる。


C言語において、単精度浮動小数点数の下限値および上限値は、float.hファイルのFLT_MINおよびFLT_MAXというマクロで定義されている。

 #include <stdio.h>
 #include <float.h>
 
 int main()
 {
    printf("FLT_MIN = %e,  FLT_MAX =%e\n", FLT_MIN, FLT_MAX);
 
   return 0;
 }


倍精度浮動小数点数(double型)

倍精度浮動小数点数(double型)は、単精度浮動小数点数(float型)に比べて、倍の精度(8byte)を持ち、符号部(1bit)、指数部(11bit)、仮数部(52bit)で表す。

指数部は、-1023のバイアスが掛かる。
仮数部は、仮数の小数点以下を表す。すなわち、仮数は仮数部の先頭に1(ケチ表現) を付加したものとなる。

倍精度浮動小数点数(double型)の表す値 = (-1)符号部 × 2(指数部 - 1023) × 1.仮数部


倍精度浮動小数点数(double型)の精度(有効桁数)は、2進数では53(=52 + 1)桁、10進数では約15桁となる。

指数部も有限であるため、倍精度浮動小数点数(double型)で表すことができる実数の絶対値は、以下の範囲に限られる。


C言語において、単精度浮動小数点数の下限値および上限値は、float.hファイルのDBL_MINおよびDBL_MAXというマクロで定義されている。

 #include <stdio.h>
 #include <float.h>
 
 int main()
 {
    printf("DBL_MIN = %e,  DBL_MAX =%e\n", DBL_MIN, DBL_MAX);
 
    return 0;
 }


現在のコンピュータでは、float型よりもdouble型を使用することが多い。
その理由として、以下が挙げられる。

  • 精度が良い。
  • 計算速度が速い。


計算速度が速い理由は、現在のコンピュータには、double型のデータを扱う専用回路が存在するからである。
float型の計算を行う場合、double型に変換した後、double型の専用回路で計算して、再度float型に変換するため、float型の方が計算時間が多く掛かる。


浮動小数点数の誤差

丸め誤差

仮数部が循環小数となる場合、仮数(の桁)が有限になるため、特定の桁数で四捨五入・切り捨て等を行うことにより発生する誤差である。
10進数を2進数に変換する時に、発生する誤差のことである。

桁落ち

桁数が決まっている浮動小数点数において、絶対値がほぼ等しい数値を減算した時に、実際の数値と比べて著しく桁数が減る誤差のことである。
(桁が落ちるのは、基本的に少数以下の部分である)

絶対値がほぼ等しい値同士を減算する場合、その差異は非常に小さな値となる。
浮動小数点数では桁数が決まっているため、非常に小さい値は切り捨てられる場合が多い。
この値を正規化する時、非常に小さい値は切り捨てられているため、0となり、実際の数値より小数点以下の桁数が大きく減ってしまう。

例.
以下のような絶対値のほぼ等しい値があるとする。
A = 1.1111111123334455667788
B = 1.111111111111111111111122

A - Bを行った後、正規化する。
1.2223344556666×10-7 (1)

上記を、有効桁数10桁の浮動小数点数で計算する。
a = 1.111111123
b = 1.111111111

a - bを行った後、正規化する。
1.200000000×10-7 (2)

上記の(1)を有効桁数10桁に変換する。
(2)は(1)と比べて桁数が減少して、ほぼ等しい値にも関わらず、大きな誤差が生じていることが分かる。
1.222334455×10-7 … (1)
1.200000000×10-7 … (2)

情報落ち

絶対値の差が非常に大きい2つの値の加減算を行う場合、小さい値が無視される誤差のことである。
桁数の決まっている浮動小数点数の計算において発生する誤差である。

浮動小数点数の加減算は、指数部を大きい方に揃えてから仮数部同士の計算をするため、値の差が大きいと小さい値は指数を大きくするために仮数部が0になるからである。

例 以下のような大きな値と小さい値があるとする。
A=1100000000000
B=0.11

両方の値を有効桁数10桁の浮動小数点数に変換する。
a = 1.100000000×1012
b = 1.100000000×10-1

この時、bの指数をaに合わせると仮数部が0となり情報が落ちる。
b = 0.000000000×1012

打ち切り誤差

無限小数等の値に対して、ある程度の時点で処理を打ち切ることで発生する誤差のことである。

丸め誤差との違いを以下に示す。

  • 丸め誤差
    10進数から2進数に変換する場合等に、特定の桁数で四捨五入や切り捨て等を行うことで生じる誤差。
  • 打ち切り誤差
    円周率等の無限小数が続く計算を途中で止めることで生じる誤差。