为什么INT_MIN和INT_MAX似乎超出int类型的范围?

时间:2013-03-06 11:22:57

标签: c

当我使用INT_MAX和INT_MIN常量时,我​​得到-2147483648 ... 2147483647。

但是当我尝试使用此函数计算整数的最大值和最小值时:

static int computeInt(void)
{
    int myInt = 0;
    int min = 0;
    int max = 32;

    for (int i = min; i < max; i++)
    {
        myInt = myInt + pow(2, i);
    }

    myInt = myInt / 2;

    return myInt;
}

我没有得到相同的号码。我认为发生的事情的技术是myInt溢出。

谢谢!

4 个答案:

答案 0 :(得分:5)

是的,你有一个溢出因为int的范围是从-2 ^ 31到2 ^ 31 - 1而你试图计算从0到31的2的幂之和。你的最终值是以下结果: (2^0 + 2^1 + 2^3 + ... + 2^31) / 2明显大于2 ^ 31 - 1

答案 1 :(得分:2)

你的假设是对的。您的int溢出,因为您不断添加它。当max int只是2 ^ 31-1或pow(2,31)-1时,我不确定你为什么要使用循环。

使用循环你可以做到:

for (int i = min; i < max; i++) {
    myInt = myInt * 2;
}
myInt = myInt - 1;

(注意,此循环也会导致临时溢出。在最后一次迭代后myInt将为-2147483648,但减去一次将导致2147483647

答案 2 :(得分:2)

以这种方式通过算术可靠地检测到最大有符号整数是不可能的,因为只要整数超过INT_MAX,结果就是未定义的(它可能会崩溃)。

然而,您可以计算出最大的无符号整数,因为这可以保证回绕到0,即UINT_MAX + 1保证为0。同样,unsigned int a = -1将等于UINT_MAX

由于签名的intunsigned int保证使用相同数量的存储空间和对齐方式,因此您可以将计算出的UINT_MAX除以2以获得INT_MAX。因此:

unsigned int maxint = -1;
maxint /= 2;

答案 3 :(得分:1)

如前面的答案和评论所述,你有一个溢出(即使假设sizeof(int) = 4。 如果你想“手动”计算这些常量,你可以这样做:

int myInt = (((unsigned int)(-1)) >> 1);
int myIntMin = -myInt - 1;

这不是trully架构独立的,因为它假设有符号整数用2的补码逻辑表示,并且整数表示中没有填充位。但在许多情况下,这应该可以正常工作(在x86 pc上测试)。