2011-10-04 14 views
16

私はそれが仮名と指数の形で保存されていると読んでいます浮動小数点数はどのようにメモリに格納されていますか?

私はthis documentを読みましたが、何も理解できませんでした。

+1

を使用し、C++で

  • #ifdef __STDC_IEC_559__を使用しています。具体的に何が分かりにくいですか? –

  • +1

    @MichaelBorgwardtいいえ、明らかではありません。この説明を必要とする問題を導入した後に指数がどのように格納されるかを説明します(「数字がゼロの場合はどうしたらいいでしょうか?」「ああああ」)。それは、あなたがすべての情報を表示していないが、物語の主人公がそれらをすべて知っているというトリックである犯罪物語のようなものです。 – xanatos

    答えて

    25

    http://en.wikipedia.org/wiki/Double_precisionは、それらが保存されているか、あなたが最初に彼らは何であり、彼らが扱うことが意図されている値の種類を理解する必要があります理解します。

    整数とは異なり、浮動小数点値は極端に小さい値と非常に大きな値を表すことを意図しています。通常の32ビット浮動小数点値の場合、 1.175494351 * 10^-38 3.40282347 * 10^+ 38の範囲の値に相当します。

    明らかに、32ビットのみを使用すると、そのような数値にすべての数字を格納することはできません。

    表現に関しては、すべての通常の浮動小数点数を1.0〜(ほぼ)2.0の範囲の値で2の累乗でスケーリングすることができます。したがって、1.0は、単に 1.0 * 2^0です。 2。0は 1.0 * 2^1です。 -5.0は、 -1.25 * 2^2である。

    これを可能な限り効率的にエンコードする必要がありますか?何が本当に必要なの?

    • 表現の記号。
    • 指数
    • 1.0〜(ほぼ)2.0の範囲の値。これは「仮数」すなわち仮数詞として知られている。

    これは、IEEE-754浮動小数点標準に従って次のようにエンコードされます。

    • 記号はシングルビットです。
    • 指数は符号なし整数として格納され、32ビットの浮動小数点値の場合、このフィールドは8ビットです。 1は最小の指数を表し、 "すべて1 - 1"が最大です。真中の値(32ビットの場合は127)は0を表し、バイアスとも呼ばれます。
    • 仮数(1.0と(ほぼ)2.0の間の値)を見ると、すべての可能な値が「1」(10進数表記と2進表記の両方)で始まることがわかります。つまり、それを保存することは意味がありません。残りの2進数字は整数フィールドに格納され、32ビットの場合にはこのフィールドは23ビットです。

      • ゼロはゼロの両方指数と仮数を用いて符号化される:

      通常の浮動小数点値に加えて、特別な値の数があります。符号ビットは、「プラスのゼロ」および「マイナスのゼロ」を表すために使用されます。マイナスゼロは、操作の結果が極端に小さい場合に役立ちますが、操作の進行方向を知ることは重要です。

    • プラスとマイナスの無限大 - 「すべて1」の指数とゼロの仮数フィールドを使用して表されます。
    • 非数(NaN) - 「すべて1」指数とゼロ以外の仮数を使用して表されます。
    • 非正規化数 - 最小正規数よりも小さい数。ゼロ指数フィールドとゼロでない仮数を使用して表されます。これらの数字の特別なことは、仮数部に余裕がないため、値が小さくなるほど精度(つまり、値の桁数に含まれる可能性がある)が低下することです。

    最後に、以下の具体例(すべての値はヘクス内にある)の一握りである:

    • 1.0:3f800000
    • -1234.0:c49a4000
    • 100000000000000000000000.0:65a96816
    6

    基本的に、scientific notationは2進数です。正式な規格(詳細はIEEE 754)です。

    +5

    +1ですが、Wikiは正式な標準ではありません。それは正式な標準の説明にすぎません:-): – xanatos

    +4

    そしてCはIEEE浮動小数点を必要としません。 –

    3
    typedef struct { 
         unsigned int mantissa_low:32;  
         unsigned int mantissa_high:20; 
         unsigned int exponent:11;   
         unsigned int sign:1; 
        } tDoubleStruct; 
    
    double a = 1.2; 
    tDoubleStruct* b = reinterpret_cast<tDoubleStruct*>(&a); 
    

    コンパイラが今日のほとんどのシステムでCダブルのデフォルトであるIEEE 754倍精度を使用する場合のメモリの設定例です。

    ここではCベースのバイナリ形式であり、それを理解するには wikipedia about double precisionをよく読んでください。

    +1

    それは1つの可能性ですが、唯一の可能性はありません。 –

    2

    さまざまな浮動小数点形式があります。それらの大部分は、符号ビット、指数を格納するための専用のビット、および仮数を格納する専用ビット(仮数とも呼ばれます)を共有します。

    IEEE浮動小数点規格は、さまざまなシステムで実装可能な単一のフォーマット(またはいくつかのサイズのフォーマットのセット)を定義しようとします。また、利用可能な操作とそのセマンティクスも定義します。これはかなりうまくいきます。遭遇する可能性が高いシステムのほとんどは、おそらくIEEE浮動小数点を使用しています。しかし、まだ完成していないIEEE実装と同様、他のフォーマットも使用されています。 C規格では、(IEEEの場合はのオプション)がサポートされていますが、必須ではありません。

    1

    仮数は、数値の最上位ビットを表します。

    指数は、実際の数値を取得するために仮数部で何回シフトを実行するかを表します。

    符号化では、仮数部の符号と指数部の符号(基本的には左または右にシフトするかどうか)を指定します。

    参照先のドキュメントでは、最も広く使用されているIEEEエンコードを指定しています。

    1

    私はあなたが参照した記事がかなり判読不能であることを発見しました(そして、IEEEの浮動小数点の仕組みを少しは知っています)。私は説明のWiki版で試してみることをお勧めします。それはかなり明確だとさまざまな例があります。

    http://en.wikipedia.org/wiki/Single_precision

    0

    これは実装定義ですが、IEEE-754が最も一般的です。

    は、IEEE-754が使用されていることを確認するには:

    Cで
    • は、あなたがにリンクされたドキュメントではなく、明らかにそれを説明するstd::numeric_limits<float>::is_iec559定数
    関連する問題