C#应用程序中没有错误

时间:2014-07-15 15:03:59

标签: c# .net compilation int jit

我有一个c#应用程序,我有这个代码:

 public static void Main()
        {
            int i = 2147483647;
            int j = i+1;
            Console.WriteLine(j);
            Console.ReadKey();
        }

结果是:-2147483648

我知道每个整数必须是< 2147483648。所以

  • 为什么我没有编译或运行时错误?比如这个例子

img

  • 负号是什么原因?

感谢

4 个答案:

答案 0 :(得分:2)

正如克里斯托斯所说,负号来自整数溢出。你做网络错误的原因是因为编译器没有为溢出值计算表达式。

 0111 1111 1111 1111 1111 1111 1111 1111 2^31-1
+0000 0000 0000 0000 0000 0000 0000 0001 1
=1000 0000 0000 0000 0000 0000 0000 0000 -2^31

原因是最左边的位是符号位,它确定int是正还是负。 0为正,1为负。如果向最大可能数字添加一个,则实质上更改符号位并获得最小的可表示数字。原因是整数使用two's complement storage

要检查值是否溢出,请执行:

int j = checked(i + 1);

答案 1 :(得分:2)

编译器默认为未选中的算术;由于two's-complement storage,你只需要溢出并循环,

这在运行时失败:

public static void Main()
{
    int i = 2147483647;
    int j = checked((int)(i + 1)); // <==== note "checked"
    Console.WriteLine(j);
    Console.ReadKey();
}

这也可以作为编译器开关全局启用。

答案 2 :(得分:1)

  

负号是什么原因?

您有一个负号,因为您已超过最大整数值,下一个整数是可以表示的最小整数。

  

为什么我没有编译或运行时错误?

您没有编译错误,因为这不是错误。此外,这不是运行时错误。您只需在运行时中向i添加一个。由于i的值是可以存储在类型int的变量中的最大整数值,并且由于编程中整数的循环性质,您将获得可以存储的最小整数类型为int的变量。

(类型int的变量可以存储32位整数)。

此外,通过默认,您在C#整数操作中不会在溢出时抛出异常。您可以从项目设置或使用checked语句更改此项,因为已经指出here

答案 3 :(得分:1)

  

为什么我没有编译或运行时错误?

因为编译器可以确定您为变量分配了大于int.MaxValue的值。因为它是硬编码的。但是对于i+1,编译器无法执行代码来确定此计算的结果将大于int.MaxValue

  

负号是什么原因?

这是因为整数溢出

请参阅:checked (C# Reference)

  

默认情况下,包含仅常量值的表达式会导致   如果表达式产生一个外部值,则编译错误   目的地类型的范围。如果表达式包含一个或   更多的非常量值,编译器不会检测到溢出。