25

私が正しいと思う唯一のことは、プログラマーの観点から浮動小数点値に特に関連するものであり、一般的なものに関連しているという事実だけです CPU の観点からのコンピューティング アプローチ。

誰かが私のためにこの2つの単語を解読できますか?

編集

私は C++ アプリケーションを対象としており、C++ 言語のみを対象としていることを覚えておいてください。

4

4 に答える 4

35

あなたは C++ について尋ねますが、浮動小数点値とエンコーディングの詳細は、C++ ではなく浮動小数点仕様 (特に IEEE 754) によって決定されます。IEEE 754 は、最も広く使用されている浮動小数点仕様であり、それを使用して回答します。

IEEE 754 では、バイナリ浮動小数点値は次の 3 つの部分でエンコードされます。符号ビットs (正の場合は 0、負の場合は 1)、バイアス付き指数e (表現された指数に固定オフセットを加えたもの)、仮数フィールドf (分数部分)。通常の数の場合、これらは正確に数 (−1) s • 2 e −<i>bias • 1. fを表します。ここで、1. fは「1.」の後に仮数ビットを書き込むことによって形成される 2 進数です。(たとえば、仮数フィールドに 10 ビット 0010111011 がある場合、仮数フィールド 1.0010111011 2、つまり 1.182617175 または 1211/1024 を表します。)

バイアスは、浮動小数点形式によって異なります。64 ビット IEEE 754 バイナリの場合、指数フィールドは 11 ビットで、バイアスは 1023 です。実際の指数が 0 の場合、エンコードされた指数フィールドは 1023 です。実際の指数は -2、-1、0、1、および 2 です。 1021、1022、1023、1024、および 1025 の指数をエンコードしています。非正規数の指数がゼロであると誰かが話すとき、それらはエンコードされた指数がゼロであることを意味します。実際の指数は -1022 未満になります。64 ビットの場合、通常の指数間隔は -1022 ~ 1023 (エンコードされた値 1 ~ 2046) です。指数がこの間隔の外に移動すると、特別なことが起こります。

この間隔を超えると、浮動小数点は有限数を表すのをやめます。エンコードされた 2047 の指数 (すべて 1 ビット) は、無限大を表します (仮数フィールドはゼロに設定されます)。この範囲を下回ると、浮動小数点は非正規数に変化します。エンコードされた指数がゼロの場合、仮数フィールドは 1. fではなく0. fを表します。

これには重要な理由があります。最低の指数値が単なる別の通常のエンコーディングである場合、その仮数の下位ビットは小さすぎて、浮動小数点値として単独で表すことはできません。その先頭の「1.」がなければ、最初の 1 ビットがどこにあったかを知る方法はありません。たとえば、指数が最も低く、仮数が 1.0010111011 2と 1.0000000000 2の 2 つの数値があるとします。仮数を減算すると、結果は .0010111011 2. 残念ながら、これを通常の数値として表す方法はありません。既に最低指数にいたため、最初の 1 がこの結果のどこにあるかを示すために必要な下位指数を表すことはできません。数学的結果は小さすぎて表現できないため、コンピューターは表現可能な最も近い数値、つまりゼロを返さなければなりません。

これにより、浮動小数点システムに望ましくないプロパティが作成されますがa != ba-b == 0. それを避けるために、非正規数が使用されます。非正規数を使用することで、実際の指数が減少しない特別な区間があり、小さすぎて表現できない数を作成することなく演算を実行できます。エンコードされた指数が 0 の場合、実際の指数はエンコードされた指数が 1 の場合と同じですが、仮数の値は1. fではなく 0. fに変わります。これを行うと、 の計算値がゼロでないことが保証されます。a != ba-b

以下は、64 ビット IEEE 754 バイナリ浮動小数点のエンコーディングにおける値の組み合わせです。

サイン 指数 ( e ) 有効ビット ( f ) 意味
0 0 0 +ゼロ
0 0 非ゼロ +2 -1022 •0. f (非正規)
0 1~2046 なんでも +2 e -1023 •1. f(ノーマル)
0 2047年 0 +無限大
0 2047年 ゼロではないが上位ビットがオフ +、シグナル NaN
0 2047年 ハイビットオン +、静かな NaN
1 0 0 −ゼロ
1 0 非ゼロ −2 −1022 •0. f (非正規)
1 1~2046 なんでも −2 e −1023 •1. f(ノーマル)
1 2047年 0 −無限大
1 2047年 ゼロではないが上位ビットがオフ −、シグナリング NaN
1 2047年 ハイビットオン −、静かな NaN

いくつかのメモ:

+0 と -0 は数学的に等しいですが、符号は保持されます。慎重に作成されたアプリケーションは、特定の特別な状況でそれを利用できます。

