Как уже говорилось другими, промежуточные результаты, которые вы получите для больших k
, слишком велики, чтобы вписаться в двойную.От определенного k
до pow
, а также factorial
будет возвращаться бесконечность.Это просто то, что происходит для очень больших двойников.И когда вы затем делите одну бесконечность на другую, вы получаете NaN.
Один из распространенных приемов для обработки слишком больших чисел - использование логарифмов для промежуточных результатов и только в конце примените экспоненциальную функцию один раз.Некоторое математическое знание логарифмов требуется здесь.Чтобы понять, что я здесь делаю, вам нужно знать exp(log(x)) == x
, log(a^b) == b*log(a)
и log(a/b) == log(a) - log(b)
.
. В вашем случае вы можете переписать
pow(4, 2*k+1)
на
exp((2*k+1)*log(4))
Тогда еще есть факториал.Функция lgamma может помочь с factorial(n) == gamma(n+1)
и log(factorial(n)) == lgamma(n+1)
.Короче говоря, lgamma дает вам журнал факториала без огромных промежуточных результатов.
Подводя итог, замените
pow(4, 2*k+1) / factorial(2*k+1)
на
exp((2*k+1)*log(4) - lgamma(2*k+2))
Это должно помочь вамс вашими NaNs.Кроме того, это должно повысить производительность, поскольку lgamma
работает в O(1)
, тогда как ваш factorial
находится в O(k)
.
Обратите внимание, однако, что я все еще очень мало уверен в том, что ваш результат будет численно точным.Точность двойного кода по-прежнему ограничена примерно 16 десятичными цифрами.Ваши 100000 итераций, скорее всего, бесполезны, возможно, даже вредны.