问题描述
下面我有一个简单的程序:
I have below a simple program:
#include <stdio.h>
#define INT32_MIN (-0x80000000)
int main(void)
{
long long bal = 0;
if(bal < INT32_MIN )
{
printf("Failed!!!");
}
else
{
printf("Success!!!");
}
return 0;
}
状况如果(BAL&LT; INT32_MIN)
总是正确的。这怎么可能?
The condition if(bal < INT32_MIN )
is always true. How is it possible?
如果我改变宏它工作正常:
It works fine if I change the macro to:
#define INT32_MIN (-2147483648L)
任何人都可以指出问题?
Can anyone point out the issue?
推荐答案
这是相当微妙的。
在你的程序文字的每个整数都有一个类型。哪种类型已经由表6.4.4.1调节:
Every integer literal in your program has a type. Which type it has is regulated by a table in 6.4.4.1:
Suffix Decimal Constant Octal or Hexadecimal Constant
none int int
long int unsigned int
long long int long int
unsigned long int
long long int
unsigned long long int
如果文字数量不能符合预设 INT
类型里面,它会在上表所示尝试下一个较大的类型。所以定期十进制整数它是这样:
If a literal number can't fit inside the default int
type, it will attempt the next larger type as indicated in the above table. So for regular decimal integer literals it goes like:
- 尝试
INT
- 如果它不适合,尝试
长
- 如果它不适合,尝试
长长
。
- Try
int
- If it can't fit, try
long
- If it can't fit, try
long long
.
的六角文字表现不同,但!的如果文字无法容纳一个符号类型如 INT
里面,它会首先尝试 unsigned int类型
移动到想要更大的类型了。看到在上表中的差。
Hex literals behave differently though! If the literal can't fit inside a signed type like int
, it will first try unsigned int
before moving on to trying larger types. See the difference in the above table.
所以,在32位系统上,你的文字为0x80000000
的类型为 unsigned int类型
。
So on a 32 bit system, your literal 0x80000000
is of type unsigned int
.
这意味着你可以将一元 -
的字面运营商,而不必调用实现定义的行为,因为你否则将溢出有符号整数时。相反,你将获得值为0x80000000
,正值。
This means that you can apply the unary -
operator on the literal without invoking implementation-defined behavior, as you otherwise would when overflowing a signed integer. Instead, you will get the value 0x80000000
, a positive value.
BAL&LT; INT32_MIN
调用通常的算术转换和前pression结果 -0x80000000
是促进unsigned int类型
到长长
。该值为0x80000000
是preserved和0小于为0x80000000,因此结果。
bal < INT32_MIN
invokes the usual arithmetic conversions and the result of the expression -0x80000000
is promoted from unsigned int
to long long
. The value 0x80000000
is preserved and 0 is less than 0x80000000, hence the result.
当您使用 2147483648L
您使用十进制格式,因此编译器不挑替换文字 unsigned int类型
,而是试图适应它长
里面。还以L结尾说,你想有一个长
的如果可能的话的。以L结尾其实有类似的规则,如果你继续读提到的表6.4.4.1:如果号码不适合里面的要求长
,它不在32位的情况下,编译器会给你一个长长
它适合就好。
When you replace the literal with 2147483648L
you use decimal notation and therefore the compiler doesn't pick unsigned int
, but rather tries to fit it inside a long
. Also the L suffix says that you want a long
if possible. The L suffix actually has similar rules if you continue to read the mentioned table in 6.4.4.1: if the number doesn't fit inside the requested long
, which it doesn't in the 32 bit case, the compiler will give you a long long
where it will fit just fine.
这篇关于为什么是0℃; -0x80000000?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!