便携式检查无限和非数字

时间:2014-04-15 19:23:57

标签: 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

1 个答案:

答案 0 :(得分:3)

自信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