17

double から int への変換をテストするために、次の短いプログラムを作成します。

int main() {
    int a;
    int d; 
    double b = 0.41;

    /* Cast from variable. */
    double c = b * 100.0;
    a = (int)(c);

    /* Cast expression directly. */
    d = (int)(b * 100.0);

    printf("c = %f \n", c);
    printf("a = %d \n", a);
    printf("d = %d \n", d);

    return 0;
}

出力:

c = 41.000000 
a = 41 
d = 40 

と がとの積であるにもかかわらず、aとが異なる値を持つのはなぜですか?db100

4

3 に答える 3

18

C 標準では、C 実装で公称型よりも高い精度で浮動小数点演算を計算できます。たとえば、Intel 80 ビット浮動小数点形式は、ソース コードの型がdoubleIEEE-754 64 ビット形式の場合に使用できます。この場合、動作は、C 実装が可能な限り (80 ビット) を使用し、C 標準で必要な場合にlong double変換すると仮定することで完全に説明できます。double

この場合、次のようになると思います。

  • ではdouble b = 0.41;0.41に変換されdouble、 に格納されbます。変換の結果、.41 よりわずかに小さい値になります。
  • ではdouble c = b * 100.0000;b * 100.0000で評価されlong doubleます。これにより、41 よりわずかに小さい値が生成されます。
  • その式は を初期化するために使用されますcdoubleC 標準では、この時点で変換する必要があります。値が 41 に非常に近いため、変換では正確に 41 が生成されます。41 も同様cです。
  • a = (int)(c);通常どおり 41 を生成します。
  • ではd = (int)(b * 100.000);、前と同じ乗算があります。値は以前と同じで、41 よりわずかに小さい値です。ただし、この値は に代入されたり、初期化に使用されたりしdoubleないため、 への変換はdouble行われません。代わりに、 に変換されintます。この値は 41 よりわずかに小さいため、変換により 40 が生成されます。
于 2013-06-20T18:32:17.070 に答える
1

cコンパイラはで初期化する必要があると推測でき0.41 * 100.0、 の計算よりも優れていますd

于 2013-06-20T18:16:58.553 に答える