根据MSDN,对于Variant数据类型:
“数值数据可以是-1.797693134862315E308到-4.94066E-324为负值的任何整数或实数值,从正值为4.94066E-324到1.797693134862315E308。”
但是,即使计算后的所有最终值都落在可接受的范围内,以下代码也会出错:
Sub Test()
Dim v1, v2, v3, v4
v1 = 569847501 + 54678 ' OKAY
v2 = 7784687414# + 98565821345# ' OKAY
v3 = 7784687414# + 1132747441 ' OKAY
v4 = 1132747441 + 1788441323 ' FAILS
End Sub
MSDN也指出:
“但是,如果对包含Byte,Integer,Long或Single的Variant执行算术运算,并且结果超出原始数据类型的正常范围,则结果将在Variant中提升为下一个更大的数据类型。 Byte被提升为Integer,Integer被提升为Long,Long和Single被提升为Double。“
文档说明当算术运算超出原始数据类型的正常范围时,应该提升类型。为什么v4
未升级为Double
?
答案 0 :(得分:6)
来自https://support.microsoft.com/en-us/kb/199809 - 参见粗体声明
此语句生成溢出错误,因为24 * 24 * 60 = 34560,超过了2字节整数的最大大小(32767)。 Visual Basic不会评估整个表达式以检查 结果的大小 ,而是继续使用2字节的临时值 计算空间。如果您发生相同的溢出错误 将前面的值声明为常量并将常量相乘。
为了解决这种问题,总是很重要 在数值计算中使用它们时显式键入数字 在定义常量时。如果前面的表达式更改为 以下内容:
所以改成它......
v4 = 1132747441# + 1788441323#
......诀窍,但肯定闻到了。
答案 1 :(得分:6)
您正在使用不是变体的数字文字。它们被编译器解释为容纳文字值的最小必要类型,尽管Byte
值将默认为Integer
类型。
Debug.Print TypeName(1132747441) 'Long
Debug.Print TypeName(1788441323) 'Long
正如@ComIntern指出的那样,你在表达式中分配2个long的结果,表达式在分配给Variant v4
正如@dazedandconfused指出的那样,您可以将文字值强制转换为更合适的类型,并且表达式将进行评估,并且可以分配变体。
为了获得Microsoft为Variant类型记录的行为,您需要将文字值强制转换为 之前在表达式中使用它们。两个变体都将包含 Long
,但您将获得文档声明的自动重新输入。
Sub Test()
Dim v1, v2, v3, v4
Debug.Print TypeName(1132747441) 'Long
Debug.Print TypeName(1788441323) 'Long
Dim v5, v6
v5 = 1132747441
v6 = 1788441323
Debug.Print TypeName(v5) 'Long
Debug.Print TypeName(v6) 'Long
v4 = v5 + v6 'OKAY
Debug.Print TypeName(v4) 'Double
v4 = 0
Debug.Print TypeName(v4) 'Integer
v4 = CVar(1132747441) + CVar(1788441323) ' OKAY
Debug.Print TypeName(v4) 'Double
v1 = 569847501 + 54678 ' OKAY
v2 = 7784687414# + 98565821345# ' OKAY
v3 = 7784687414# + 1132747441 ' OKAY
v4 = 1132747441 + 1788441323 ' FAILS
End Sub