2016-11-17 16 views
0

Я озадачен, оценивая следующую функцию, она производит число до F (0,8, 172, 1), но когда я увеличиваю 172 до 173, результат становится бесконечным. Я подозреваю, что существует проблема с числовой точностью?численная точность в рекурсивных функциях

double F(double d, int c, int t) { 
    // base cases 
    if ((c==1 && t==1) || (c==0 && t==0)) 
     return 1.; 
    if (c==0 || t==0) 
     return 0.; 
    if (t>c) 
     return 0.; 
    return F(d,c-1,t-1) + (c-1 - t*d)*F(d,c-1,t); 
} 
+2

Вы можете объяснить, что это делает? – Mox

+1

Я не думаю, что здесь проблема точности. Причина в том, что double не используется как условие где-либо в этой функции. Возможно, настоящая ошибка где-то еще? – Mox

+2

http://floating-point-gui.de/formats/fp/ Итак, вы на самом деле правы, это проблема с «двойной» численной точностью (в некотором смысле она ограничена во всех отношениях - конечно, вы можете поставить только так много числа в 64 бита). – Ped7g

ответ

2

Я не знаю, что ваша функция должна делать, но учитывая аргументы: F(0.8, 172, 1) возвращаемое значение 4.41861e+306, который чуть меньше максимального значения а double может представлять:

// 1.79769e+308 
std::cout << std::numeric_limits<double>::max() << std::endl; 

Когда 172 заменяется на 173, возвращаемое значение превышает максимальное значение a double может представлять и становится положительной бесконечностью. Это можно сделать, изменив тип возврата F на long double, который приводит к значению 7.56466e+308

+0

demo https://eval.in/679209 он находится в c, но действителен и для C++ также – bansi

+0

@bansi. Пока что номер удалился вправо, и сначала я подумал, что вы указываете ошибку, прежде чем я понял, что «7.56466 e + 308' просто большой, ха-ха. 'std :: cout' дает научную нотацию – asimes

+0

' long double' не обязательно шире, чем 'double' –