为什么pow函数给我nan作为答案

Why does the pow function give me nan as an answer?

本文关键字:答案 nan pow 函数 为什么      更新时间:2023-10-16

我有一个程序,它可以读取 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 作为答案,但在输入小数字时返回正确答案?

编辑:回答第一个问题。现在我知道我遇到了溢出问题,我该如何解决它?

pow(x,y) 的手册页:

   If x is a finite value less than 0, and y is a finite noninteger, 
a domain error occurs, and a NaN is returned. 
   Except as specified below, if x or y is a NaN, the result is a NaN.
   If x is negative, then large negative or positive y values yield a NaN 
as the function result, with  errno  set  to  EDOM,  and  an  invalid
   (FE_INVALID)  floating-point  exception.  For example, with pow(), 
one sees this behavior when the absolute value of y is greater than about
   9.223373e18.

所以看起来像你案例中的第一种情况。

要(可能)避免溢出,请重写为

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)) 

问题不在于pow。表达式

num1 * num2 * num3 * num4 * num5

本身就是罪魁祸首。如果您在调试器中查看结果值,您可能会看到一些无意义的值。这就是pow失败的原因。如果失败并显示域错误,则第一个参数为负数,第二个参数不是整数。

85、43、95、100 和 78 的乘积不符合您平台上的int范围。它溢出并导致未定义的行为。这就是你观察到的。

将该表达式的值计算为

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

你的pow应该给出更有意义的结果。

你溢出了双倍可以存储的东西。 数字太大,导致您输入的双精度值溢出。

此外,您还可以根据错误期间发生的一些事件检查这些问题,如以下文档中所述:http://en.cppreference.com/w/cpp/numeric/math/pow

为清楚起见进行了编辑:pow() 采用双精度作为输入,因此当您将所有这些整数相乘时,当结果类型转换为双精度时可能会导致溢出。 此外,数学本身也可能导致溢出。