boost:math:factorial2 在计算 -1 的双阶乘时抛出错误?
boost:math:factorial2 throws an error while computing double factorial of -1?
C++中boost库的官方文档确认-1!!被定义为。但是,当我尝试计算 -1 的双阶乘时,它会抛出以下错误
“函数错误 boost::math::tgamma gamma 结果太大而无法表示”。我可以实现一个基于迭代的代码来计算相同的(如果涉及到),但我想尽可能使用优化的库。对纠正这个问题有什么建议吗?
#include <iostream>
#include <boost/math/special_functions/factorials.hpp>
int main(int argc, char const *argv[]) {
double t = boost::math::double_factorial<double>(-1);
std::cout << t <<"\n";
return 0;
}
这是最小的工作示例。
函数是declared as
template <class T>
T double_factorial(unsigned i);
和unsigned(-1)
是一个非常大的数字。
这就是 boost::math::double_factorial
declared:
namespace boost{ namespace math{
template <class T>
T double_factorial(unsigned i);
template <class T, class Policy>
T double_factorial(unsigned i, const Policy&);
}} // namespaces
根据documentation为boost::math::double_factorial
The argument to double_factorial is type unsigned even though
technically -1!! is defined.
这意味着,虽然数学上 -1!!定义明确,函数不支持负输入。
事实上,-1 将是 silently converted 到 unsigned
,这将导致很大的数字——因此溢出。
作为解决方法,您可以在 namespace boost::math
中声明一个额外的 double_factorial
函数
例如,为了简单起见,我只允许 -1!!
#include <iostream>
#include <exception>
#include <boost/math/special_functions/factorials.hpp>
namespace boost { namespace math {
template <class T>
T double_factorial(int i) { if (i == -1) return T{1}; else throw(std::runtime_error("Unknown double factorial")); }
} }
int main(int argc, char const *argv[]) {
double t = boost::math::double_factorial<double>(-1);
std::cout << t <<"\n";
return 0;
}
警告
此解决方案可行,因为当您使用否定参数调用 double_factorial
时,编译器将在同一命名空间内选择您的新重载。
然而,它有潜在的危险:如果 boost
的未来版本允许负值,代码可能无法再编译,或者忽略新的提升版本。
更好的解决方案是将 double_gamma
环绕到您定义的函数中,如下所示
template <class T>
T my_double_factorial(int i) {
if (i > 0)
return boost::math::double_factorial<T>(i);
else if (i == -1)
return T{1};
else
throw(std::runtime_error("Unknown double factorial"));
}
C++中boost库的官方文档确认-1!!被定义为。但是,当我尝试计算 -1 的双阶乘时,它会抛出以下错误 “函数错误 boost::math::tgamma gamma 结果太大而无法表示”。我可以实现一个基于迭代的代码来计算相同的(如果涉及到),但我想尽可能使用优化的库。对纠正这个问题有什么建议吗?
#include <iostream>
#include <boost/math/special_functions/factorials.hpp>
int main(int argc, char const *argv[]) {
double t = boost::math::double_factorial<double>(-1);
std::cout << t <<"\n";
return 0;
}
这是最小的工作示例。
函数是declared as
template <class T>
T double_factorial(unsigned i);
和unsigned(-1)
是一个非常大的数字。
这就是 boost::math::double_factorial
declared:
namespace boost{ namespace math{
template <class T>
T double_factorial(unsigned i);
template <class T, class Policy>
T double_factorial(unsigned i, const Policy&);
}} // namespaces
根据documentation为boost::math::double_factorial
The argument to double_factorial is type unsigned even though technically -1!! is defined.
这意味着,虽然数学上 -1!!定义明确,函数不支持负输入。
事实上,-1 将是 silently converted 到 unsigned
,这将导致很大的数字——因此溢出。
作为解决方法,您可以在 namespace boost::math
double_factorial
函数
例如,为了简单起见,我只允许 -1!!
#include <iostream>
#include <exception>
#include <boost/math/special_functions/factorials.hpp>
namespace boost { namespace math {
template <class T>
T double_factorial(int i) { if (i == -1) return T{1}; else throw(std::runtime_error("Unknown double factorial")); }
} }
int main(int argc, char const *argv[]) {
double t = boost::math::double_factorial<double>(-1);
std::cout << t <<"\n";
return 0;
}
警告
此解决方案可行,因为当您使用否定参数调用 double_factorial
时,编译器将在同一命名空间内选择您的新重载。
然而,它有潜在的危险:如果 boost
的未来版本允许负值,代码可能无法再编译,或者忽略新的提升版本。
更好的解决方案是将 double_gamma
环绕到您定义的函数中,如下所示
template <class T>
T my_double_factorial(int i) {
if (i > 0)
return boost::math::double_factorial<T>(i);
else if (i == -1)
return T{1};
else
throw(std::runtime_error("Unknown double factorial"));
}