CInt函数异常行为:为何抛出System.OverflowException?
VB.NET算术表达式中间结果溢出判定规则解析
Integer类型的最大值为2'147'483'647,先看以下代码表现:
Dim t As Integer = 4094 Dim sz as Integer sz = CInt((t / 2) * 1024 * 1024) sz = CInt(t * 1024 * 1024 / 2)
第3行执行正常,但第4行抛出:
System.OverflowException: 'Arithmetic operation resulted in an overflow.
尽管两个表达式的最终结果均为2'146'435'072(小于Integer最大值)。
但运行以下代码时无报错:
Dim t As Integer = 4094 * 2 Dim sz As Integer sz = CInt(((t / 2) * 1024 * 1024) / 2)
其中间结果实际超出了Integer最大值。另外,以下代码也能正常执行:
Dim ln As Long = CLng(1024 ^ 5) Dim n As Integer = CInt((ln + 1) / (1024 ^ 2))
核心判定规则
- 同类型整数运算的溢出检查:当表达式中所有操作数都是Integer类型时,运算过程会保持Integer类型。Debug模式下默认启用整数溢出检查,只要中间步骤的结果超出Integer范围,就会直接抛出
OverflowException,不会继续执行后续运算。比如第一段代码第4行,先计算t * 1024 * 1024,结果为4'293'918'720,远超Integer最大值,因此触发溢出异常。 - 除法运算的类型隐式转换:VB.NET中,整数之间的除法(
/)会默认返回Double类型,而非Integer。比如第一段代码第3行的(t / 2)得到Double,后续与1024的运算都基于Double类型执行,Double的取值范围远大于Integer,因此中间结果不会溢出,最后通过CInt转换为Integer时,结果在范围内就正常。 - 不同类型操作数的隐式提升:当表达式中存在不同精度的数值类型(比如Integer和Long、Integer和Double),VB会自动将低精度类型提升为高精度类型进行运算。比如第三个案例中,
ln是Long类型,1024^2是Integer,运算时Integer会被提升为Long,中间结果保持Long类型,不会触发Integer溢出;第二个案例中(t/2)得到Double,后续运算都基于Double执行,同样不会触发Integer溢出检查。 - 溢出检查的开关控制:溢出检查仅在Debug模式(默认未勾选“移除整数溢出检查”)下生效;若在Release模式勾选“移除整数溢出检查”,Integer运算溢出会直接截断高位,不会抛出异常,但这属于不安全的行为。
内容的提问来源于stack exchange,提问作者Thomas Anderson
相关产品推荐
相关产品推荐

