2015-08-22 123 views
3

程序將生成階乘數,直到它發生溢出。表達式r <= UINT_MAX/j用於檢測溢出。現在,如果我將表達式重寫爲r * j <= UINT_MAX,它將進入無限循環。我的問題不是關於如何檢測整數溢出。這就是表達式讓流程進入無限循環的原因。帶有無符號整數溢出檢測的表達式

for (unsigned i = 0;;++i) { 
    unsigned r = 1; 
    for (unsigned j = 2; j <= i; ++j) { 
     if (r <= UINT_MAX/j) 
      r *= j; 
     else { 
      printf("Overflow!\n"); 
     } 
    } 
} 
+0

表達式'r * j'也是一個無符號整數。所以它永遠不會比'UINT_MAX'大。 – wimh

+0

可能重複的[在整數加法溢出測試](http://stackoverflow.com/questions/3422709/test-for-overflow-in-integer-addition) – wimh

+2

可能重複[如何檢測整數溢出在C/C++?](http://stackoverflow.com/questions/199333/how-to-detect-integer-overflow-in-cc) –

回答

3

無符號整數類型有算術其最大值加1
你的情況,我們有算術模(UINT_MAX+1)

因此,操作r*j總是給出結果<= UINT_MAX,並且比較始終爲真。

然而,當r抵抗UINT_MAX/j相比,真實(數學)算術與無符號類型的算術重合,因爲UINT_MAX/j在數學上是在unsigned的範圍內。
這解釋了爲什麼在C代碼中,條件將與數學比較完全相同。

因此,r <= UINT_MAX/j方法是正確的。

相關問題