NaN
我对 IEEE 单精度和双精度浮点的实现和表示感到好奇,我发现了“is NaN”函数的这种实现。即:
int isnan(double x)
{
int32_t hx,lx;
// Move lower 32 bits of double to lx, higher 32 to hx.
EXTRACT_WORDS(hx,lx,x);
// Remove sign bit, since -NaN and NaN are both NaN.
hx &= 0x7fffffff;
// Equivalent to hx |= (lx != 0).
hx |= (u_int32_t)(lx|(-lx))>>31;
// Difference is negative iff (hx & 0x7ff00000) == 0x7ff00000 and (hx & 0x000fffff) != 0.
hx = 0x7ff00000 - hx;
return (int)((u_int32_t)(hx))>>31;
}
我不明白 的目的(lx|(-lx)) >> 31
,并且在我的头脑中没有推理出来之后,我对所有整数进行了测试,发现结果为 0 ,lx = 0
否则为 1。
我能想出的唯一原因是,(lx != 0)
由于某些 C 标准没有定义为真操作分配什么整数值(例如,不保证为真时为 1),或者可能!=
比负数慢,所以可能无法使用代替 -或位移位。否则,我难住了。
作为参考,我用来尝试所有整数的代码,以防出错。
#include <stdio.h>
#include <stdint.h>
int main(void) {
int32_t i = 0;
do {
if (((uint32_t)(i | (-i)) >> 31) == 0)
printf("%d\n", i); // prints only 0
} while (i++ != 0xFFFFFFFF); // overflows to -max_int and then climb to -1
return 0;
}