2015-04-06 2 views
0

Рассмотрим следующий пример:Оценка и печать факторный

double fact(int n) 
{ 
    int i; 
    double res = 1; 
    for (i = 1; i <= n; i++) 
     res *= i; 

    return res; 
} 

double f = 1; 
for (int i = 0; i < 16; i++) 
{ 
    printf("%lf \n", fact(2*i + 1)); 
    f *= (f + 1)*(f + 2); 
    printf("%lf \n", f); 
} 

Почему fact(2*i+1) приводит правильное значение, а f результатов странное значение в 1.#INF00?

+0

, насколько я могу видеть, 'факт() 'является функцией,' f' является переменной и бессмысленным циклом 'for' в вашем коде. Вы хотите немного разобраться? –

ответ

1

Потому что это переполнение.

Значение f после 16 итераций больше, чем если бы ваш код выглядел, как это и ваш первоначальный f был 2:

f *= f*f; 

Что такое же, как

f = f*f*f 

Так вы берете куб 16 раз - это ОГРОМНОЕ!

2^3 = 8

8^3 = 512

512^3 = 134217728

...

+0

Но даже 'f * = (f + 1)' переполняется. Зачем? – Elimination

+1

По той же причине - взятие квадратов 16 раз ОГРОМНОЕ ... Чего вы пытаетесь достичь. –

+0

То же поведение функции 'fact' – Elimination

1

На тему непредсказуемое поведение, то длина l модификатора в %lf определяется только для спецификаторов преобразования, используя integer. Если вы хотели использовать %Lf, тогда ваш аргумент должен быть long double. Возможно, вы хотели использовать %f, что соответствует аргументу double (float s в конечном итоге повышается до double при передаче их в вариационные функции, такие как printf).

Как объяснил Питер Иванов, ваши расчеты вызывают переполнение, которое IIRC также является неопределенным поведением.

Как вы уже, наверное, догадались, вы можете найти решение вашей проблемы путем использования long double типа (и соответствующий формат %Lf спецификатор) на протяжении всего кода ...

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