我有一个c#应用程序,我有这个代码:
public static void Main()
{
int i = 2147483647;
int j = i+1;
Console.WriteLine(j);
Console.ReadKey();
}
结果是:-2147483648
我知道每个整数必须是< 2147483648
。所以
感谢
答案 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
负号是什么原因?
这是因为整数溢出。
默认情况下,包含仅常量值的表达式会导致 如果表达式产生一个外部值,则编译错误 目的地类型的范围。如果表达式包含一个或 更多的非常量值,编译器不会检测到溢出。