3

5 つの整数を読み取り、それらの数値を使用してさまざまな計算の結果を出すプログラムがあります。幾何平均の計算に特に問題があります。数値を掛け合わせて、結果の n 乗根を取ることになっていることは承知しています。

私のコードは次のとおりです (すべての #includes と main メソッドが正しいと仮定します):

int num1, num2, num3, num4, num5;

cout << "Enter five integers: \n";
cin >> num1 >> num2 >> num3 >> num4 >> num5;

double gMean = pow((num1 * num2 * num3 * num4 * num5), (1.0/5.0));
cout << "Geometric mean     = " << gMean << endl;

このコードは、1、2、3、4、5 などの小さな数字に対して機能しますが、大きな数字を入力すると、答えとして nan が返されます。

この作業に必要な数字は、85、43、95、100、および 78 です。

私の質問は次のとおりです: pow() 関数は、大きな数値を入力すると答えとして nan を返しますが、小さな数値を入力すると正しい答えを返すのはなぜですか?

編集:最初の質問に答えました。オーバーフローの問題があることがわかったので、どうすれば解決できますか?

4

4 に答える 4

2

問題は ではありませんpow。表現

num1 * num2 * num3 * num4 * num5

それ自体が犯人です。デバッガーで結果の値を見ると、意味のないの値が表示される可能性があります。これがpow失敗の原因です。最初の引数が負で、2 番目の引数が整数でない場合、ドメイン エラーで失敗します。

85、43、95、100、および 78 の積は、intプラットフォームの範囲に収まりません。オーバーフローし、未定義の動作につながります。これはあなたが観察するものです。

その式の値を次のように評価します。

(double) num1 * num2 * num3 * num4 * num5

よりpow意味のある結果が得られるはずです。

于 2013-09-17T05:32:52.147 に答える
2

(おそらく) オーバーフローを回避するには、次のように書き直します。

double gMean = pow(num1, (1.0/5.0)) *
               pow(num2, (1.0/5.0)) *
               pow(num3, (1.0/5.0)) *
               pow(num4, (1.0/5.0)) *
               pow(num5, (1.0/5.0)) 
于 2013-09-17T05:08:27.803 に答える
1

あなたはダブルが保存できるものをあふれさせています。数値が大きすぎるため、入力している double がオーバーフローします。

また、次のドキュメントで説明されているように、エラー中に発生するいくつかのイベントに基づいてこれらの問題を確認できます: http://en.cppreference.com/w/cpp/numeric/math/pow

わかりやすくするために編集: pow() は入力として double を取るため、これらすべての int を乗算すると、結果が double に型キャストされるときにオーバーフローが発生する可能性があります。また、数学自体がオーバーフローを引き起こす可能性があります。

于 2013-09-17T04:57:50.343 に答える