doubleを印刷するとき、または文字列をdoubleに変換するときにどの精度を想定するかについて、Cの規則を理解するのに苦労しています。次のプログラムは私のポイントを説明する必要があります:
#include <errno.h>
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
double x, y;
const char *s = "1e-310";
/* Should print zero */
x = DBL_MIN/100.;
printf("DBL_MIN = %e, x = %e\n", DBL_MIN, x);
/* Trying to read in floating point number smaller than DBL_MIN gives an error */
y = strtod(s, NULL);
if(errno != 0)
printf(" Error converting '%s': %s\n", s, strerror(errno));
printf("y = %e\n", y);
return 0;
}
このプログラムをコンパイルして実行したときに得られる出力(gcc4.5.2のCore2 Duoで)は次のとおりです。
DBL_MIN = 2.225074e-308, x = 2.225074e-310
Error converting '1e-310': Numerical result out of range
y = 1.000000e-310
私の質問は次のとおりです。
- xがゼロ以外の数値として出力されるのはなぜですか?コンパイラが計算の目的でdoubleをより高精度の型にプロモートすることがあることは知っていますが、printfはxを64ビットのdoubleとして扱うべきではありませんか?
- Cライブラリが拡張精度の浮動小数点数を密かに使用している場合、これらの小さな数を変換しようとすると、strtodがerrnoを設定するのはなぜですか?そして、なぜそれはとにかく正しい結果を生み出すのですか?
- この動作は単なるバグであり、特定のハードウェアと開発環境の結果ですか?(残念ながら、現時点では他のプラットフォームでテストすることはできません。)
あなたが与えることができるどんな助けにも感謝します。フィードバックがありましたら、問題を明確にしようと思います。