2015-10-14 37 views
1

我在學習c,並且感到困惑,因爲我的代碼似乎認爲(1e16-1> = 1e16)應該是false。我的代碼如下,它返回c中的不等式不起作用

9999999999999999 INVALIDBIG\n 

當我希望它不會返回任何東西。我認爲使用long long可以避免大數量的問題。

int main(void) 
{ 
    long long z; 

    z = 9999999999999999; 

    if (z >= 1e16 || z < 0) 
    { 
     printf("%lli INVALIDBIG\n",z); 
    } 
} 
+0

無法重現。試試'1e16LL'。更新:實際上指數符號返回的是浮點類型,所以你不能附加整數後綴。你最好使用整數常量 –

+0

@EugeneSh。 「浮動」還是「雙」? –

+0

@SouravGhosh浮點數。確切的類型在這裏並不重要,我相信.. –

回答

3

1E16是雙型文字值,並浮/雙打可以是不精確的十進制算術/比較(只是許多常見的例子之一:小數0.2)。它會將長長的z向上加倍以便進行比較,並且我猜測標準雙重表示不能存儲所需的精度(也許其他人可以演示二進制尾數/符號表示)

嘗試將1e16更改爲(長雙)1e16,則不會打印出您的消息。 (更新:或者,如其他問題評論者所述,將1e16更改爲整數文字)

1

雙打和浮點數可以保存有限的數字位數。在你的情況下,值爲99999999999999991e16的雙數字具有相同的8字節的十六進制表示。您可以逐字節地檢查它們:

long long z = 9999999999999999; 
double dz1 = z; 
double dz2 = 1e16; 

/* prints 0 */ 
printf("memcmp: %d\n", memcmp(&dz1, &dz2, sizeof(double))); 

因此,它們是平等的。

較小的整數可以以完美的精度雙倍存儲。例如,參見Double-precision floating-point formatbiggest integer that can be stored in a double

可以轉換到加倍恰好是2 (9007199254740992)的最大整數。