[英]Why 2147483648 + 2147483648 = 0 in C?
Here's the code:这是代码:
int a;
a = 2147483648 + 2147483648;
printf("%d", a);
I know that maximum number of int variable is 2147483647. So, as I know, 2147483648 = -2147483648.我知道 int 变量的最大数量是 2147483647。所以,据我所知,2147483648 = -2147483648。 But why 2147483648 + 2147483648 = 0?但为什么 2147483648 + 2147483648 = 0?
2147483648 is 1 followed by 31 zeroes. 2147483648 是 1 后跟 31 个零。 If you add it twice, it simply overflows (all 32 bits will be zero and carry will be set).如果您添加两次,它只会溢出(所有 32 位都将为零,并且将设置进位)。 Since carry is basically discarded (ignored, when you store the value into a), you don't see it, all you see are 0s.由于进位基本上被丢弃(忽略,当你将值存储到a中时),你看不到它,你看到的都是0。
10000000 00000000 00000000 00000000 +10000000 00000000 00000000 00000000 ------------------------------------ (1)00000000 00000000 00000000 00000000
Because your constants do not fit in an int
they are treated as a long
(or, if necessary, long long
, so:因为您的常量不适合int
它们被视为long
(或者,如有必要, long long
,所以:
2147483648 = 0x80000000
+ another 0x80000000
= 0x100000000
, which when you assign it to a
is truncated to 0 (assuming 4 byte int
s.) 2147483648 = 0x80000000
+ another 0x80000000
= 0x100000000
,当你将它分配给a
时,它被截断为 0(假设 4 字节int
s。)
gcc issues a warning for the assignment. gcc 对分配发出警告。
Second one of these today.今天第二个。
The behaviour of this code depends on:此代码的行为取决于:
The code could output any number or raise a signal but this must be covered in the compiler's documentation.该代码可以 output 任何数字或引发信号,但这必须包含在编译器的文档中。
There are two places in which the code relies on implementation-defined behaviour: the result of the addition, and then the operation of storing the result of the addition into an int
variable.代码有两个地方依赖于实现定义的行为:加法的结果,以及将加法的结果存储到int
变量中的操作。
Also I would like to point out that C arithmetic is based on values , not representations.另外我想指出,C 算术是基于值,而不是表示。 The answer does NOT depend on 2's complement or binary carries or anything like that.答案不取决于 2 的补码或二进制进位或类似的东西。 2147483648
is always a large positive integer, it is not a negative number. 2147483648
始终是一个大的正数 integer,它不是负数。 Adding two positive numbers cannot produce a negative number either.两个正数相加也不能产生负数。 This is commonly misunderstood.这通常被误解。
Here are some example cases:以下是一些示例案例:
long
is 32 bits, 2147483648
has type either unsigned int
or unsigned long
.在long
为 32 位的 C90 实现中, 2147483648
的类型为unsigned int
或unsigned long
。 According to the definition of unsigned arithmetic the result is the mathematical value of 2147483648 + 2147483648 modulo 2^32 which works out to 0
.根据无符号算术的定义,结果是 2147483648 + 2147483648 模 2^32 的数学值,结果为0
。int
is 32-bit and long
is 64-bit, 2147483648
has type long
.在int
为 32 位且long
为 64 位的实现中, 2147483648
的类型为long
。 Then the result of the addition has type long
and value 4294967296
.然后加法的结果具有类型long
和值4294967296
。 Then, assigning this value to an int
is an out-of-range assignment causing implementation-defined behaviour.然后,将此值分配给int
是超出范围的分配,导致实现定义的行为。 One common way that implementations define this is truncating higher bits.实现定义这一点的一种常见方式是截断高位。 Raising a signal is another option.发出信号是另一种选择。long
and 64-bit long long
then the case is quite similar to the previous bullet except the type is long long
.在具有 32 位long
和 64 位long long
的普通 C99 实现中,情况与前面的项目符号非常相似,只是类型为long long
。long
where the addition then causes undefined behaviour due to overflow, but we generally don't worry about that and assume nobody would ever design such a system.可能有一些 33 位long
的深奥系统,其中加法然后由于溢出导致未定义的行为,但我们通常不担心这一点,并假设没有人会设计这样的系统。 (There are systems with 36-bit integers though!) (虽然有些系统具有 36 位整数!)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.