我正在执行一个程序来检查双精度或浮点数字的符号,首先,我将数字的指针转换为长整数,然后检查符号位是否为0或1。我没有理解为什么使用此操作* pointer >> 63来打印符号位是-1而不是1?(假设* pointer是我将double / float强制转换为的int64_t)
这是完整的代码:
double d = -0.0;
int64_t *pointer = (int64_t *) &d;
if (*pointer >> 63)
printf("negative number\n");
else
printf("positive number\n");
// if i print the result of (*pointer >> 63), it gives me -1
// so how can this go inside my if condition?
通过-0.0的64位二进制打印,我得到了100000000 ... 000
答案 0 :(得分:3)
由于浮点类型中存在带符号的零以及可能存在1的补码整数类型,因此很难完全通用。
除了(int64_t*)&d
的不确定性(您可以使用union
类型双关来解决)之外,该方法还会为-0.0
返回错误的符号。
幸运的是,您可以使用signbit()
中的math.h
,它可能以非便携式的方式实现了该功能。
答案 1 :(得分:0)
首先,定义负整数右移。接下来,由于严格的别名规则(对于Google,您不知道),因此取消引用与实际类型不同的类型的指针显然是未定义的行为。
如果您希望代码具有可移植性,那么唯一安全的方法就是使用memcpy来传输值的表示形式。这仅假设:
sizeof(double)
与sizeof(uint64_t)
相同:uint64_t
的bit63 代码:
double d = -0.0;
uint64_t u;
memcpy(&u, &d, sizeof(u));
print("Sign bit in that architecture %d\n", u>>63);
答案 2 :(得分:0)
那么这如何进入我的if条件中?
1使用signbit(d)
if (signbit(d)) {
puts("Negative");
}
或
2使用复合文字和union
。
// v--------------------------------------------v compound literal
if ((union { double dd; int64_t i64; }){ .dd = d }.i64 < 0) {
puts("Negative");
}
此方法需要具有预期的大小,并且必须使用double
进行编码,且符号位应与int64_t
放在同一位置。
// Test size
_Static_assert(sizeof(int64_t) == sizeof(double), "Mis-match size");