簡體   English   中英

為什么該函數與float一起正常工作,但對double卻不工作?

[英]Why does the function work with float properly but doesn't work with double?

我找到了檢查浮點數是否為2的冪的代碼:

int isPowOf2(float number) {
    union {
        float   floatRepresent;
        int     intRepresent;
    } bitset;

    bitset.floatRepresent = number;

    if((bitset.intRepresent & ((1 << 23)-1)) != 0)
        return ((bitset.intRepresent & (bitset.intRepresent-1)) == 0); // denormalized number
    int power = bitset.intRepresent >> 23;
    return power > 0 && power < 255;
}

// ...

printf("[%f -> %d] ",2.0,isPowOf2(2.0f)); // [2.000000 -> 1] 
printf("[%f -> %d] ",4.0,isPowOf2(4.0f)); // [4.000000 -> 1]
printf("[%f -> %d] ",0.25,isPowOf2(0.25f)); // [0.250000 -> 1]
printf("[%f -> %d]\n ",11.0,isPowOf2(11.0f)); // [11.000000 -> 0]

正如您在評論中看到的那樣,它可以正常工作。 但是,當我嘗試將此程序轉換為雙倍數版本時,它給出了錯誤的結果:

int isPowOf2(double number) {
    union {
        double      floatRepresent;
        long long   intRepresent;
    } bitset;

    bitset.floatRepresent = number;

    if((bitset.intRepresent & ((1 << 53)-1)) != 0)
        return ((bitset.intRepresent & (bitset.intRepresent-1)) == 0); // denormalized number
    int power = bitset.intRepresent >> 53;
    return power > 0 && power < 2047;
}

// ...

printf("[%f -> %d] ",2.0,isPowOf2(2.0)); // [2.000000 -> 1] 
printf("[%f -> %d] ",4.0,isPowOf2(4.0)); // [4.000000 -> 0]
printf("[%f -> %d] ",0.25,isPowOf2(0.25)); // [0.250000 -> 0]
printf("[%f -> %d]\n ",11.0,isPowOf2(11.0)); // [11.000000 -> 0]

您能解釋什么問題嗎?

失敗的原因是有效位數錯誤。

對於float將存儲23位。

double的情況下,存儲了53個位。

更正了這一點,並添加了LL限定符(如注釋中所述),違規行變為

if((bitset.intRepresent & ((1LL << 52)-1)) != 0) {

並給出與float相同的結果。

代碼正在執行無效的移位。 1是一個int 需要long long @羅ᵩ

union {
  double floatRepresent;
  long long intRepresent;
} bitset;

// if((bitset.intRepresent & ((1 << 53)-1)) != 0)
if((bitset.intRepresent & ((1LL << 53)-1)) != 0)

代碼使用了錯誤的常量。 IEEE 754 binary64 double編碼有效位數為52位。 @njuffa

// if((bitset.intRepresent & ((1 << 53)-1)) != 0)
if((bitset.intRepresent & ((1LL << (53-1))-1)) != 0)

代碼也無法正確使用+ infinity。

// return power > 0 && power < 2047;
return power > 0 && power < 1023;  // Candidate fix for infinity.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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