C语言定义INT_MIN和INTMAX如下:
#define INT_MAX 2147483647
#define INT_MIN (-INT_MAX - 1)
为什么不直接定义INT_MIN为-2147483648呢?
如果你运行如下代码:
if (-2147483648 > 0) printf(“TRUE”); else printf(“FALSE”);
你可能会发现令你意想不到的结果。这是为什么呢?
因为-2147483648不是一个数字,而是一个表达式:一个正值2147483648,前面有个操作符 - 。2147483648超过了int范围的最大正值。如果编译平台的long int类型比int的范围更大,编译器会自动假设2147483648是long int。这会使-2147483648是long int类型,它是一个负数,小于0。但是如果long int和int的范围一样,或者说编译平台没有其他int类型的范围比int大,这意味着2147483648超过了int的范围,导致程序的行为是未定义的。
实际上由于程序的行为是未定义的,2147483648可能被编译器解释为负数,前面的负号使得-2147483648大于0。
为什么定义INT_MIN为(-INT_MAX - 1)能解决问题呢?
-INT_MAX(即-2147483647)的十六进制为0x8001,(-INT_MAX - 1)正好是0x8000,即-2147483648。
下面是相关的一段程序:
/* * Description: * INT_MIN related curiosities. */ #include <stdio.h> #include <limits.h> #include <stdlib.h> #define btoa(x) ((x) ? "TRUE" : "FALSE") int main() { int a = -2147483648; int b = 2147483648; printf("-2147483647 > 0 is %s\n", btoa(-2147483647 > 0)); // FALSE printf("-2147483648 > 0 is %s\n", btoa(-2147483648 > 0)); // Undefined: may TRUE printf("INT_MIN-1 > 0 is %s\n", btoa(INT_MIN-1 > 0)); // TRUE: 0x8000-1=0x7999(INT_MAX)>0 printf("2147483647 > 0 is %s\n", btoa(2147483647 > 0)); // TRUE printf("2147483648 > 0 is %s\n", btoa(2147483648 > 0)); // Undefined: may FALSE printf("INT_MAX+1 > 0 is %s\n", btoa(INT_MAX+1 > 0)); // FALSE: 0x7999+1=0x8000(INT_MIN)<0 printf("int(-2147483648) > 0 is %s\n", btoa(a > 0)); // Undefined: printf("int(2147483648) > 0 is %s\n", btoa(b > 0)); // Undefined: printf("-2147483648L > 0 is %s\n", btoa(-2147483648L > 0)); // if LONG_INT_MAX > INT_MAX: FALSE; else Undefined. printf("-2147483648LL > 0 is %s\n", btoa(-2147483648LL > 0)); // FALSE printf("abs(INT_MIN) is %d\n", abs(INT_MIN)); }
在不同平台的运行结果如下:
OS X 10.10 Yosemite(x86-64):
-2147483647 > 0 is FALSE
-2147483648 > 0 is FALSE
INT_MIN-1 > 0 is TRUE
2147483647 > 0 is TRUE
2147483648 > 0 is TRUE
INT_MAX+1 > 0 is FALSE
int(-2147483648) > 0 is FALSE
int(2147483648) > 0 is FALSE
-2147483648L > 0 is FALSE
-2147483648LL > 0 is FALSE
Ubuntu 14.04(x86-64):
-2147483647 > 0 is FALSE
-2147483648 > 0 is FALSE
INT_MIN-1 > 0 is TRUE
2147483647 > 0 is TRUE
2147483648 > 0 is TRUE
INT_MAX+1 > 0 is FALSE
int(-2147483648) > 0 is FALSE
int(2147483648) > 0 is FALSE
-2147483648L > 0 is FALSE
-2147483648LL > 0 is FALSE
abs(INT_MIN) is -2147483648
可以看到现在很多系统已经是64bit,所以(-2147483648 > 0 )也没有出错。
不过值得注意的是,abs(INT_MIN)依然还是-2147483648。这是abs的例外:
If the result cannot be represented by the returned type (such as abs(INT_MIN) in an implementation with two‘s complement signed values), it causes undefined behavior.