2013-09-17 3 views
2

У меня есть программа, которая читает в 5 целых чисел и выдает результаты различных вычислений с использованием этих чисел. У меня возникают особые трудности при вычислении среднего геометрического значения. Я знаю, что вы должны умножить числа вместе и взять n-й корень из результата.Почему функция pow дает мне nan как ответ?

мой код выглядит следующим образом (предполагается, что все и директивы #includes основного метода являются правильными.):

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, но когда Я ввожу большие числа, это дает мне нан как ответ.

Числа мне нужно работать в этом являются: 85, 43, 95, 100 и 78

Моего вопроса: Почему военнопленные() функция дает мне нана в ответ, когда большие значения вставлять, но возвращать правильные ответы при вводе небольших чисел?

EDIT: Первый вопрос ответил. Теперь, когда я знаю, что у меня проблемы с переполнением, как мне его решить?

+5

Цифры в вашем примере вызывают неопределенное поведение, потому что они переполняют 'int'. – chris

+0

Не могли бы вы найти, что 'errno' содержит сразу после строки, вызывающей' pow' i.e перед 'cout'? Вы должны иметь возможность печатать его просто. –

+1

Интересно, если выборка не была выбрана намеренно, чтобы выделить эту потенциальную проблему? –

ответ

1

Вы переполняете то, что может хранить двойной. Числа слишком велики и вызывают удвоение, которое вы вводите для переполнения.

Кроме того, вы можете проверить эти вопросы, основываясь на некоторых событиях, которые происходят во время ошибок, как описано в документации здесь: http://en.cppreference.com/w/cpp/numeric/math/pow

отредактированный для ясности: Pow() принимает два раза, как это вход, так что, когда вам умножьте все эти int вместе, вы можете вызвать переполнение, когда результат будет выглядеть с двойным. Кроме того, сама математика может вызвать переполнение.

+0

Вы, вероятно, имеете в виду '' int'', а не '' double''? Трудно переливать вдвое. '' 85 * 43 * 95 * 100 * 78'' находится между '' 2^31'' и '' 2^32'', что приводит к отрицательному '' int'' (который затем преобразуется в '' double '' перед тем, как перейти к '' pow'', но это не помогает, так как это уже отрицательно). – fjarri

+0

Я говорил в общих чертах, но есть потенциал для передачи столь значительных значений, что они генерируют исключение, прежде чем pow() даже начнет выполнять экспоненциальное вычисление AFAIK. –

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. 

Так выглядит первый случай в вашем случае.

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

Проблема не в pow. Выражение

num1 * num2 * num3 * num4 * num5 

является виновником сам по себе. Если вы посмотрите на полученное значение в отладчике, вы, вероятно, увидите какое-то бессмысленное значение минус. Это то, что делает ошибку pow. Если с ошибкой домена возникает ошибка, если первый аргумент отрицательный, а второй аргумент не является целым числом.

Изделие 85, 43, 95, 100 и 78 не входит в диапазон int на вашей платформе. Он переполняется и ведет к неопределенному поведению. Это то, что вы наблюдаете.

Вычислить значение этого выражения как

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

и ваш pow должен дать более значимый результат.

Смежные вопросы