数据类型 LongLong 溢出
Data Type LongLong Is Overflowing
我正在 MsAccess 中开发一个有趣的项目,以毫秒为单位进行时间记录。
尝试将秒转换为毫秒时,出现溢出错误。我已经确认我的系统 运行 是 64 位的,而且我所做的数学计算还没有接近极限。
有人知道发生了什么事吗?
Public Sub this()
Dim this As LongLong
this = 474 * 86400 * 1000
End Sub
对 LongLong 类型使用 type-declaration character:
this = 474^ * 86400^ * 1000^
您可以强制转换为 LongLong:
Public Sub this()
Dim this As LongLong
this = CLngLng(474) * 86400 * 1000
Debug.Print this
End Sub
嗯,为什么不起作用?
VBA 尝试根据位数转换之前未声明的数字。它从 Integer
开始 'thinking',然后是 Long
,并且不能继续猜测,除非您没有明确声明其中一个乘数来接受必要的结果类型。它尝试将结果放入上述猜测的类型之一。如果不可能,它 returns 是讨论中的错误。所以,为了避免错误,需要至少有一个被乘数被声明为结果期望的类型,或者更大的类型。
请看下一个测试Sub
:
Sub testMultiplyingNumbers()
Dim x As LongLong, first As Variant
'x = 474 * 86400 * 1000 'returns Overflow (Run-time error '6')
Debug.Print VarType(1000) 'returns 2 (vbInteger)
Debug.Print VarType(474 * 86400) 'returns 3 (vbLong)
first = 474 'accepts up to 1.797693134862315 E308 for positive values
Debug.Print VarType(first * 86400 * 1000) 'returns 5 (vbDouble) 40953600000 admitted
'max 1.79769313486231570 E+308 for positive values
x = CLngLng(476) * 86400 * 1000 'it works
x = 474^ * 86400 * 1000 'it works
x = CDbl(474) * 86400 * 1000 'it works
x = first * 86400 * 1000 'it works
Debug.Print x
End Sub
好吧,如果您使用的是 Access x64,那么您可以使用 LongLong,而 Steeve 的 post 使用类型字符 (^) 看起来相当不错。 (投票!!!)。
但是,您可能希望保持 x32 位兼容性,因为很多计算机仍然是 运行 office x32 位(它仍然是更常见的安装版本 - 但这种情况开始发生变化)。
因此,您可以使用双变量(两者都可用 x32/x64),或者您可以使用压缩十进制。压缩小数通常优于双精度,因为它不会出现小数舍入错误。
dim x as Variant
x = 474@ * 86400@ * 1000@
因此,double 类型工作有效,但它们存在舍入问题,因此上面将为您提供 DECIMAL 类型。这些数字最长可达 28 位,它们实际上是缩放整数类型(因此没有浮点数舍入错误。
如前所述,上面的优点是代码将在 x32 和 x64 位版本的 Access 中工作。
LongLong 仅在 Access x64 位中可用。
我正在 MsAccess 中开发一个有趣的项目,以毫秒为单位进行时间记录。
尝试将秒转换为毫秒时,出现溢出错误。我已经确认我的系统 运行 是 64 位的,而且我所做的数学计算还没有接近极限。
有人知道发生了什么事吗?
Public Sub this()
Dim this As LongLong
this = 474 * 86400 * 1000
End Sub
对 LongLong 类型使用 type-declaration character:
this = 474^ * 86400^ * 1000^
您可以强制转换为 LongLong:
Public Sub this()
Dim this As LongLong
this = CLngLng(474) * 86400 * 1000
Debug.Print this
End Sub
嗯,为什么不起作用?
VBA 尝试根据位数转换之前未声明的数字。它从 Integer
开始 'thinking',然后是 Long
,并且不能继续猜测,除非您没有明确声明其中一个乘数来接受必要的结果类型。它尝试将结果放入上述猜测的类型之一。如果不可能,它 returns 是讨论中的错误。所以,为了避免错误,需要至少有一个被乘数被声明为结果期望的类型,或者更大的类型。
请看下一个测试Sub
:
Sub testMultiplyingNumbers()
Dim x As LongLong, first As Variant
'x = 474 * 86400 * 1000 'returns Overflow (Run-time error '6')
Debug.Print VarType(1000) 'returns 2 (vbInteger)
Debug.Print VarType(474 * 86400) 'returns 3 (vbLong)
first = 474 'accepts up to 1.797693134862315 E308 for positive values
Debug.Print VarType(first * 86400 * 1000) 'returns 5 (vbDouble) 40953600000 admitted
'max 1.79769313486231570 E+308 for positive values
x = CLngLng(476) * 86400 * 1000 'it works
x = 474^ * 86400 * 1000 'it works
x = CDbl(474) * 86400 * 1000 'it works
x = first * 86400 * 1000 'it works
Debug.Print x
End Sub
好吧,如果您使用的是 Access x64,那么您可以使用 LongLong,而 Steeve 的 post 使用类型字符 (^) 看起来相当不错。 (投票!!!)。
但是,您可能希望保持 x32 位兼容性,因为很多计算机仍然是 运行 office x32 位(它仍然是更常见的安装版本 - 但这种情况开始发生变化)。
因此,您可以使用双变量(两者都可用 x32/x64),或者您可以使用压缩十进制。压缩小数通常优于双精度,因为它不会出现小数舍入错误。
dim x as Variant
x = 474@ * 86400@ * 1000@
因此,double 类型工作有效,但它们存在舍入问题,因此上面将为您提供 DECIMAL 类型。这些数字最长可达 28 位,它们实际上是缩放整数类型(因此没有浮点数舍入错误。
如前所述,上面的优点是代码将在 x32 和 x64 位版本的 Access 中工作。
LongLong 仅在 Access x64 位中可用。