根据我的理解,这应该会给你一个溢出错误,当我这样写时:
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 为什么这样做?它应该抛出一个错误,因为它显然是溢出的!
答案 0 :(得分:51)
int.MaxValue - int.MinValue
= int无法容纳的值。因此,数字回绕到-1。
就像2147483647 - ( - 2147483648)= 4294967295这不是一个int
此常量的值为 -2,147,483,648; 即十六进制 0x80000000的。
此常量的值为 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