int a = int.MaxValue;
int b = int.MaxValue;
int c = a + b;
为什么c=-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 = 0
? int.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,如果你玩一下。
如何处理整数溢出?
(long)int.MaxValue + (long)int.MaxValue
。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