2

私はこのコードを持っています

#include <stdio.h>
#include <math.h>

static double const x = 665857;
static double const y = 470832;

int main(){
    double z = x*x*x*x -y*y*y*y*4 - y*y*4;
    printf("%f \n",z);
    return 0;
}

これの本当の解決策は方程式が 1 です。以前の質問で私自身が既に答えたように、このコードは壊滅的なキャンセルのために失敗します。しかし、今、私はさらに奇妙なことを発見しました。長いロングを使用すると機能しますが、私の知る限り、それらはダブルよりも範囲が狭くなります。なんで?

4

3 に答える 3

4

long longは よりも範囲が狭くなりますが、精度は高くなりdoubleます。

しかし、それはここで働いていることではありません。あなたの計算は実際には の範囲も超えていlong longますが、システムでの整数オーバーフローの処理方法が原因で、正しい結果が得られません。(符号付き整数のオーバーフローの動作は、C 標準によって固定されていませんが、「通常」はここに示すように動作することに注意してください)。

代わりに中間結果x*x*x*xを見ると、 double を使用して計算すると、適切な値になることがわかります。正確ではありませんが、丸みがあり、ほとんどの目的には十分です。ただし、 で計算すると、long longオーバーフローのために、最初は完全にばかげているように見える数値が見つかります。

于 2012-05-11T16:39:32.867 に答える
1

double には、仮数と指数のビットがあります。大きな double の場合、2 つの double 間の距離 (同じ指数、仮数に 1 を追加) は 1 よりもはるかに大きくなります。したがって、無限 + 1 = 無限と同じ状況になります。

long long はオーバーフローし、モジュロ 2 を計算するため、1 になるはずの結果が実際には 1 になる可能性があります。

于 2012-05-11T16:46:38.060 に答える
0

浮動小数点型のオーバーフローは、言語と環境に応じて、未定義またはエラーと見なされます。整数型のオーバーフローは単純にラップ アラウンドします (正しい結果が得られる場合もあれば、そうでない場合もあります)。

于 2012-05-11T16:39:29.363 に答える