我正在寻找不使用关于浮点类型实现的假设,也不使用 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/