Why int.Max+ int.Max = -2
本文关键字:int Max+ Why Max | 更新日期: 2023-09-27 18:12:45
int a = int.MaxValue;
int b = int.MaxValue;
int c = a + b;
为什么总是c=-2
?我也检查了循环。它似乎是垃圾价值,但为什么只有-2
?
让我们用4位整数来玩这个。有符号最大值为0x7
0x7 + 0x7 = 14 = 0xE
0xE
比最大无符号值0xF
小1。解释为有符号的最大unsigned值总是-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#编译器就不会警告你这里发生的所有溢出。
正如你所看到的,如果你稍微摆弄一下,是可以直观地掌握二的补算术的。
如何处理整数溢出?
- 使用一个可以保存结果的类型:
(long)int.MaxValue + (long)int.MaxValue
。 - 或者,至少通知这个可能的错误:
checked(int.MaxValue + int.MaxValue)
.
因为将两个值为MaxValue
的int加在一起并将结果放入int
的结果超出了int
的32位所能容纳的范围。结果是你所看到的:-2是由于产生的位模式和int的高(符号)位现在被设置(称为"换行")。这不是一个随机的"垃圾"值,而是期望的值。
用32位二进制表示:
+=
1111 1111 1111 1111 1111 1111 1111 1110
在Two的补算术中和是-2
更多说明在这里:http://en.wikipedia.org/wiki/Integer_overflow