我有一个读取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作为答案但是当输入小数字时会返回正确的答案?
编辑:第一个问题回答。既然我知道我有溢出问题,我该如何解决呢?
答案 0 :(得分:5)
来自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.
所以看起来像你的第一个案例。
答案 1 :(得分: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))
答案 2 :(得分:2)
问题不在pow
。表达式
num1 * num2 * num3 * num4 * num5
本身就是罪魁祸首。如果您在调试器中查看结果值,您可能会看到一些无意义的否定值。这就是pow
失败的原因。如果第一个参数为负且第二个参数不是整数,则如果失败并出现域错误。
85,43,95,100和78的产品不适合您平台上int
的范围。它溢出并导致未定义的行为。这就是你观察到的。
将该表达式的值评估为
(double) num1 * num2 * num3 * num4 * num5
并且您的pow
应该会给出更有意义的结果。
答案 3 :(得分:1)
你正在溢出双人可以存储的东西。数字太大会导致您输入的双打溢出。
此外,您可以根据此处文档中所述的错误期间发生的某些事件来检查这些问题: http://en.cppreference.com/w/cpp/numeric/math/pow
为了清晰起见编辑:pow()在输入时采用double,所以当你将所有这些ints相乘时,当结果被强制转换为double时,可能会导致溢出。此外,数学本身可能导致溢出。