为什么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;