VBA 中最大可能的十进制值是多少?
What is the largest possible decimal value in VBA?
我一直在尝试在 vba 中创建类似于 DEC_MAX
常量的东西。
问题是,这有点棘手,因为没有Decimal
数据类型!
最接近功能小数的是 CDec()
定义的函数:
Return the Decimal data value that is the result of Expression being
Let-coerced to Decimal
所以很自然地,我认为任何可能溢出的值都会被强制到可实现的最大值 Decimal
。我尝试插入最大小数 vb.net value from MSDN Documentation
但是请注意,这样做会导致溢出:
那么在这里如何计算最接近十进制最大值的近似值呢?我试过这个 "computer-bricking" 丑陋的代码循环:
Private Sub brick_my_Excel()
On Error Resume Next
x = 79228162514264337593543950335 'let's let it auto-coerce i guess
Do
Debug.Print(x)
x = x - 1
Loop
End Sub
然而,这完全抑制了溢出,以几乎类似字符串的方式打印 x,而没有过多关注计算。
所以,
- 如何计算它?
- 我们可以传递给
CDec()
函数的最大可能表达式是什么?
我能弄清楚如何做到这一点的唯一方法是完全绕过 VBA 和 "build" 内存中的最大值。 The DECIMAL
structure为16字节,定义为:
typedef struct tagDEC {
USHORT wReserved;
BYTE scale;
BYTE sign;
ULONG Hi32;
ULONGLONG Lo64;
} DECIMAL;
由于您无法在 VBA 中显式声明 Decimal
,CDec(0)
将为您提供一个具有正确 Variant
类型的供您使用。符号和比例独立于 12 字节值,因此只需设置该内存区域中的所有位即可获得最大值(最大值的比例为 0):
#If VBA7 Then
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias _
"RtlMoveMemory" (Destination As LongPtr, Source As Any, _
ByVal length As Long)
#Else
Private Declare Sub CopyMemory Lib "kernel32" Alias _
"RtlMoveMemory" (Destination As Long, Source As Any, _
ByVal length As Long)
#End If
Private Const VT_DECIMAL As Integer = &HE
Private Const BIT_MASK As Long = &HFFFFFFFF
Private Const DATA_OFFSET = 4
Private Const SIZEOF_LONG = 4
Public Function MaxDecimal() As Variant
'Get a decimal to work with.
Dim dec As Variant
dec = CDec(0)
Dim vtype As Integer
'First 2 bytes are the VARENUM.
CopyMemory ByVal VarPtr(vtype), ByVal VarPtr(dec), LenB(vtype)
'Make sure the VARENUM is a VT_DECIMAL.
If vtype = VT_DECIMAL Then
'Fill the top 12 bytes of it's data area with truthy bits
CopyMemory ByVal VarPtr(dec) + DATA_OFFSET, BIT_MASK, SIZEOF_LONG
CopyMemory ByVal VarPtr(dec) + DATA_OFFSET + SIZEOF_LONG, BIT_MASK, SIZEOF_LONG
CopyMemory ByVal VarPtr(dec) + DATA_OFFSET + SIZEOF_LONG * 2, BIT_MASK, SIZEOF_LONG
End If
MaxDecimal = dec
End Function
请注意,这显然不会为您提供 Const
,但它确实为您提供了正确的最大值:
Public Sub Test()
MsgBox MaxDecimal
End Sub
我不确定问题是什么,因为有很多 intentions/questions 提出:
What is the largest possible decimal value in VBA?
如你所知:79228162514264337593543950335
I've been trying to create something similar to a DEC_MAX constant in vba.
您不会将 Variant 转化为常量,但 String 可能适合您?
How would one go about calculating it?
喜欢:
Public Const MAX_DEC_STRING = "79228162514264337593543950335"
Public Function MAX_DEC() As Variant
MAX_DEC = CDec(MAX_DEC_STRING)
End Function
Sub test()
Dim v As Variant, x As Variant
v = MAX_DEC
x = CDec("79228162514264337593543950334") '7922816251426433759354395033
MsgBox v - x
End Sub
What is the largest possible expression we can pass to the CDec() function?
同上
我一直在尝试在 vba 中创建类似于 DEC_MAX
常量的东西。
问题是,这有点棘手,因为没有Decimal
数据类型!
最接近功能小数的是 CDec()
定义的函数:
Return the Decimal data value that is the result of Expression being Let-coerced to Decimal
所以很自然地,我认为任何可能溢出的值都会被强制到可实现的最大值 Decimal
。我尝试插入最大小数 vb.net value from MSDN Documentation
但是请注意,这样做会导致溢出:
那么在这里如何计算最接近十进制最大值的近似值呢?我试过这个 "computer-bricking" 丑陋的代码循环:
Private Sub brick_my_Excel()
On Error Resume Next
x = 79228162514264337593543950335 'let's let it auto-coerce i guess
Do
Debug.Print(x)
x = x - 1
Loop
End Sub
然而,这完全抑制了溢出,以几乎类似字符串的方式打印 x,而没有过多关注计算。
所以,
- 如何计算它?
- 我们可以传递给
CDec()
函数的最大可能表达式是什么?
我能弄清楚如何做到这一点的唯一方法是完全绕过 VBA 和 "build" 内存中的最大值。 The DECIMAL
structure为16字节,定义为:
typedef struct tagDEC {
USHORT wReserved;
BYTE scale;
BYTE sign;
ULONG Hi32;
ULONGLONG Lo64;
} DECIMAL;
由于您无法在 VBA 中显式声明 Decimal
,CDec(0)
将为您提供一个具有正确 Variant
类型的供您使用。符号和比例独立于 12 字节值,因此只需设置该内存区域中的所有位即可获得最大值(最大值的比例为 0):
#If VBA7 Then
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias _
"RtlMoveMemory" (Destination As LongPtr, Source As Any, _
ByVal length As Long)
#Else
Private Declare Sub CopyMemory Lib "kernel32" Alias _
"RtlMoveMemory" (Destination As Long, Source As Any, _
ByVal length As Long)
#End If
Private Const VT_DECIMAL As Integer = &HE
Private Const BIT_MASK As Long = &HFFFFFFFF
Private Const DATA_OFFSET = 4
Private Const SIZEOF_LONG = 4
Public Function MaxDecimal() As Variant
'Get a decimal to work with.
Dim dec As Variant
dec = CDec(0)
Dim vtype As Integer
'First 2 bytes are the VARENUM.
CopyMemory ByVal VarPtr(vtype), ByVal VarPtr(dec), LenB(vtype)
'Make sure the VARENUM is a VT_DECIMAL.
If vtype = VT_DECIMAL Then
'Fill the top 12 bytes of it's data area with truthy bits
CopyMemory ByVal VarPtr(dec) + DATA_OFFSET, BIT_MASK, SIZEOF_LONG
CopyMemory ByVal VarPtr(dec) + DATA_OFFSET + SIZEOF_LONG, BIT_MASK, SIZEOF_LONG
CopyMemory ByVal VarPtr(dec) + DATA_OFFSET + SIZEOF_LONG * 2, BIT_MASK, SIZEOF_LONG
End If
MaxDecimal = dec
End Function
请注意,这显然不会为您提供 Const
,但它确实为您提供了正确的最大值:
Public Sub Test()
MsgBox MaxDecimal
End Sub
我不确定问题是什么,因为有很多 intentions/questions 提出:
What is the largest possible decimal value in VBA?
如你所知:79228162514264337593543950335
I've been trying to create something similar to a DEC_MAX constant in vba.
您不会将 Variant 转化为常量,但 String 可能适合您?
How would one go about calculating it?
喜欢:
Public Const MAX_DEC_STRING = "79228162514264337593543950335"
Public Function MAX_DEC() As Variant
MAX_DEC = CDec(MAX_DEC_STRING)
End Function
Sub test()
Dim v As Variant, x As Variant
v = MAX_DEC
x = CDec("79228162514264337593543950334") '7922816251426433759354395033
MsgBox v - x
End Sub
What is the largest possible expression we can pass to the CDec() function?
同上