2016-12-13 30 views
0

私はcodechef質問をやろうとした - https://www.codechef.com/problems/FLOW009なぜ浮動小数点型の浮動小数点型は、正常に動作しないのですか?

ここで、私のコード(正常に送信)これです -

int main(void) { 

    int testCases; 

    scanf ("%d\n", &testCases); 
    while (testCases--) { 

     float q,p; 
     scanf ("%f%f", &q,&p); 

     if (q >= 1000){ 

      printf("%.6f\n",q*p - (q*p*0.1)); 
     } 
     else{ 
      printf("%.6f\n", q*p); 
     } 

    } 

    return 0; 
} 

これが正常に送信...しかし、私はこのコードを試してみましたがときました -

int main(void) { 

    int testCases; 

    scanf ("%d\n", &testCases); 
    while (testCases--) { 

     float q,p; 
     scanf ("%f%f", &q,&p); 

     if (q >= 1000){ 
      float a = q*p - (q*p*0.1); 
      printf("%.6f\n",a); 
     } 
     else{ 
      printf("%.6f\n", q*p); 
     } 

    } 

    return 0; 
} 

これは間違った答えです。私のコンパイラでは、結果はすべてのテストケースで同じです。何が起こっている。最初のコード - 私はちょうど値を印刷しています。 2番目に - 私は値を格納する変数を使用しています。

PS - 値をタイプキャストしようとしましたが、結果はありませんでした。

+0

簡単な答えは、 "0.1"は2進浮動小数点で正確に表現できないということです。おそらく、2つのコードは、内部で精度を高く保つように最適化されていました。 (小数点以下の桁数に似て、 "3 x 1/3"は1を返すかもしれませんが、変数に1/3を格納すると、 "0.3333333"に丸められ、3を乗算すると1と等しくなりません)。 –

+2

問題の説明のコーディングでは、すべての入力が整数である必要があります。これは、計算でも整数を使用する必要があることを示唆しています。 – Peter

+0

注: '0.1'の型は' double'です。 – pmg

答えて

1

doubleからfloatに値を変換して戻っても、同じ結果が保証されるわけではありません。

printf("%.6f\n", q*p - (q*p*0.1)); 

の値が全て double型に変換され、計算は doubleで行われます。タイプ doubleの結果は、 printfに直接送信されます。

変数がfloatの場合、値はdoubleに変換され、計算はdoubleで行われ、代入のためにfloatに変換されます。その値はdoubleに変換されてからprintfに渡されます。

浮動小数点変数には常にdoubleを使用してください。

+0

ありがとうございました。 :) –

関連する問題