在最新的Boost中,有一个计算伯努利数的函数,但我完全错过它的作用。
例如,Mathematica
,Python mpmath
和www.bernoulli.org
说:
BernoulliB[1] == -1/2
但是提升版
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/math/special_functions/bernoulli.hpp>
boost::multiprecision::cpp_dec_float_100 x = bernoulli_b2n<boost::multiprecision::cpp_dec_float_100>(1);
返回0.166667
为什么会出现这种差异?我错过了什么吗?
答案 0 :(得分:4)
所有奇数Bernoulli numbers都是零,除了B1,你知道的是 - 1/2
。所以,
boost::math::bernoulli_b2n
返回唯一的偶数(2n
)伯努利数。
例如,要获得B4
,您需要实际传递2
:
std::cout
<< std::setprecision(std::numeric_limits<double>::digits10)
<< boost::math::bernoulli_b2n<double>(2) << std::endl;
如果您通过1
,则会获得B2
。
当然,您可以制作一个简单的包装器,模仿首选语法 1 :
double bernoulli(int n)
{
if (n == 1) return -1.0 / 2.0; // one
if (n % 2) return 0; // odd
return boost::math::bernoulli_b2n<double>(n / 2);
}
int main()
{
std::cout << std::setprecision(std::numeric_limits<double>::digits10);
for (int i = 0; i < 10; ++i)
{
std::cout << "B" << i << "\t" << bernoulli(i) << "\n";
}
}
甚至是一个超载operator[]
的课程(对于要求苛刻的人;)):
class Bernoulli
{
public:
double operator[](int n)
{
return bernoulli(n);
}
};
甚至可以使用模板魔法并在编译时进行所有这些检查(我将其留作读者的练习;))。
1 请注意,这个确切的函数体未经过充分验证,可能包含错误。但我希望你已经知道如何制作包装器。