Я пытаюсь вычислить число Пи для одного из моих университетских проектов, используя формулу Рамануджана для произвольного числа цифр после плавающей запятой.Для работы я использую библиотеку boost::multiprecision
, которая является просто оберткой вокруг mpfr и mpir, которые я уже установил на свою машину.
Пока все хорошо, но я либо что-то упустил, либо что-то не так, так как мойФункция вычисления (вычисляющая каждую итерацию суммы в формуле) время от времени выдает StackOverflow exception
.(когда он запускается, это согласованно)
Вот так это выглядит
boost::multiprecision::mpf_float calculatePi(int start, int end)
{
boost::multiprecision::mpf_float partition = 0;
for (; start < end; ++start)
{
boost::multiprecision::mpf_float n =
factorial(4 * start) * boost::multiprecision::mpf_float(1103 + 26390 * start);
boost::multiprecision::mpf_float d =
boost::multiprecision::pow(factorial(start), 4) * pow((boost::multiprecision::mpf_float)396, 4 * start); <-- this is where stackoverflow exception is thrown
partition += (n / d);
}
return (2 * boost::multiprecision::sqrt((boost::multiprecision::mpf_float)2) / 9801) * partition;
}
Я признаю, что я слишком зелен в вычислениях / преобразованиях и библиотеках произвольной точности, поэтому я могу что-то упустить.
Я не могу показать вам полный стек вызовов, потому что он слишком длинный, но после
ParallelPi.exe!boost::multiprecision::number<boost::multiprecision::backends::gmp_float<0>,1>::**do_multiplies**<boost::multiprecision::detail::expression<boost::multiprecision::detail::function,boost::multiprecision::detail::number_kind_floating_pointpow_funct<boost::multiprecision::backends::gmp_float<0> >,boost::multiprecision::number<boost::multiprecision::backends::gmp_float<0>,1>,int,void>,boost::multiprecision::detail::function>(const boost::multiprecision::detail::expression<boost::multiprecision::detail::function,boost::multiprecision::detail::number_kind_floating_pointpow_funct<boost::multiprecision::backends::gmp_float<0> >,boost::multiprecision::number<boost::multiprecision::backends::gmp_float<0>,1>,int,void> & e, const boost::multiprecision::detail::function & __formal) Line 1754 C++
Тогда есть 3603 последовательных вызовов на
ParallelPi.exe!boost::multiprecision::number<boost::multiprecision::backends::gmp_float<0>,1>::**operator=**<boost::multiprecision::detail::function,boost::multiprecision::detail::number_kind_floating_pointpow_funct<boost::multiprecision::backends::gmp_float<0> >,boost::multiprecision::number<boost::multiprecision::backends::gmp_float<0>,1>,int,void>(const boost::multiprecision::detail::expression<boost::multiprecision::detail::function,boost::multiprecision::detail::number_kind_floating_pointpow_funct<boost::multiprecision::backends::gmp_float<0> >,boost::multiprecision::number<boost::multiprecision::backends::gmp_float<0>,1>,int,void> & e) Line 216 C++
ParallelPi.exe!boost::multiprecision::number<boost::multiprecision::backends::gmp_float<0>,1>::number<boost::multiprecision::backends::gmp_float<0>,1><boost::multiprecision::detail::function,boost::multiprecision::detail::number_kind_floating_pointpow_funct<boost::multiprecision::backends::gmp_float<0> >,boost::multiprecision::number<boost::multiprecision::backends::gmp_float<0>,1>,int,void>(const boost::multiprecision::detail::expression<boost::multiprecision::detail::function,boost::multiprecision::detail::number_kind_floating_pointpow_funct<boost::multiprecision::backends::gmp_float<0> >,boost::multiprecision::number<boost::multiprecision::backends::gmp_float<0>,1>,int,void> & e, void * __formal) Line 324 C++
только для того, чтобы привести к исключениям stackoverflow несколькими вызовами позже в
ParallelPi.exe!boost::multiprecision::backends::gmp_float<0>::precision() Line 630 C++
Как ни странно, я не помню, чтобы менялась функция calculatePi
до того, как она "заработала".
Не могли бы вы, ребята, помочь мне расшифровать, что происходит, потому что я, кажется, потерян?
Моя точность по умолчанию для boost::multiprecision::mpf_float
составляет 150 цифр после плавающей запятой, которая ранее не была проблемой (я помню, я рассчиталнекоторое число с точностью 10 000 с плавающей запятой без SO или чего-либо еще)
Запросы
1.Код моего факториала
boost::multiprecision::mpf_float factorial(int n)
{
boost::multiprecision::mpf_float fact = 1;
for (int i = 1; i <= n; ++i)
fact *= i;
return fact;
}