2012-02-18 61 views
1

任何人都可以向我解釋爲什麼這段代碼打印「錯誤」?這隻出現在整數的最小值上。溢出C代碼

int abs(int x) { 
    int result = 0; 
    if(x < 0) 
     result = -1*x; 
    else 
     result = x; 

    return result; 
} 

int main() { 

    printf("Testing abs... "); 
    if (abs(-2147483648) != 2147483648) 
     printf("error\n"); 
    else 
     printf("success\n"); 
} 
+0

你試圖'INT A = -2147483648; int b = 2147483648; printf(「%d%d」,a,b);'? – 2012-02-18 00:29:25

回答

7

因爲對於一個32位整數整數簽署,使用two's complement,你可以存儲最多爲2147483647

範圍是-2147483648 2147483647

你一定要小心 - 溢出簽名的數字是未定義的行爲。

0

32位整數的最大值是2,147,483,647。

0

把long代替int。對於更大的整數,你需要很長的時間。谷歌的這種類型提供的範圍。同樣爲了與靜態數字進行比較,你必須聲明它像8438328L

+2

在32位Linux,32位OS X或任何Windows版本中使用'long'都無濟於事。 – 2012-02-18 00:38:21

0

由於整數表示方式(2's complement),如果您的int是32位,-2147483648是它自己的負數。

-2147483648abs()返回後,可能會將其作爲long,64位整數進行比較。如果比較是32位,則2147483648將等於-2147483648。也許如果你打開你的編譯器的所有警告,它會抱怨?

0

的32位帶符號整數的範圍是,如前-2147483648(= -2 )爲2147483647(= 2 - 1)已經提及。在你的abs()函數中,你已經溢出了一個有符號的整數,這是未定義的行爲(引用要插入的標準)。因此,任何事情都可能發生,但實際發生的事情很可能是結果只是迴繞,再次產生-2147483648。但是,您比較,爲整數文字2147483648,它不適合一個32位有符號整數,因此,因爲它沒有(N)的符號性後綴,即文字在列表

  1. 下一個類型int
  2. long int
  3. long long int

其可以表示它的值(如果有的話)。在可能是long intlong long int的64位系統上,前者在Linux上是典型情況,後者就我所知,在Windows上,在32位系統上,幾乎可以肯定是long long int

然後int值-2147483648被提升爲long (long) int和測試條件是

if (-2147483648L != 2147483648L) // or LL