2012-02-18 53 views
1

任何人都可以向我解释为什么这段代码打印“错误”?这只出现在整数的最小值上。溢出C代码

int abs(int x) { 
    int result = 0; 
    if(x < 0) 
     result = -1*x; 
    else 
     result = x; 

    return result; 
} 

int main() { 

    printf("Testing abs... "); 
    if (abs(-2147483648) != 2147483648) 
     printf("error\n"); 
    else 
     printf("success\n"); 
} 
+0

你试图'INT A = -2147483648; int b = 2147483648; printf(“%d%d”,a,b);'? – 2012-02-18 00:29:25

回答

7

因为对于一个32位整数整数签署,使用two's complement,你可以存储最多为2147483647

范围是-2147483648 2147483647

你一定要小心 - 溢出签名的数字是未定义的行为。

0

32位整数的最大值是2,147,483,647。

0

把long代替int。对于更大的整数,你需要很长的时间。谷歌的这种类型提供的范围。同样为了与静态数字进行比较,你必须声明它像8438328L

+2

在32位Linux,32位OS X或任何Windows版本中使用'long'都无济于事。 – 2012-02-18 00:38:21

0

由于整数表示方式(2's complement),如果您的int是32位,-2147483648是它自己的负数。

-2147483648abs()返回后,可能会将其作为long,64位整数进行比较。如果比较是32位,则2147483648将等于-2147483648。也许如果你打开你的编译器的所有警告,它会抱怨?

0

的32位带符号整数的范围是,如前-2147483648(= -2 )为2147483647(= 2 - 1)已经提及。在你的abs()函数中,你已经溢出了一个有符号的整数,这是未定义的行为(引用要插入的标准)。因此,任何事情都可能发生,但实际发生的事情很可能是结果只是回绕,再次产生-2147483648。但是,您比较,为整数文字2147483648,它不适合一个32位有符号整数,因此,因为它没有(N)的符号性后缀,即文字在列表

  1. 下一个类型int
  2. long int
  3. long long int

其可以表示它的值(如果有的话)。在可能是long intlong long int的64位系统上,前者在Linux上是典型情况,后者就我所知,在Windows上,在32位系统上,几乎可以肯定是long long int

然后int值-2147483648被提升为long (long) int和测试条件是

if (-2147483648L != 2147483648L) // or LL