为什么int.MaxValue - int.MinValue = -1?

时间:2014-05-23 16:15:33

标签: c#

根据我的理解,这应该会给你一个溢出错误,当我这样写时:

public static void Main()
{

    Console.WriteLine(int.MaxValue - int.MinValue);
}

它确实正确地给了我一个溢出错误。

然而:

public static void Main()
{

    Console.WriteLine(test());
}

public static Int32 test(int minimum = int.MinValue, int maximum = int.MaxValue)
{
    return maximum - minimum;
}

将输出-1 为什么这样做?它应该抛出一个错误,因为它显然是溢出的!

4 个答案:

答案 0 :(得分:51)

int.MaxValue - int.MinValue = int无法容纳的值。因此,数字回绕到-1。

就像2147483647 - ( - 2147483648)= 4294967295这不是一个int

Int32.MinValue Field

  

此常量的值为 -2,147,483,648; 即十六进制   0x80000000的。

Int32.MaxValue Field

  

此常量的值为 2,147,483,647; 即十六进制   0x7FFFFFFF的。

来自MSDN

  

当发生整数溢出时,会发生什么取决于执行   上下文,可以选中或取消选中。在检查的上下文中,   抛出OverflowException。在未经检查的背景下,最多   结果的有效位被丢弃并继续执行。   因此,C#为您提供了处理或忽略溢出的选择。

答案 1 :(得分:15)

这是因为代码的编译时溢出检查。这条线

Console.WriteLine(int.MaxValue - int.MinValue);

在运行时实际上不会出现错误,它会简单地写入“-1”,但由于溢出检查,您会收到编译错误“操作在编译时以编译模式溢出”。

在这种情况下,为了解决编译时溢出检查,你可以这样做:

         unchecked
        {
            Console.WriteLine(int.MaxValue - int.MinValue);                
        }

哪个会正常运行并输出“-1”

答案 2 :(得分:2)

控制此项的默认项目级设置设置为"未选中"默认情况下。您可以通过转到项目属性,“构建”选项卡,“高级”按钮来打开溢出检查。弹出窗口允许您打开溢出检查。您链接到的.NET Fiddle工具似乎执行一些额外的静态分析,阻止您看到真正的开箱即用的运行时行为。 (上面第一个代码片段的错误是"在编译模式下,操作在编译时溢出。"您没有看到运行时错误。)

答案 3 :(得分:2)

我认为它比溢出更进一步。

如果我看看这个

 Int64 max = Int32.MaxValue;
 Console.WriteLine(max.ToString("X16")); // 000000007FFFFFFF
 Int64 min = Int32.MinValue;
 Console.WriteLine(min.ToString("X")); //FFFFFFFF80000000
 Int64 subtract = max - min;
 Console.WriteLine(subtract.ToString("X16")); //00000000FFFFFFFF <- not an overflow since it's a 64 bit number
 Int32 neg = -1
 Console.WriteLine(neg.ToString("X")); //FFFFFFFF

在这里,您可以看到,如果您只是在2的补码中减去十六进制值),您将获得32位数中的-1的数字。 (在主导0的主干之后

2的补码算法非常有趣http://en.wikipedia.org/wiki/Two's_complement