7

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

私の質問は次のとおりです。

  1. xがゼロ以外の数値として出力されるのはなぜですか?コンパイラが計算の目的でdoubleをより高精度の型にプロモートすることがあることは知っていますが、printfはxを64ビットのdoubleとして扱うべきではありませんか?
  2. Cライブラリが拡張精度の浮動小数点数を密かに使用している場合、これらの小さな数を変換しようとすると、strtodがerrnoを設定するのはなぜですか?そして、なぜそれはとにかく正しい結果を生み出すのですか?
  3. この動作は単なるバグであり、特定のハードウェアと開発環境の結果ですか?(残念ながら、現時点では他のプラットフォームでテストすることはできません。)

あなたが与えることができるどんな助けにも感謝します。フィードバックがありましたら、問題を明確にしようと思います。

4

2 に答える 2

8
  1. IEEE-754標準 に非正規化数が存在するため。DBL_MIN最小の正規化された値です。

  2. 標準がそう言っているので(C99 7.20.1.3):

    結果がアンダーフロー(7.12.1)の場合、関数は、戻り型の最小の正規化された正の数以下の大きさの値を返します。errnoがERANGEの値を取得するかどうかは、実装によって定義されます。

    「正しい」値(つまり1e-310)を返すことは、上記の制約に従います。

  3. バグではありません。C標準では非正規化数(AFAIK)の存在や動作に要件がないため、これは技術的にプラットフォームに依存します。

于 2012-01-09T20:23:46.693 に答える
7

strtodアンダーフロー(C99、7.20.1.3p10)についての標準の記述は次のとおりです。

「結果がアンダーフロー(7.12.1)の場合、関数は、戻り型の正規化された最小の正の数以下の大きさの値を返します。errnoが値ERANGEを取得するかどうかは、実装によって定義されます。」

アンダーフローに関してERANGEstrtod、glibcの説明は次のとおりです。

「アンダーフローが発生すると、アンダーフロー例外が発生し、ゼロ(適切に署名された)が返されます。errnoはERANGEに設定される場合がありますが、これは保証されません。」

http://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_node/Math-Error-Reporting.html

(このページは、glibcstrtodページ「Parsingof Floats」に明示的にリンクされていることに注意してください: http ://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_node/Parsing-of-Floats.html

于 2012-01-09T20:24:49.413 に答える