簡體   English   中英

右移浮點數的二進制表示形式-0.0

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM