【问题标题】:strange no error within C# application [duplicate]C#应用程序中奇怪的没有错误[重复]
【发布时间】:2014-07-15 15:03:59
【问题描述】:

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

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

结果是:-2147483648

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

  • 为什么我没有编译或运行时错误?就像在这个例子中

  • 负号是什么原因?

谢谢

【问题讨论】:

  • 这个问题已经被回答了很多次...(编辑:我的意思是溢出问题)例如:here
  • @ThreeFx 有什么问题吗?你的意思是它是重复的?
  • 是的,我就是这个意思

标签: c# .net compilation int jit


【解决方案1】:

编译器默认为未经检查的算术;感谢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】:

    正如克里斯托斯所说,负号来自整数溢出。你确实得到一个错误的原因是因为编译器不会评估溢出值的表达式。

     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);
    

    【讨论】:

      【解决方案3】:

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

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

      负号的原因是什么?

      这是因为整数溢出。

      见:checked (C# Reference)

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

      【讨论】:

      • 在运行时,为什么我没有错误??对于编译来说似乎很清楚
      • @Lamloumi,在运行时你会得到一个异常Arithmetic operation resulted in an overflow.。错误发生在编译时。 (如果您已检查关键字)
      【解决方案4】:

      负号的原因是什么?

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

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

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

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

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

      【讨论】:

      • 结果是假的,为什么我这里没有错误int j = (int)(i+1);??
      • @Lamloumi 结果不假,就整数而言是正确的
      猜你喜欢
      • 1970-01-01
      • 2016-06-06
      • 1970-01-01
      • 2016-07-07
      • 2017-12-15
      • 2016-08-16
      • 2014-12-25
      • 2020-11-04
      • 1970-01-01
      相关资源
      最近更新 更多