2015-08-22 67 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方法是正确的。

相关问题