c++ - C++ 中的 native isnan 检查

标签 c++

我偶然发现这段代码来检查 NaN:

/**
 * isnan(val) returns true if val is nan.
 * We cannot rely on std::isnan or x!=x, because GCC may wrongly optimize it
 * away when compiling with -ffast-math (default in RASR).
 * This function basically does 3 things:
 *  - ignore the sign (first bit is dropped with <<1)
 *  - interpret val as an unsigned integer (union)
 *  - compares val to the nan-bitmask (ones in the exponent, non-zero significand)
 **/
template<typename T>
inline bool isnan(T val) {
    if (sizeof(val) == 4) {
        union { f32 f; u32 x; } u = { (f32)val };
        return (u.x << 1) > 0xff000000u;
    } else if (sizeof(val) == 8) {
        union { f64 f; u64 x; } u = { (f64)val };
        return (u.x << 1) > 0x7ff0000000000000u;
    } else {
        std::cerr << "isnan is not implemented for sizeof(datatype)=="
              << sizeof(val) << std::endl;
    }
}

这看起来依赖于架构,对吧?但是,我不确定字节序,因为无论是小字节序还是大字节序,float 和 int 可能以相同的顺序存储。

另外,我想知道是不是像

volatile T x = val;
return std::isnan(x);

本来可以的。

这在过去与 GCC 4.6 一起使用。

最佳答案

Also, I wonder whether something like std::isnan((volatile)x) would have worked.

isnan 按值获取其参数,因此 volatile 限定符将被丢弃。换句话说,不,这行不通。

您发布的代码依赖于特定的浮点表示法 (IEEE)。它还表现出未定义的行为,因为它依赖于 union hack 来检索底层的 float 表示。

关于代码审查的注释,即使我们忽略上一段的潜在问题(这是有道理的),该函数还是写得很糟糕:为什么该函数使用运行时检查而不是编译时检查和编译时错误处理?如果只提供两个重载会更好更容易。

关于c++ - C++ 中的 native isnan 检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22907923/

相关文章:

c++ - 如何积累模板参数包?

c++ - C++ 数组大小的奇怪行为

c++ - 遍历所有驱动器?

c++ - C++ 中的结构偏移量和指针安全

c++ - Windows EVENTLOGRECORD 结构中的可变长度字段如何工作?

c++ - Lambda 捕获 C++14

c++ - 在 Windows 中对二进制文件进行逆向工程的最佳做法是什么?

c++ - 如何修复程序中 ';' 错误之前丢失的 '*'?

C++ DirectX FPS 相机怪异

c++ - C++11 中的构造