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 であることが保証されていない)、またはおそらく!=
負の値よりも遅いことです。 or-and-bit-shift。そうでなければ、私は困惑しています。
参考までに、エラーが発生した場合に備えて、すべての整数を試すために使用したコード。
#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;
}