返回

c++-无法使用机器的 epsilon 使用 std::fetestexcept() 检查双精度/浮点操作的溢出

发布时间:2022-08-07 17:51:48 284
# golang

在编写一些数学时,我遇到了以下极端情况问题,我想使用std::fetestexcept检测并通过抛出异常来发出信号:

#include 
#include 
#include 
#include 
#include 
#include 

static bool constexpr has_iec60559_math = []() {
    return static_cast(math_errhandling & MATH_ERREXCEPT)
           && static_cast(math_errhandling & MATH_ERRNO);
}();

static_assert(has_iec60559_math,
              "Target must support floating-point exceptions and errno to report errors");

template
void failure_check() 
{
    static T constexpr lhs = std::numeric_limits::max();
    static T constexpr rhs = std::numeric_limits::epsilon();  

    {
        std::feclearexcept(FE_ALL_EXCEPT); 
        // add
        try {
            auto const r = lhs + rhs;
            
            int const fp_exception_raised = std::fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT);
            if (fp_exception_raised) {
                std::feclearexcept(FE_ALL_EXCEPT);
                auto const ec = std::error_code(errno, std::generic_category());
                throw std::system_error(ec);
            }
            std::cout << r << '\n';
        }
        catch(std::exception const& e) {
            std::cerr << "caught: " << e.what() << '\n';
        }
    }
    {
        std::feclearexcept(FE_ALL_EXCEPT); 
        // mul        
        try {
            T const r = lhs *(T{1} + rhs);
            
            int const fp_exception_raised = std::fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT);
            if (fp_exception_raised) {
                std::feclearexcept(FE_ALL_EXCEPT);
                auto const ec = std::error_code(errno, std::generic_category());
                throw std::system_error(ec);
            }  
            std::cout << r << '\n';
        }
        catch(std::exception const& e) {
            std::cerr << "caught: " << e.what() << '\n';
        }
    }
}

int main() {
    failure_check();
    failure_check();
}

但我得到了coliru不是预期的结果:

3.40282e+38

caught: Success

1.79769e+308

caught: Success

我希望这两种浮点类型都会溢出,因为FLT_MAX + FLT_EPS > FLT_MAX和FLT_MAX * (1.0 + FLT_MAX ) > FLT_MAX. 不是吗?也许我没有正确理解浮点实用程序fetestexcept?我怎样才能得到预期的行为?

请注意,我对支持现代 x86 架构特别感兴趣,可能是 Apple 的 M1。

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(2)
按点赞数排序
用户头像
下一篇
vb.net-Visual Studio vb:无法完成操作 2022-08-07 15:30:56