[英]right shifting the binary representation of the floating point number -0.0
我正在執行一個程序來檢查雙精度或浮點數字的符號,首先,我將數字的指針轉換為長整型,然后檢查符號位是否為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
由於浮點類型中存在有符號的零,並且存在1的補碼整數類型的可能性,因此很難完全籠統地做到這一點。
除了(int64_t*)&d
的不(int64_t*)&d
(您可以使用union
type-pun來解決)之外,該方法還會為-0.0
返回錯誤的符號。
幸運的是,您可以使用math.h
中的signbit()
,它可能以非便攜式的方式實現了該功能。
首先,定義一個負整數右移。 接下來,由於嚴格的別名規則(對於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);
那么這怎么能進入我的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");
}
這種方法需要具有預期的大小,並且必須使用與int64_t
相同的符號位進行double
編碼。
// Test size
_Static_assert(sizeof(int64_t) == sizeof(double), "Mis-match size");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.