当我使用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溢出。
谢谢!
答案 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
。
由于签名的int
和unsigned 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上测试)。