3

メモリに格納されているよりも高い精度で浮動小数点数を印刷する場合、余分な場所にはゼロが含まれているはずではありませんか?私はこのようなコードを持っています:

double z[2*N]="0";
...
for( n=1; n<=2*N; n++) {
  fprintf( u1, "%.25g", z[n-1]);
  fputc( n<2*N ? ',' : '\n', u1);
}

これは次のような出力を作成しています:

0,0.7071067811865474617150085,....

浮動小数点数は小数点以下17桁のみである必要があります(そうですか?53ビットは小数点以下17桁になりません)。もしそうなら、18、19...25位はゼロを持つ必要があります。上記の出力で、0以外の数字が含まれていることに注意してください。

私は何かを誤解していますか?もしそうなら、何ですか?

4

4 に答える 4

7

いいえ、53ビットは、小数点以下17桁が信頼できることを意味しますが、使用する基数10の表記は、doubleが格納される基数(2進数)とは異なるため、後の桁は1/2^であるためです。 53は正確には1/10^nではありません。つまり、

1/2 ^ 53 = .0000000000000001110223024625156540423631668090820312500000000

于 2012-12-07T09:29:38.270 に答える
4

実装によって出力された文字列は、例の double の正確な値を示しています。これは、以下に示すように、C 標準で許可されています。

まず、浮動小数点オブジェクトが何を表しているかを理解する必要があります。C 標準ではこれが不十分ですが、実装で IEEE 754 浮動小数点標準が使用されていると仮定すると、通常の浮動小数点オブジェクトは、符号ビットに対して(-1) s •2 e •(1+f) を正確に表します。 s (0 または 1)、指数 e (特定の型の範囲内、double の場合は -1022 から 1023)、および小数 f (これも範囲内、double の基数ポイントの 52 ビット後)。多くの人がオブジェクトを使用して近くの値を概算しますが、標準によれば、オブジェクトは定義された 1 つの値のみを表します。

表示する値 0.7071067811865474617150085 は、double (符号ビット 0、指数 -1、小数ビット [16 進数] .6a09e667f3bcc 16 ) として正確に表現できます。この値を持つ double が正確にその値を表していることを理解することが重要です。0.707106781186547461715 などの近くの値を表していません。

に渡される値がわかったのでfprintf、C 標準がこれについて何と言っているかを検討できます。まず、C 標準では、DECIMAL_DIG という名前の定数が定義されています。C 2011 5.2.4.2.2 11 は、これを 10 進数の桁数として定義し、サポートされている最も広い型の浮動小数点数を、値を変更せずにその数の 10 進数の桁数に丸め、元に戻すことができるようにします。に渡した精度fprintf25 は、システムの DECIMAL_DIG の値よりも大きい可能性があります。

C 2011 7.21.6.1 13 では、標準で次のように規定されています。それ以外の場合、ソース値は 2 つの隣接する 10 進文字列 L < U によって制限され、両方とも DECIMAL_DIG 有効桁数を持ちます。結果の 10 進文字列 D の値は、L ≤ D ≤ U を満たす必要があり、エラーには現在の丸め方向の正しい符号が必要であるという特別な規定があります。」</p>

この言い回しは、コンパイラに多少の余地を与えます。その意図は、エラーなしで元の double に変換できるように、結果が十分に正確でなければならないということです。より正確な場合があり、一部の C 実装では正確に正しい値が生成されますが、これは上記の段落を満たしているため許可されています。

ちなみに、表示される値は sqrt(2)/2 に最も近い double ではありません。その値は +0x1.6A09E667F3BCDp-1 = 0.70710678118654757273731092936941422522068023681640625 です。

于 2012-12-07T12:24:52.720 に答える
0

倍精度浮動小数点で表現する0.7071067811865474617150085のに十分な精度があります。64 ビット出力は、実際には3FE6A09E667F3BCC です。

53数値の評価に使用される式は累乗であるため、ビットが17小数点以下の桁数になるとは言えません。

編集:別のインスタンスについては、wiki記事の以下の例を見てください:

 0.333333333333333314829616256247390992939472198486328125
=2^(−54) × 15 5555 5555 5555 base16
=2^(−2) × (15 5555 5555 5555 base16 × 2^(−52) )
于 2012-12-07T09:31:56.877 に答える
0

float を求めていますが、コードでは double と表示されます。

とにかく、float も double も常に同じ小数点以下の桁数はありません。Float は、IEEE 754 に従って、浮動小数点表現に 32 ビット (4 バイト) を割り当てました。

ウィキペディアから:

フロート表現

IEEE 754 標準では、binary32 が次のように指定されています。

  • 符号ビット: 1 ビット
  • 指数幅: 8 ビット
  • 有効桁数の精度: 24 (明示的に格納された 23)

これにより、10 進数の有効桁数が 6 ~ 9 桁になります (10 進数の有効桁数が最大 6 桁の 10 進文字列が IEEE 754 単精度に変換され、次に同じ有効桁数に変換された場合、最終的な文字列は元の文字列と一致する必要があります。また、 IEEE 754 の単精度が 9 桁以上の有効桁数を持つ 10 進文字列に変換されてから単精度に戻される場合、最終的な数値は元の数値と一致する必要があります)。

二重の場合、ウィキペディアから再び:

二重表現

倍精度 2 進浮動小数点は、パフォーマンスと帯域幅のコストにもかかわらず、単精度浮動小数点よりも範囲が広いため、PC で一般的に使用される形式です。単精度浮動小数点形式と同様に、同じサイズの整数形式と比較すると、整数の精度が不足しています。一般的には単にダブルとして知られています。IEEE 754 標準では、binary64 は次のように指定されています。

  • 符号ビット: 1 ビット
  • 指数幅: 11 ビット
  • 有効桁数の精度: 53 ビット (明示的に格納された 52 ビット)

これにより、15 桁から 17 桁の有効桁数の精度が得られます。10 進数の有効桁数が最大 15 の 10 進文字列を IEEE 754 倍精度に変換してから、同じ桁数の有効桁数に戻す場合、最終的な文字列は元の文字列と一致する必要があります。また、IEEE 754 倍精度が 10 進数の有効桁数が 17 以上の 10 進数文字列に変換されてから倍精度に戻される場合、最終的な数値は元の数値と一致する必要があります。

一方、float があり、実際に格納されている精度よりも高い精度で出力すると、残りの桁が 0 で埋められるとは期待できません。コンパイラは、実行しようとしているトリックを想像できません。

于 2012-12-07T09:48:24.737 に答える