How to catch boost::wrapeexcept from cpp_int?

问题描述 投票:0回答:2

出于某种原因,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";
}

我期待至少调用“捕获到一些异常”行,但事实并非如此。感谢您的帮助。

c++ exception boost boost-multiprecision
2个回答
0
投票

不要试图抓住包装纸 - 它是从

std::overflow_error
继承的,这就是你应该去抓住的东西。

还要确保您正在捕获异常

const std::overflow_error&
- 如果您尝试捕获异常作为 const 引用 以外的任何东西,您将遇到一系列意想不到的副作用。也就是说,编译器将不得不为您的异常处理程序copy异常,这可能会因各种原因而失败或导致低效行为。

最后,您仍然遇到的问题是

boost::multiprecision::cpp_int number(strNumber);
行可能已经抛出异常。

检查异常规范:https://www.boost.org/doc/libs/1_80_0/libs/multiprecision/doc/html/boost_multiprecision/tut/ints/cpp_int.html


0
投票

为了避免尝试捕获,不要像你那样使用

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
© www.soinside.com 2019 - 2024. All rights reserved.