我正在使用 gcc (Ubuntu 13.2.0-23ubuntu4) 13.2.0。
我的代码中有一个错误,其中数值分析函数给出了非常不同的答案。 以下每个都返回 true。 x 是双精度数。
assert (fpclassify(x) == FP_NORMAL);;
assert (x == x);
assert (!(isnan(x)));
assert (isnormal(x));
uint64_t abc = *((long long*)&x) ;
printf("%" PRIx64 "\n", abc);
/* Prints fff8000000000000 */
printf("%f",x);
/* Prints -nan */
uint64_t x4 = 0xfff8000000000000;
assert (x4 == abc);
我从 OCaml 调用 C 代码,因此 OCaml 运行时可能会弄乱这些值。
这可能是编译器错误还是有其他解释?
编辑:这篇文章的先前版本错误地使用了按位否定而不是布尔否定。
~
运算符是按位补码——它翻转值的所有位——不是逻辑非。 因此,将其应用于“布尔”值很少会达到您想要的效果。 例如程序:
#include <stdbool.h>
#include <stdio.h>
int main() {
if (~true) {
printf("~true is true\n");
}
}
将打印
~true is true
每个
issomething
浮点分类宏“当且仅当其参数”位于测试类别中时返回非零值(7.12.3 中的 C 2018 子条款)。所以它不一定产生 0 或 1。它可能产生 2、4 或其他数字。
当您对这些值应用按位求补运算符
~
时,零值将产生非零结果,但 1、2、4 和大多数其他值也将产生非零结果;结果将关闭操作数中打开的位,但打开关闭的位,通常会产生一个非零数字。
对于二进制补码,只有等于
~0
, −1 的值才会产生零结果。
要测试
isnormal
的逆,您可以使用布尔否定:!isnormal(x)
。