実装によって出力された文字列は、例の 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 進数の桁数に丸め、元に戻すことができるようにします。に渡した精度fprintf
25 は、システムの 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 です。