考虑一下这个

        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: 进行了更正:现在你会得到我正在得到的。(对此感到抱歉)

var n = i + 1;到

var n = i + 3;

编辑2: 另一件事,如果它溢出,为什么不引发异常?

添加: 发生溢出时,是不是设置的类型不对

变量n

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


欢迎您提出更好的标题,因为这没有意义......至少我

谢谢

有帮助吗?

解决方案

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

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

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

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

其他提示

 1)  -2147483646 is bigger than -2,147,483,648
 2) 2147483648 is out of range
 3) int is an alias for Int32

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

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

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

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

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

  1. 这是一个溢出, ,您的号码转为负值
  2. 这不是编译器的工作,因为运行时的循环可能会导致同样的事情
  3. int 是别名或 System.Int32 它们在 .Net 中是等效的。

这是因为位表示

您使用 Int32,但 char (8 位)也是如此

第一位保存符号,然后后面的位保存数字

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

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

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

这也是为什么当你这样做时你会得到一个意想不到的整数:

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

或者

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

对于这个问题。

编辑:
也不例外,因为.NET 会溢出该数字。
溢出异常只会在赋值操作时发生,或者如 Mark 所解释的,当您设置生成异常的条件时。

通过使用十六进制符号,您可以使我们所有人更容易做到这一点。

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

只是在说'

如果你想抛出异常,写

abc = checked(i+3)

反而。这将检查是否有溢出。

另外,在 C# 中,默认设置是在溢出时不引发异常。但是您可以在项目属性的某个位置切换该选项。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top