为什么int.Max + int.Max = -2

时间:2014-07-13 12:19:37

标签: c# .net

 int a = int.MaxValue;
 int b = int.MaxValue;
 int c = a + b;

为什么c=-2总是?我也检查了循环。它似乎是垃圾价值,但为什么只有-2

2 个答案:

答案 0 :(得分:16)

让我们用4位整数来播放它。最大签名值为0x7

0x7 + 0x7 = 14 = 0xE

0xE比最大无符号值0xF小1。解释为已签名的最大无符号值始终为-1,因为向其添加1会溢出到0(就像(-1) + 1 = 0)。

所以你有(-1) - 1 = -2

进一步注意,对于位级别的有符号和无符号整数,加法的行为方式相同。这就是我被允许在上述陈述中在签名和未签名之间跳转的原因。


这是不同的东西:

int.MaxValue + int.MaxValue = -2
(int.MaxValue + 1) + (int.MaxValue + 1) - 2 = -2
int.MinValue + int.MinValue - 2 = -2
0 - 2 = -2

为什么int.MinValue + int.MinValue = 0int.MinValue仅设置最重要的位。因此,加倍int.MinValue只是将MSB位向左移动并从整数移出。结果是0。像这样:

int.MinValue + int.MinValue = 0
int.MinValue * 2 = 0
int.MinValue << 1 = 0 //int.MinValue is 0x80000000, shift out the left bit

您可以使用LINQPad方便地播放这些表达式。您需要将它们包装在unchecked中,以便C#编译器停止向您发出此处发生的所有溢出的警告。

正如你所看到的那样 可以直观地抓住Two's Complement Arithmetic,如果你玩一下。


如何处理整数溢出?

  1. 使用可以保存结果的类型:(long)int.MaxValue + (long)int.MaxValue
  2. 或者,至少会收到有关此可能错误的通知:checked(int.MaxValue + int.MaxValue)

答案 1 :(得分:6)

因为将值为MaxValue的2个整数加在一起并将结果放入int的结果溢出了int中的32位可以容纳的结果。结果如下所示:-2由于结果位模式和现在设置的int的高(符号)位(称为“环绕”)。它不是一个随机的“垃圾”值,而是可以预期的。

以32位二进制显示:

0111 1111 1111 1111 1111 1111 1111 1111注意符号位 NOT 设置(最大有符号,32位整数)

+

0111 1111 1111 1111 1111 1111 1111 1111注意符号位 NOT 设置(最大有符号,32位整数)

=

1111 1111 1111 1111 1111 1111 1111 1110注意符号位 IS 设置,使其为负数

二进制补码算术中的和为-2

此处有更多解释:http://en.wikipedia.org/wiki/Integer_overflow