2012-01-09 19 views
7

doubleを出力するとき、または文字列をdoubleに変換するときの精度について、Cのルールを理解できない。次のプログラムは、私のポイントを説明する必要があります。Cの文字列をdoubleに変換するときの奇妙な動作

#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; 
} 

を私はコンパイル時に取得し、(GCC 4.5.2とCore 2 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は非ゼロの数字として印刷されますか?私は、コンパイラが計算の目的で倍精度をより高精度の型に昇格させることがあることを知っていますが、xを64ビットのdoubleとして扱うべきではありませんか?
  2. Cライブラリが密接に拡張精度浮動小数点数を使用している場合、これらの小数を変換するときにstrtodがerrnoを設定するのはなぜですか?とにかく正しい結果が得られるのはなぜですか?
  3. この動作は、特定のハードウェアおよび開発環境の結果であるバグですか? (残念ながら、現時点で他のプラットフォームではテストできません)

ありがとうございました。私はフィードバックを得る際に問題を明確にしようとします。そのためIEEE-754規格のdenormal numbersの存在の

+0

:: 'DBL_MIN = 2.225074e-308'はあまり意味がありませんフロートの解析 ""

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

は(このページは明示的にはglibc strtodページにリンクされていることに注意してください"最小IEEE DP値が '4.94066e-324'であるので、' 100'での割り切りが正しく動作する理由を説明しますが、なぜ 'DBL_MIN'が' 4.94066e-324'でないのかがわかります。 – Mysticial

+0

以下に明示されています:DBL_MINは最小の_normalised_値 –

答えて

8
  1. DBL_MINは、の正規化の最小値です。

  2. 標準がそう言うので

    (C99 7.20.1.3):

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

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

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

+1

ありがとう、これは非常に参考になる情報ですが、この場合はstrtodでエラーを報告しないことを願っていますが、それを回避するだけです。 –

7

標準はstrtodアンダーフロー(C99、7.20.1.3p10)

「結果がアンダーフロー(7.12.1)場合、関数は大きさよりも大きくない値を返すために言っていることです戻り値の型で最小の正規化された正の数; errnoが値ERANGEを取得するかどうかは実装定義です。 strtodアンダーフロー上のERANGEについて

は、ここではglibcがアンダーフローが発生すると

」、errnoをERANGEに設定することができる。返されたアンダーフロー例外が発生し、ゼロは(適切に署名した)言っていることですが、これではありません保証される。 1の場合http://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_node/Parsing-of-Floats.html

関連する問題