我正在尝试将十六进制的大整数转换为十进制并且VBA
不断返回不正确的值。
在VBA
中,当我期望"&H0A1000043"
时,字符串-1593835453
会返回2701131843
。我尝试了CDbl
,CLng
和Val
函数,它们都返回了错误的负值。
Excel HEX2DEC
确实返回了正确的值。我认为这是VBA
函数中的错误我错了吗?
答案 0 :(得分:6)
这里的实际核心问题是VBA Long数据类型的有限长度以及VBA数字类型(几乎)全部签名的事实。因此,当您尝试CLng("&H0A1000043")
之类的内容时,您试图将该数字解释为带符号的32位整数。在这种情况下,-1593835453是正确的值。您可以检查像this one这样的十六进制转换器(确保将“二进制类型”设置为带符号的32位。
为了正确地完成此转换,您必须使用更大的数字类型,例如LongLong(仅在64位Office中可用)。例如。 CLngLng("&H0A1000043^")
Hex2Dec
成功失败的原因是因为Hex2Dec
可能直接转换为字符串,而不必经过数字的中间内部表示,这是它被解释为正在签署。
答案 1 :(得分:2)
您需要从字符串:
开始Sub BigHexToDecimal()
Dim N As String
N = "A1000043"
MsgBox Application.WorksheetFunction.Hex2Dec(N)
End Sub
答案 2 :(得分:1)
尝试添加&到Hex-String的末尾并使用Val函数: MS Documentation
答案 3 :(得分:0)
感谢您直接获取有关位数的信息。我键入了#34; VBA"到一个搜索引擎,它给了我一个Visual Basic的表,不一样。一个人必须阅读文本。 " Application.WorksheetFunction.Hex2Dec(N)" 返回一个字符串,但我做了那个工作。我从来没有找到任何正确处理64位整数的东西,但字符串消除了它的需要。
答案 4 :(得分:0)
我编写了一个快速函数,允许将大数从十进制转换为十六进制以及从十六进制转换为十进制。我没有对传递的参数进行任何验证,但如果无效,我建议添加它并抛出错误。 我也确信有一种更好、更有效的方法来做到这一点,但为了快速和肮脏,我的解决方案将在紧要关头发挥作用。
要添加代码,请在 Excel Visual Basic 中打开并创建新模块,然后粘贴下面的代码。确保转到“工具”,单击“参考”并添加“Microsoft Scripting Runtime”以启用 Scripting.Dictionary 变量创建。
Function Hex2Dec64(rngRef As Range) As Double
Dim dict As Scripting.Dictionary
Set dict = New Scripting.Dictionary
dict.Add "0", 0
dict.Add "1", 1
dict.Add "2", 2
dict.Add "3", 3
dict.Add "4", 4
dict.Add "5", 5
dict.Add "6", 6
dict.Add "7", 7
dict.Add "8", 8
dict.Add "9", 9
dict.Add "A", 10
dict.Add "B", 11
dict.Add "C", 12
dict.Add "D", 13
dict.Add "E", 14
dict.Add "F", 15
Dim val As String
Dim dec As Double
val = rngRef.Value
For n = 0 To Len(val) - 1
dec = dec + dict(Mid(val, Len(val) - n, 1)) * (16 ^ n)
Next n
Hex2Dec64 = dec
End Function
Function Dec2Hex64(rngRef As Range) As String
Dim hex As String
Dim n As Double
n = rngRef.Value
Dim dict As Scripting.Dictionary
Set dict = New Scripting.Dictionary
dict.Add 0, "0"
dict.Add 1, "1"
dict.Add 2, "2"
dict.Add 3, "3"
dict.Add 4, "4"
dict.Add 5, "5"
dict.Add 6, "6"
dict.Add 7, "7"
dict.Add 8, "8"
dict.Add 9, "9"
dict.Add 10, "A"
dict.Add 11, "B"
dict.Add 12, "C"
dict.Add 13, "D"
dict.Add 14, "E"
dict.Add 15, "F"
While (n <> 0)
Dim tmp As Double
tmp = 0
tmp = Modulus(n, 16)
hex = dict(tmp) & hex
tmp = n / 16
If InStr(1, CStr(tmp), ".") > 0 Then
n = CDbl(Left(CStr(tmp), InStr(1, CStr(tmp), ".") - 1))
Else
n = tmp
End If
Wend
Dec2Hex64 = hex
End Function
Function Modulus(int1 As Double, int2 As Double) As Double
Dim myInt As Double
myInt = int1 / int2
If InStr(1, CStr(myInt), ".") > 0 Then
myInt = CDbl("0." & Right(CStr(myInt), Len(CStr(myInt)) - InStr(1, CStr(myInt), ".")))
Else
myInt = 0
End If
Modulus = myInt * int2
End Function