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 ?

Why int.Max+ int.Max = -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#编译器就不会警告你这里发生的所有溢出。

正如你所看到的,如果你稍微摆弄一下,可以直观地掌握二的补算术的。


如何处理整数溢出?

  1. 使用一个可以保存结果的类型:(long)int.MaxValue + (long)int.MaxValue
  2. 或者,至少通知这个可能的错误: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