出于某种原因,boost 1.78 和 1.79 之间的行为发生了变化,导致现在 cpp_int
convert_to<double>
转换为非常大的数字抛出异常。有时是 overflow_error,有时是 domain_error。
我还没有发现它是否是有意的改变,但现在作为快速的第一步,我只想对此做出反应并保留我们代码的旧行为,它为这些数字提供了无穷大,
std::numeric_limits<double>::max
。
但是我很难捕捉到异常。我怎样才能抓住
boost::wrapexcept<std::overflow_error>
的实例?是否需要一些特殊处理?按照简单的代码 - 请参阅行为比较提升 78 vs 79 here - 没有捕获异常但只是终止
在抛出“boost::wrapexceptstd::overflow_error”实例后调用终止
what(): function float_next(double) 错误:溢出错误
#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
int main() {
std::string strNumber = "179769313486231590617005494896502488139538923424507473845653439431848569886227202866765261632299351819569917639009010788373365912036255753178371299382143631760131695224907130882552454362167933328609537509415576609030163673758148226168953269623548572115351901405836315903312675793605327103910016259918212890625";
boost::multiprecision::cpp_int number(strNumber);
try {
std::cout << number.convert_to<double>() << "\n";
} catch (boost::wrapexcept<std::overflow_error> &e) {
std::cout << "boost exception caught" << "\n";
} catch (...) {
std::cout << "some exception caught" << "\n";
}
std::cout << "finished" << "\n";
}
我期待至少调用“捕获到一些异常”行,但事实并非如此。感谢您的帮助。
不要试图抓住包装纸 - 它是从
std::overflow_error
继承的,这就是你应该去抓住的东西。
还要确保您正在捕获异常
const std::overflow_error&
- 如果您尝试捕获异常作为 const 引用 以外的任何东西,您将遇到一系列意想不到的副作用。也就是说,编译器将不得不为您的异常处理程序copy异常,这可能会因各种原因而失败或导致低效行为。
最后,您仍然遇到的问题是
boost::multiprecision::cpp_int number(strNumber);
行可能已经抛出异常。
为了避免尝试捕获,不要像你那样使用
convert_to
,而不是这样做Boost Multiprecision float,在数字类型之间构造和相互转换:
#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
#include <boost/multiprecision/cpp_dec_float.hpp>
namespace mp = boost::multiprecision;
int main() {
std::string strNumber = "179769313486231590617005494896502488139538923424507473845653439431848569886227202866765261632299351819569917639009010788373365912036255753178371299382143631760131695224907130882552454362167933328609537509415576609030163673758148226168953269623548572115351901405836315903312675793605327103910016259918212890625";
mp::cpp_int number(strNumber);
std::cout << "Boost Multiprecision: "
<< std::setprecision(std::numeric_limits<mp::cpp_dec_float_50>::digits10)
<< number << std::endl;
std::cout << "Double: "
<< std::setprecision(std::numeric_limits<double>::digits10)
<< number << std::endl;
}
输出:
Boost Multiprecision: 179769313486231590617005494896502488139538923424507473845653439431848569886227202866765261632299351819569917639009010788373365912036255753178371299382143631760131695224907130882552454362167933328609537509415576609030163673758148226168953269623548572115351901405836315903312675793605327103910016259918212890625
Double: 179769313486231590617005494896502488139538923424507473845653439431848569886227202866765261632299351819569917639009010788373365912036255753178371299382143631760131695224907130882552454362167933328609537509415576609030163673758148226168953269623548572115351901405836315903312675793605327103910016259918212890625
这样你就不需要try catch了。
或者你可以如何从 boost::multiprecision::cpp_int 转换为 cpp_dec_float<0>:
#include <boost/multiprecision/number.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
namespace mp = boost::multiprecision;
int main() {
using Int = mp::cpp_int;
std::string strNumber = "179769313486231590617005494896502488139538923424507473845653439431848569886227202866765261632299351819569917639009010788373365912036255753178371299382143631760131695224907130882552454362167933328609537509415576609030163673758148226168953269623548572115351901405836315903312675793605327103910016259918212890625";
Int number(strNumber);
using Dec = mp::number<mp::cpp_dec_float<0>>;
std::cout << number.convert_to<Dec>();
}
输出:
1.79769e+308
或者如果你需要 try catch 做下一件事:
#include <boost/multiprecision/number.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
int main() {
std::string strNumber = "179769313486231590617005494896502488139538923424507473845653439431848569886227202866765261632299351819569917639009010788373365912036255753178371299382143631760131695224907130882552454362167933328609537509415576609030163673758148226168953269623548572115351901405836315903312675793605327103910016259918212890625";
boost::multiprecision::cpp_int number(strNumber);
try {
std::cout << number.convert_to<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<0>>>() << "\n";
} catch (boost::wrapexcept<std::overflow_error> const& e) {
std::cout << "boost exception caught" << "\n";
} catch (...) {
std::cout << "some exception caught" << "\n";
}
std::cout << "finished" << "\n";
}
输出:
1.79769e+308
finished