我正在寻找一些不使用有关浮点类型实现的假设的东西,并且不使用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; }
解决方法
自信OP的代码并不总是有效.
双精度(例如IEEE 754)具有非唯一的NaN二进制表示形式:
(s是符号位.)
s1111111 1111baaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa
并非所有baa … aaa都是0.(如果baa … aaa全部为0,那么它就是INF.)静态NaN和信号NaN之间的差异通常用b的值表示.
突出的问题是并非所有NaN都具有相同的位模式.针对单个位模式提出的双重测试是对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