NaN は「非数」を意味します。一般に、これは何らかの非数学的な結果またはその他のエラーが発生したことを意味し、計算を破棄するか別の方法でやり直す必要があります。一般に、NaN を使用した操作は別の NaN を生成するため、何か問題が発生したという情報が保持されます。たとえば3 + NaN、NaN を生成します。シグナリング NaN は、例外を発生させて、プログラムが間違っていることを示したり、他のソフトウェア (デバッガなど) が特別なアクションを実行できるようにすることを目的としています。クワイエット NaN は、NaN が大量のデータ セットの一部に過ぎず、後で個別に処理されるか破棄される場合に、残りの大規模な計算を完了できるように、さらなる結果に伝播することを目的としています。

符号 + と - は NaN で保持されますが、数学的な値はありません。

通常のプログラミングでは、浮動小数点計算の制限と動作について通知される範囲を除いて、浮動小数点エンコーディングについて気にする必要はありません。非正規数に関して特別なことをする必要はありません。

残念ながら、一部のプロセッサは、非正規数をゼロに変更することで IEEE 754 規格に違反したり、非正規数を使用するとパフォーマンスが非常に遅くなったりするという点で壊れています。このようなプロセッサ用にプログラミングする場合、非正規数の使用を避けるように努める場合があります。

于 2012-12-22T11:21:57.710 に答える
12

非正規浮動小数点値を理解するには、最初に正規値を理解する必要があります。浮動小数点値には、仮数と指数があります。1.2345E6のような10進値では、1.2345は仮数、6は指数です。浮動小数点表記の良いところは、いつでも正規化して記述できることです。0.012345E8や0.12345E7と同様に、1.2345E6と同じ値です。つまり、値がゼロでない限り、仮数の最初の桁を常にゼロ以外の数値にすることができます。

コンピューターは浮動小数点値を2進数で格納し、数字は0または1です。したがって、ゼロではない2進数の浮動小数点値の特性は、常に1から始めて書き込むことができるということです。

これは非常に魅力的な最適化ターゲットです。値は常に1で始まるため、その1を格納しても意味がありません。それの良いところは、事実上、無料で追加の精度が得られることです。64ビットdoubleの場合、仮数には52ビットのストレージがあります。暗黙の1のおかげで、実際の精度は53ビットです。

この方法で格納できる最小の浮動小数点値について説明する必要があります。最初に10進数で実行すると、仮数に5桁、指数に2桁のストレージを備えた10進数プロセッサがある場合、ゼロではない最小値は1.00000E-99です。1は、保存されない暗黙の数字です(10進数では機能しませんが、私には耐えられます)。したがって、仮数は00000を格納し、指数は-99を格納します。これよりも小さい数を格納することはできません。指数は-99で最大になります。

ええ、できます。正規化された表現をあきらめて、暗黙の数字の最適化を忘れることができます。非正規化して保存できます。これで、0.1000E-99または1.000E-100を保存できます。0.0001E-99または1E-103まで、現在保存できる絶対最小数です。

これは一般的に望ましいことであり、保存できる値の範囲を拡張します。これは実際の計算で問題になる傾向がありますが、微分解析などの実世界の問題では非常に小さい数が非常に一般的です。

ただし、これには大きな問題もあります。正規化されていない数値では精度が低下します。浮動小数点計算の精度は、格納できる桁数によって制限されます。例として使用した偽の10進数プロセッサを使用すると直感的に理解でき、有効数字5桁でしか計算できません。値が正規化されている限り、常に有効数字5桁を取得します。

ただし、非正規化すると数字が失われます。0.1000E-99と0.9999E-99の間の値には、有効数字が4桁しかありません。0.0100E-99と0.0999E-99の間の値には、有効数字が3桁しかありません。0.0001E-99と0.0009E-99までずっと、有効数字は1桁しか残っていません。

これにより、最終的な計算結果の精度が大幅に低下する可能性があります。さらに悪いことに、これらの非常に小さい非正規化された値は、より複雑な計算に現れる傾向があるため、非常に予測不可能な方法でこれを行います。これは確かに心配なことです。有効数字が1桁しか残っていない場合、最終結果を信頼することはできなくなります。

浮動小数点プロセッサには、これについて通知する方法や、問題を回避する方法があります。たとえば、値が非正規化されたときに割り込みまたは信号を生成して、計算を中断することができます。また、「ゼロにフラッシュ」オプションがあります。これは、すべての非正規値を自動的にゼロに変換するようにプロセッサに指示するステータスワードのビットです。これは無限大を生成する傾向があり、結果はジャンクであり、破棄する必要があることを示す結果です。

于 2012-12-22T11:44:42.880 に答える
3

IEEE ドキュメントから

指数がすべて 0 であるが、小数部がゼロ以外の場合 (そうでない場合はゼロと解釈されます)、値は非正規化数であり、2 進小数点の前に先行する 1 が想定されていません。したがって、これは数値 (-1)s × 0.f × 2-126 を表します。ここで、s は符号ビット、f は分数です。倍精度の場合、非正規化数は (-1)s × 0.f × 2-1022 の形式になります。このことから、ゼロを特別なタイプの非正規化数として解釈できます。

于 2012-12-22T10:12:30.550 に答える