3

考虑这个

        int i = 2147483647;
        var n = i + 3;
        i = n;

        Console.WriteLine(i);           // prints -2147483646    (1)
        Console.WriteLine(n);           // prints -2147483646    (2)
        Console.WriteLine(n.GetType()); // prints System.Int32   (3)

我对以下内容感到困惑

  • (1) int 怎么能保持值 -2147483646 ?(整数范围 = -2,147,483,648 到 2,147,483,647)
  • (2)为什么这个打印 -2147483648 而不是 2147483648 (编译器应该决定更好的类型,因为 int 范围超过)
  • (3)如果它在某处转换,为什么 n.GetType() 给出 System.Int32 ?

编辑1:更正:现在你会得到我正在得到的。(对此感到抱歉)

变量 n = i + 1; 至

变量 n = i + 3;

Edit2:还有一件事,如果它溢出,为什么不引发异常?

补充:当溢出发生时,设置类型是不是不对

变量 n

相应地声明var n = i + 3;另一种类型?


欢迎你提出一个更好的标题,因为这对……至少我没有意义

谢谢

4

8 回答 8

7

更新:海报解决了他的问题。

1) 这是预期的输出,因为您将 3 添加到 int.MaxValue 导致溢出。默认情况下,在 .NET 中,这是在未经检查的代码中对负值进行环绕的合法操作,但如果您checked在代码周围添加一个块,它将抛出一个OverflowException相反的。

2) 声明的变量的类型var是在编译时而不是运行时确定的。这是一个规则,添加两个 Int32 会给出一个 Int32,而不是 UInt32、Int64 或其他东西。所以即使在运行时你可以看到结果对于 Int32 来说太大了,它仍然必须返回一个 Int32。

3)它没有转换为另一种类型。

于 2010-02-14T01:25:34.607 回答
3
 1)  -2147483646 is bigger than -2,147,483,648
 2) 2147483648 is out of range
 3) int is an alias for Int32
于 2010-02-14T01:26:44.043 回答
3

1)
首先,变量中的值不是-2147483646,而是-2147483648。再次运行测试并检查结果。

没有理由 int 不能保存值 -2147483646。它在 -2147483648..2147483647 范围内。

2)
编译器选择变量的数据类型作为表达式结果的类型。该表达式返回一个 int 值,即使编译器会为变量选择更大的数据类型,该表达式仍会返回一个 int 并且您会得到与结果相同的值。

溢出的是表达式中的操作,而不是将结果分配给它溢出的变量。

3)
它没有在任何地方转换。

于 2010-02-14T01:32:27.277 回答
1
  1. 这是一个溢出,你的号码环绕并变成负数
  2. 这不是编译器的工作,因为运行时的循环可能会导致同样的事情
  3. int是别名,或者System.Int32它们在 .Net 中是等价的。
于 2010-02-14T01:25:49.520 回答
1

这是因为位表示

你使用 Int32 但同样适用于 char (8位)

第一位保存符号,然后以下位保存数字

所以用 7 位你可以代表 128 个数字0111 1111

当您尝试第 129 个时1000 0001,符号位被设置,因此计算机认为它是 -1

于 2010-02-14T01:33:03.883 回答
0

如果要抛出异常,请编写

abc = checked(i+3)

反而。这将检查溢出。

此外,在 c# 中,默认设置是在溢出时不抛出异常。但是您可以在项目属性的某处切换该选项。

于 2010-02-14T03:07:30.140 回答
0

您可以使用十六进制表示法使我们所有人都更容易做到这一点。

不是每个人都知道第八个梅森素数是 0x7FFFFFFF

只是在说'

于 2010-02-14T02:28:38.217 回答
0

.NET 中的算术运算不会改变实际类型。
你从一个(32 位)整数开始,+3 不会改变它。

这也是为什么您在执行此操作时会得到一个意外的整数:

int a = 2147483647;
double b = a / 4;

或者

int a = 2147483647;
var b = a / 4;

对于这个问题。

编辑
没有例外,因为 .NET 溢出了数字。
溢出异常只会发生在赋值操作中,或者正如 Mark 在设置条件以生成异常时所解释的那样。

于 2010-02-14T01:37:39.577 回答