【问题标题】:How unchecked int overflow work c#未经检查的int溢出如何工作c#
【发布时间】:2026-01-15 15:35:01
【问题描述】:

我们知道一个int值的最大值是2^31 - 1,最小值是-2^31。如果我们将 int 设置为最大值:

int x = int.MaxValue;

然后我们把那个 x 加到一个未选中的字段中

unchecked
{
    x++;
}

然后我们得到 x = int 的最小值。我的问题是为什么会发生这种情况以及它是如何以二进制形式发生的。

【问题讨论】:

  • What is “2's Complement”? 的可能重复项
  • @ColeJohnson 直到现在我才知道它被称为 2 的补码。
  • 伙计们不再讨厌我才上 7 年级,并试图学习一些东西。 ._.

标签: c# binary theory


【解决方案1】:

在 C# 中,内置整数由预定义长度的位值序列表示。对于长度为 32 位的基本 int 数据类型。由于 32 位只能表示 4,294,967,296 个不同的可能值(因为是 2^32),

由于 int 可以同时保存正数和负数,因此必须以某种方式对数字的符号进行编码。这是用第一位完成的。如果第一位为 1,则该数为负数。

以下是 int 值以十六进制和十进制形式排列在数轴上:

 Hexadecimal        Decimal
 -----------    -----------
 0x80000000     -2147483648
 0x80000001     -2147483647
 0x80000002     -2147483646
    ...              ...
 0xFFFFFFFE              -2
 0xFFFFFFFF              -1
 0x00000000               0
 0x00000001               1
 0x00000002               2
     ...             ...
 0x7FFFFFFE      2147483646
 0x7FFFFFFF      2147483647

从这张图表中可以看出,代表最小可能值的位是通过将最大可能值加 1 得到的,同时忽略符号位的解释。以这种方式添加有符号数时,称为“整数溢出”。是否允许整数溢出或将其视为错误可以使用 C# 中的已检查和未检查语句进行配置。

这个representation被称为2's complement

如果你想更深入,你可以check this link

【讨论】:

    【解决方案2】:

    Int 的最大值为 2^31 - 1,因为 int 是 Int32 的别名,它在内存中存储 4 个字节来表示该值。

    现在让我们来看看int.Max + 1 的概念。在这里,您需要了解用于存储负值的Signed number representations。在二进制数表示中,没有什么像负数一样,而是由一个补码和二进制补码位表示。

    可以说,我的 int1 有一个 1 字节的存储内存,即。 8 位。所以你可以存储到 int1 的最大值是 2^8 -1 = 255 。现在让我们在这个值上加 1-

         11111111 
       + 00000000 
       ----------
        100000000
    

    您的输出是十进制的 100000000 = (512),超出了 int1 的存储容量,表示十进制的负值 -256(因为第一位显示负值)。

    这就是将 int.Max 加 1 变为 int.Minimum 的原因。即。

     `int.Maximum + 1 = int.Minimum`
    

    【讨论】:

      【解决方案3】:

      好的,为了方便起见,我假设 C# 中有一个 4 位整数类型。最高有效位用于存储符号,其余三位用于存储幅度。

      可以存储在这种表示中的最大数字是 +7(以 10 为底的正 7)。在二进制中,这是:

      0111
      

      现在让我们添加一个正面的:

       0111
      +0001
      _____
       1000
      

      哎呀,从幅度中继承并翻转了符号位!您在上面看到的总和实际上是数字 -8,这是可以存储在此表示中的最小可能数字。如果您不熟悉two's complement,这是有符号数字通常以二进制表示的方式,您可能会认为该数字是负零(sign and magnitude 表示中就是这种情况)。您可以阅读二进制补码以更好地理解这一点。

      【讨论】:

      • 有人能解释一下我在这里做错了什么吗?
      • 谢谢这是一个很好的简短解释!不知道为什么其他人投了反对票……