为什么int32.maxvalue + 1溢出很长?

如果您将以下代码放在.NET 4.5应用程序中:

public const long MAXIMUM_RANGE_MAGNITUDE = int.MaxValue + 1; 

生成编译器错误,指出“操作在编译模式下在编译时溢出”。 我知道我可以把它放在一个“未经检查”的块中并且没问题,但我的问题是为什么错误出现在第一位? 很明显,long可以保持int的最大值加1。

请注意,使用Int32和Int64而不是long和int似乎没有帮助。

这是因为赋值右侧的计算是以整数类型完成的。 它是溢出整数

你可以解决这个问题:

 public const long MAXIMUM_RANGE_MAGNITUDE = int.MaxValue + (long)1; // or 1L 

通过将至少一个操作数转换为long

您收到错误的原因在C#规范中指定。

参见C#规范第4.1.5节(积分类型)

对于二进制+, – ,*,/,%,&,^,|,==,!=,>,<,> =和<=运算符,操作数转换为类型T,其中T是第一个int,uint,long和ulong ,可以完全表示两个操作数的所有可能值。 然后使用类型T的精度执行操作,结果的类型是T(或关系运算符的bool)。 不允许一个操作数为long类型,另一个操作数为binary类型的二元运算符。

在您的情况下,因为两个加法操作数都可以用int表示,因此计算以整数类型完成。 将一个操作数显式地转换为long会导致long结果,因此不会出现溢出错误。

你的代码实际上是这样的:

 (long)(int.MaxValue + 1) 

但是因为.Net框架在int和long之间有一个内置的隐式转换,所以你不必在代码中显式地使用强制转换。

所以首先执行这部分代码:

 int.MaxValue + 1 

并且此操作的结果是一个导致和溢出exception的int值。 所以你的代码甚至没有机会开始从int到long的转换。

我认为这与在转换为int.MaxValue + 1 之前计算的int.MaxValue + 1的值有关。 当然long可以保存该值,但由于您正在进行整数加法,因此无法在int中存储int.MaxValue + 1的整数值,直到进行int.MaxValue + 1为止。

尝试

 public const long MAXIMUM_RANGE_MAGNITUDE = (long)int.MaxValue + 1L; 

将常量值转换为long。

 public const long MAXIMUM_RANGE_MAGNITUDE = (long) int.MaxValue + 1;