简体   繁体   English

为什么 C 中的 2147483648 + 2147483648 = 0?

[英]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:此代码的行为取决于:

  • which version of C you are using您使用的是哪个版本的 C
  • what the sizes of types are on your compiler (implementation-defined)编译器上的类型大小是多少(实现定义的)
  • perhaps other implementation-defined features也许其他实现定义的功能

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:以下是一些示例案例:

  • In a C90 implementation where long is 32 bits, 2147483648 has type either unsigned int or unsigned long .long为 32 位的 C90 实现中, 2147483648的类型为unsigned intunsigned 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
  • On an implementation where 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.发出信号是另一种选择。
  • On a normal C99 implementation with 32-bit 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
  • There could be some esoteric system with a 33-bit 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 位整数!)
  • Non-conforming compilers such as MSVC could of course do something different.不符合标准的编译器(例如 MSVC)当然可以做一些不同的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM