c - 无穷大和非数字的可移植检查

标签 c c++98

我正在寻找不使用关于浮点类型实现的假设,也不使用 C++11/C99 方法的东西。

以下代码是否是检查 INF 和 NAN 的可靠方法?如果不是,究竟会出现什么问题?

bool isfinite(double n)
{
    if(std::numeric_limits<double>::has_infinity)
    {
        double inf = std::numeric_limits<double>::infinity();
        if(std::memcmp(&n, &inf, sizeof(double)) == 0)
            return false;

        double neginf = -inf;
        if(std::memcmp(&n, &neginf, sizeof(double)) == 0)
            return false;
    }

    if(std::numeric_limits<double>::has_quiet_NaN)
    {
        double nan = std::numeric_limits<double>::quiet_NaN();
        if(std::memcmp(&n, &nan, sizeof(double)) == 0)
            return false;

        double negnan = -nan;
        if(std::memcmp(&n, &negnan, sizeof(double)) == 0)
            return false;
    }

    return true;
}

编辑:具体来说,我正在寻找一种在语言中实现这一目标的方法,而不是依赖于编译器内部函数、先验定义或其他库,例如 boost

最佳答案

Confident OP 的代码并不总是有效。

double(例如 IEEE 754)有一个非唯一的 NaN 二进制表示:
(s 是符号位。)

s1111111 1111baaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa

不是所有的baa ... aaa都是0。(如果baa ... aaa全是0,那么就是INF .) 安静 NaN 和信号 NaN 之间的区别通常用 b 的值表示。

突出的问题是并非所有 NaN 都具有相同的位模式。针对单个位模式针对 double 提出的测试不足以检测 NaN。

建议改为不依赖于 NaN 或给定 C 平台中存在的 Infinity 的可移植测试。

double x;

// NAN are never arithmetically equal, even to themselves.
if (x != x) NaN_Detected();
if (x > DBL_MAX || x < -DBL_MAX) Inf_Detected();

[编辑] 比较修复:感谢@Jongware

关于c - 无穷大和非数字的可移植检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23092615/

相关文章:

c++ - c++98 中的 move() 是什么?

c++ - 检测usb设备的API

c - C 的文件 I/O 函数

c++ - 段错误(核心转储)- 具有多维 vector 的循环 C++98

c++ - 在队列中存储一组字符?

c++ - 涉及 CRTP 和内部类型的类特化

c++ - boost::functions 类型的空实现

MySql 客户端的凭据数据包

Codeblocks vs GCC 不同的输出(奇怪的行为)?

C 数组元素初始化