2013-01-12 31 views
0

我寫了這個簡單的代碼來生成所有正整數的第四次方,最大值爲1005.它只能工作到215的整數。然後它給出了錯誤的讀數。爲什麼這樣?C代碼只能運行到某個點

# include<stdio.h> 

int main(void) 
{ 
    int i; 
    unsigned long long int j; 

    for (i = 1; i <= 1005; i++){ 
     j = i*i*i*i; 
     printf("%i.........%llu\n",i,j); 

    } 

    return 0; 

} 

回答

6

你可以通過這個小小的改變fix it

unsigned long long i; 

的問題是,在線路j = i*i*i*i;,右手側被計算爲int它被分配給j之前。由於這個原因,如果i^4超過整數限制,它將基本上開始第一個負數,並在高位被截斷時開始循環。當負號分配給j,因爲j無符號-i變得max - i,這哪裏是龐大的數字從何而來。您還需要將printf格式說明符從%i更改爲%llu,對於i

您還可以通過執行以下

j = (unsigned long long)i*i*i*i; 

解決這個問題基本上,這會強制執行乘法之前鑄造的高達j類型。

完整性檢查 - 215 ^4 = 2136750625這非常接近signed int的上限2,147,483,647。

+0

在printf的指定器應改變以匹配新的I型。 –

+0

@EricPostpischil似乎沒有必要,因爲我從來沒有超過整數限制,正如你可以從我的LWS鏈接看到的,我不確定這是否是由於系統特定的內存結構。 –

+0

如果參數不是轉換規範的正確類型,行爲不是由C標準定義的,根據C 2011 7.21.6.1 9.超出數字限制是無關緊要的。考慮到在某些平臺上,一個32位'int'可以在寄存器中傳遞,而64位'unsigned long long'在堆棧上傳遞。當參數實際位於堆棧上時,這將使'printf'使用「%i」的任何位,即使該值在範圍內。參數類型**必須**符合轉換規範。 –

4

i*i產生inti*i*ii*i*i*i也是如此。 215是最大的正整數,其4次冪適合32位int

除此之外,結果通常會被截斷(通常是因爲嚴格來說,您遇到了未定義行爲;有符號整數溢出導致UB按照C標準)。

你可能想投iunsigned long long或者將其定義爲unsigned long long,所以乘法是64位:

j = (unsigned long long)i*i*i*i;