我正在寻找一些不使用有关浮点类型实现的假设的东西,并且不使用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 。
答案 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