単精度浮動小数点数のソースを表示
←
単精度浮動小数点数
ナビゲーションに移動
検索に移動
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループに属する利用者のみが実行できます:
登録利用者
。
このページのソースの閲覧やコピーができます。
[[情報処理]]において、'''単精度浮動小数点数 '''(たんせいどふどうしょうすうてんすう、{{lang-en-short|single-precision floating-point number}})は、[[コンピュータの数値表現]]の一種である。 本来の単精度浮動小数点数とは、倍精度浮動小数点数に対比して使われる用語であって倍精度浮動小数点数が無いシステムであれば単に浮動小数点数と呼ばれるべきものである(また浮動小数点数はもともと固定小数点数と対比させた言葉であった)。 そうして、単精度はシステムの基本となる精度であり、バイトマシン(キャラクターマシン)が普通になる前のワードマシンにおいて1語長分の記憶場所を占める浮動小数点数であるのが普通である。 昔のFORTRAN言語では、整数型と実数型は同じ語長を占めることを前提に言語の規格が制定されていたりもした。その記憶語1単位分のを占める実数型が単精度であり、記憶語2単位分を占める実数型は倍精度と呼ばれた。 Crayのベクトルマシンのような語長が64ビットである科学技術専用計算機では、たとえば単精度とは64ビットを意味した。 現在の[[浮動小数点数|浮動小数点]]形式の標準である[[IEEE 754]]では、単精度は[[32ビット]](4[[オクテット (コンピュータ)|オクテット]])、[[倍精度]]は[[64ビット]](8オクテット)である。IEEE 754-2008 では単精度の形式は正式には '''binary32''' と呼ばれている。「単」や「倍」という表現は32ビットを1ワードとする32ビットアーキテクチャを基にしている。 単精度浮動小数点数は、同じ幅の[[固定小数点数]]に比べてより広範囲な数値を表せるようになっているが、同時に精度を犠牲にしている。 ほとんどの[[プログラミング言語]]では標準の組み込み型として定義されている。[[C言語]]、[[C++]]、[[C Sharp|C#]]、[[Java]]、[[Haskell]]では単精度のデータ型を '''float''' と呼ぶ<ref>http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html</ref>が、C/C++の規格ではIEEE 754に準拠することは要求されていない。[[MATLAB]]では '''single''' と呼ぶ。[[Pascal]]および[[Visual Basic .NET]]では '''Single''' と呼ぶ。[[.NET Framework]]の[[共通型システム]]では<code>System.Single</code>[[構造体]]型として定義されており、各.NET言語における組み込み型はこの型へのエイリアスである。{{要出典範囲|date=2019-07|バージョン3.2以前の[[GNU Octave|Octave]]では '''single''' という名前だが[[倍精度]]である}}。[[Python]]の '''float''' は倍精度であり、単精度のサポートはない。[[F Sharp|F#]]の単精度は '''float32''' または '''single''' であり、倍精度は '''float''' または '''double''' である。 == IEEE 754 での単精度浮動小数点数の形式: binary32 == [[IEEE 754]] での '''binary32''' の定義は次の通りである。 * 符号ビット: 1ビット * 指数部の幅: 8ビット * [[仮数]]部の幅: 23ビット 符号ビットは表現する数値の符号(正負)を示す。指数部は 8 ビットで、符号なし整数として見た場合は 0 から 255 の値をとり、0 の時はゼロか[[非正規化数]]であることを、1 から 254 の時は -127 のゲタ履き(バイアス付き)表現で -126 から 127 の指数を、255 の時は無限大または NaN であることを示す。 指数部が 0(ゼロ、および非正規化数)の場合を除き、仮数部で表現されるビットパターンのさらにひとつ上のケタに暗黙の 1 のビットがあるとみなす表現法(いわゆる「ケチ表現」)により、通常の数(正規化された数)の精度は、24ビット相当である。従って十進に換算したとき表現できる桁数は log{{sub|10}}(2{{sup|24}}) ≈ 7.225 桁となる。標準化されたレイアウトは以下のようになる。 [[ファイル:Float example.svg]] 符号ビットを '''sign'''、バイアスつきの指数部を '''e'''、23ビットの仮数部の各ビットを '''b{{sub|-n}}''' とすると、32ビットの binary32 フォーマットで表される数値は <math>(-1)^{\text{sign}}(1.b_{-1}b_{-2}...b_{-23})_2 \times 2^{e-127} </math> となり、より正確に表現すると <math> \text{value} = (-1)^{\text{sign}}\left(1 + \sum_{i=1}^{23} \ b_{-i}2^{-i} \right)\times 2^{e-127}</math> となる。 === 指数部の符号化方式 === 単精度バイナリ浮動小数点数の指数部はオフセット表現を使って符号化されており、指数値がゼロのときのオフセット値(バイアス値)は127である。 * E<sub>min</sub> = 01<sub>H</sub>−7F<sub>H</sub> = −126 * E<sub>max</sub> = FE<sub>H</sub>−7F<sub>H</sub> = 127 * 指数部バイアス = 7F<sub>H</sub> = 127 指数部バイアスは、エクセスNとも言う。詳しくは[[符号付数値表現]]を参照されたい。真の指数値は、指数部の値から指数部バイアスを引いた値となる。 00<sub>H</sub> と FF<sub>H</sub> は予約された指数値である。 {|class="wikitable" style="text-align:center" ! 指数部 !! 仮数部がゼロの場合 !! 仮数部がゼロでない場合 !! 式 |- | 00<sub>H</sub> || [[0]], [[−0]] || [[非正規化数]] || (−1)<sup>signbits</sup>×2<sup>−126</sup>× 0.significandbits |- | 01<sub>H</sub>, ..., FE<sub>H</sub> ||colspan=2| 正規化数 || (−1)<sup>signbits</sup>×2<sup>exponentbits−127</sup>× 1.significandbits |- | FF<sub>H</sub> || ±[[無限]]大 || [[NaN]] (quiet, signalling) |} 従って、全てのビットパターンが符号として意味がある。正の最小値(非正規化数)は 2<sup>−149</sup> ≈ 1.4 × 10<sup>−45</sup> である。正の正規化数の最小値は 2<sup>−126</sup> ≈ 1.18 × 10<sup>−38</sup> である。表現可能な最大値は (2−2<sup>−23</sup>) × 2<sup>127</sup> ≈ 3.4 × 10<sup>38</sup> である。 === 十進表現から binary32 フォーマットへの変換 === IEEE754 では実数値から対応する binary32 フォーマットへの変換を丸めも含めて厳密に定めている。 ここでは十進の実数値から IEEE 754 binary32 フォーマットへの変換は大まかに次のようになる。 * 実数値を 12.375 のように整数部と小数部で表すものとする。 * 整数部を[[二進法]]で表現したものに変換する。 * 小数部を以下に示す技法で変換する。 * 2つの変換結果を組み合わせ、さらに変換を加えて最終的な表現を得る。 '''小数部の変換:''' 12.375 の小数部 0.375 を例とする。これを二進の小数に変換するため、小数部に2をかけて整数部をとり、さらに2をかけて整数部をとるというように繰り返していき、小数部がゼロになるか精度の上限である二進23桁になるまで続ける。 0.375 x 2 = 0.750 = 0 + 0.750 ⇒ b{{Sub|−1}} = 0 となるので、二進での小数部の一桁目はゼロとなる。そこでさらに 0.750 に2をかける。 0.750 x 2 = 1.500 = 1 + 0.500 ⇒ b{{Sub|−2}} = 1 0.500 x 2 = 1.000 = 1 + 0.000 ⇒ b{{Sub|−3}} = 1 となり、小数部が 0.000 となったのでここで変換は停止する。 これで (0.375){{Sub|10}} は正確に二進で (0.011){{Sub|2}} で表されることがわかった。十進で有限桁数の小数が必ず二進で有限桁で表せるわけではない。例えば、十進の 0.1 は二進では正確に表現できないため近似値を用いることになる。 したがって、(12.375)<sub>10</sub> = (12)<sub>10</sub> + (0.375)<sub>10</sub> = (1100)<sub>2</sub> + (0.011)<sub>2</sub> = (1100.011)<sub>2</sub> となる。 IEEE 754 binary32 フォーマットでは、値を <math> (1.x_1x_2...x_{23})_2 \times 2^{e}</math> という形式で表現しなければならないので、1100.011 をシフトして整数部が一桁になるようにしなければならない。この例では3桁シフトするので <math> (1.100011)_2 \times 2^{3} </math> となる。 最終的に <math> (12.375)_{10} =(1.100011)_2 \times 2^{3} </math> となる。 この結果から次が得られる。 * 指数部は 3 となる(バイアスを加えるので実際は 130 = 1000 0010 となる)。 * 仮数部は 100011 となる(小数点より右側だけを仮数とする)。 したがって、IEEE 754 binary32 フォーマットで 12.375 を表すと 0-10000010-10001100000000000000000 = 41460000<sub>H</sub> となる。 '''注:''' 68.123 を IEEE 754 binary32 フォーマットで表す場合を考えてみよう。上述の技法を適用すると 42883EF9<sub>H</sub> というビット列が得られ、最後の4ビットは 1001 となる。しかし、IEEE 754 のデフォルトの丸め方式により最終的に 42883EFA<sub>H</sub> となり、最後の4ビットは 1010 となる。 '''例:''' 十進の1を変換すると <math> (1)_{10} =(1.0)_2 \times 2^{0} </math> となる。ここから次のことが導かれる。 * 指数は 0 である(バイアスを加えるので 127 = 0111 1111 となる)。 * 仮数は 0 である(小数点より右側はゼロなので仮数部のビット列は全てゼロになる)。 従って実数 1 を IEEE 754 binary32 フォーマットで表すと 0-01111111-00000000000000000000000 = 3f800000<sub>H</sub> となる。 '''例:''' 0.25 を変換すると、<math> (0.25)_{10} =(1.0)_2 \times 2^{-2} </math> となる。ここから次のことが導かれる。 * 指数は -2 である(バイアスを加えるので 127+(−2)= 125 = 0111 1101 となる)。 * 仮数は 0 である(小数点より右側はゼロなので仮数部のビット列は全てゼロになる)。 従って実数 0.25 を IEEE 754 binary32 フォーマットで表すと 0-01111101-00000000000000000000000 = 3e800000<sub>H</sub> となる。 '''例:''' 0.375 を変換すると、<math> 0.375 = {(1.1)_2}\times 2^{-2} </math> となる。ここから次のことが導かれる。 * 指数は -2 である(バイアスを加えるので 127+(−2)= 125 = 0111 1101 となる)。 * 仮数は 1 である(1.1 の小数点より右側は 1 = x{{sub|1}} のみである)。 従って実数 0.375 を IEEE 754 binary32 フォーマットで表すと 0-01111101-10000000000000000000000 = 3ec00000<sub>H</sub> となる。 === 単精度浮動小数点数の例 === 浮動小数点数値のビット列を[[十六進法]]で表した例を以下に示す。これには符号、バイアスを加えた指数値、仮数値が含まれている。 3f80 0000 = 1 c000 0000 = -2 7f7f ffff ≒ 3.4028234 x 10<sup>38</sup> (単精度浮動小数点数の正の最大値) 0000 0000 = 0 8000 0000 = -0 7f80 0000 = 正の無限大 ff80 0000 = 負の無限大 3eaa aaab ≒ 1/3 1/3 は[[倍精度]]とは異なり、切り上げられる。これは仮数部のビット数が偶数であるため、丸める桁位置以降が <code>1010...</code> となってその桁位置で 1/2 より大きくなるためである。 === 単精度バイナリ形式から十進への変換 === 16進の値 41c80000 を例として変換を行う。これを二進で表すと次のようになる。 41c8 0000<sub>16</sub> = 0100 0001 1100 1000 0000 0000 0000 0000<sub>2</sub> これを、符号ビット、指数部、仮数部の3つに分割する。 符号ビット: 0 指数部: 1000 0011<sub>2</sub> = 83<sub>16</sub> = 131 仮数部: 100 1000 0000 0000 0000 0000<sub>2</sub> = 480000<sub>16</sub> ここで仮数部に暗黙の整数ビットを加える。 仮数: '''1'''100 1000 0000 0000 0000 0000<sub>2</sub> = C80000<sub>16</sub> 指数部の値から127を引いて実際の指数値を得る。 指数部の値: 83<sub>16</sub> = 131 本来の指数: 131 − 127 = '''4''' 24ビットの仮数は最上位ビットが1に対応し、次の桁が0.5、その次が0.25というように、前の桁の1/2に対応している。 bit 23 = 1 bit 22 = 0.5 bit 21 = 0.25 bit 20 = 0.125 bit 19 = 0.0625 . . bit 0 = 0.00000011920928955078125 この例では、仮数で立っているビットは bit 23、bit 22、bit 19 の3ビットだけであり、上記の対応する値を加算することで十進での仮数が得られる。 本来の仮数: 1 + 0.5 + 0.0625 = 1.5625 = C80000/2<sup>23</sup> 基数 2 を指数値でべき乗したものを仮数にかけると本来の値が得られる。 1.5625 × 2<sup>4</sup> = '''25''' 従って 41c8 0000 = 25 となる。これは次の式と等価である。 <math>n = (-1)^s \times (m2^{-23})\times 2^{x - 127}</math> ここで <math>s</math> は符号ビット、<math>x</math> は指数部、<math>m</math> は仮数を基数10で表したものである。 == MSXの場合 == MSX-BASICの演算ルーチンMATHPACKの場合、同様に4バイトで表すが、IEEE 754とは異なり * s(符号ビット): 1 * y(指数部の幅): 7 * x(仮数部の幅): 24 syyy yyyy xxxx xxxx xxxx xxxx xxxx xxxx であり、指数部をバイナリ、仮数部を[[二進化十進表現|BCD]]で表現する。 そのため、有効数字は正確に10進で6桁で、指数は±63乗である。 他のパソコンのBASICはほとんどが2進での演算であった(他にBCDを採用した機種として[[FP-1000]]がある)。 2進小数の主な利点は高速性とメモリ消費にあり、BCD小数の主な利点は現実の10進小数を誤差なく扱える事にあったと言ってよい。 2進小数は原理上0.5や0.25、0.375といったn/(2^m)以外の値、つまり0.1や0.2といった数値を正確に扱う事が苦手であり(表示上は補正されているが、10進小数を2進小数に変換すると殆どの場合循環小数となり、微小な切り捨てが発生する)高速性よりも(10進の世界での)正確性が優先されるようなケースにおいてBCD小数は強みを発揮した(各種利息計算など)。 ただし当時のスペックにおいて10進小数は相応に重い処理であり、DAAという10進補正用の専用CPU命令を持っていたZ80であっても複雑な演算になればなるほど(例えば三角関数や対数関数のような数学関数)2進小数より負荷が増していく。 MSX-BASICにおいて10進小数が採用された理由は、マイクロソフトBASICの中でも比較的後期に開発され新しい実装を試せた事、加えてホームコンピュータという需要の開拓においてより一般性を高めたいアスキー側の狙いがあったと考えられる。 CPUの浮動小数点ユニットとの相互運用を視野に入れなければならない現代の言語では、特殊な用途を除いてBCD小数を目にする機会は少ない。 == 脚注・出典 == {{Reflist}} == 関連項目 == * {{コンピュータの数値精度}} * [[IEEE 754]] * [[浮動小数点数]] * [[プリミティブ型]] * [[数値的安定性]] == 外部リンク == * [https://web.archive.org/web/20070424205950/http://www.h-schmidt.net/FloatApplet/IEEE754.html Online calculator] * [http://www.binaryconvert.com/convert_float.html Online converter for IEEE 754 numbers with single precision] * [http://www.decimal2binary.com/decimal-to-binary.php Online converter Decimal to binary] * [http://www.mathworks.com/matlabcentral/fileexchange/23173 IEEE 754r Half Precision floating point converter] : IEEEの倍精度・単精度・半精度の間での変換を行うCのソースコードがある。 {{データ型}} {{DEFAULTSORT:たんせいと}} [[Category:コンピュータの算術]] [[Category:データ型]] [[Category:プログラミング]]
このページで使用されているテンプレート:
テンプレート:Lang-en-short
(
ソースを閲覧
)
テンプレート:Reflist
(
ソースを閲覧
)
テンプレート:Sub
(
ソースを閲覧
)
テンプレート:Sup
(
ソースを閲覧
)
テンプレート:コンピュータの数値精度
(
ソースを閲覧
)
テンプレート:データ型
(
ソースを閲覧
)
テンプレート:要出典範囲
(
ソースを閲覧
)
単精度浮動小数点数
に戻る。
ナビゲーション メニュー
個人用ツール
ログイン
名前空間
ページ
議論
日本語
表示
閲覧
ソースを閲覧
履歴表示
その他
検索
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
特別ページ
ツール
リンク元
関連ページの更新状況
ページ情報