2017-08-12 66 views
9
void main() { 
    int i; 
    if (i < 0) { i = -i; }; 
} 

任何人都可以幫助我理解爲什麼在上面的程序中可能發生溢出嗎?爲什麼在下面的程序中會發生溢出?

+4

未定義的行爲。該變量未被初始化。並且否定最負的可能整數在二進制補碼運算中產生相同的值 –

+1

在2的補碼中, INT_MIN | > INT_MAX – BLUEPIXY

+1

當'i == INT_MIN'以2的補碼錶示時。 –

回答

13

可能會發生溢出,因爲二進制補碼中整數表示的範圍不對稱:可以表示的最小負數的幅度是可以表示的最大正數的幅度加1。例如,在32位系統上,值爲-2,147,483,6482,147,483,647。這就是爲什麼否定-2,147,483,648會導致溢出的原因:否定的結果爲正值2,147,483,648,不能用相同大小的int表示。

請注意此問題的逆是不正確的:否定一個正數不會導致溢出:

if (i > 0) { i = -i; } // No overflow here 
+2

@Tom請注意,MSVC在'limits.h'中有'#define INT_MIN(-2147483647 - 1)'。 –

+0

明白...非常感謝 – Tom

1

的原因整數溢出是在運算試圖創建一個數值即在可以用給定位數表示的範圍之外,或者大於最大值或者小於最小可表示值。

  • 那麼,在你的情況下,變量i未初始化。所以在這裏會發生什麼是分配給變量i整數類型的內存空間將包含一些垃圾值。
  • 如果內存地址包含最大可能的整數值-2^31(-2,147,483,648),那麼否定此值將導致整數溢出。

我希望這有助於。

1

當main啓動時,您的堆棧中的「i」值是未定義的。調用main()之前運行的啓動代碼可以在那裏留下任何東西。

Addig對Kashif說什麼,負整數可以比非負整數低一個數值,因爲負數不需要留下零空間。當符號反轉時,符號位中的「1」(所有剩餘位爲零)會導致溢出。

在16位:-0x8000 ==〜爲0x8000 + 1 == 0x7FFF的+ 1 ==爲0x8000
// 「 - 」 負值==反相+ 1 ==反轉+ 1 ==最終是相同的

該值的可能性很低,但存在。它不會發生,除非堆棧恰好包含違規號碼。

相關問題