将 HEX 字符串转换为 Unsigned INT (VBA)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40213758/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert HEX string to Unsigned INT (VBA)
提问by SBF
In MSACCESS VBA, I convert a HEX string to decimal by prefixing the string with "&h"
在 MSACCESS VBA 中,我通过在字符串前加上“&h”来将十六进制字符串转换为十进制
?CLng("&h1234")
4660
?CLng("&h80000000")
-2147483648
What should I do to convert it to an unsigned integer?
我该怎么做才能将其转换为无符号整数?
Using CDbl doesn't work either:
使用 CDbl 也不起作用:
?CDbl("&h80000000")
-2147483648
采纳答案by Slai
Your version seems like the best answer, but can be shortened a bit:
你的版本似乎是最好的答案,但可以缩短一点:
Function Hex2Dbl(h As String) As Double
Hex2Dbl = CDbl("&h0" & h) ' Overflow Error if more than 2 ^ 64
If Hex2Dbl < 0 Then Hex2Dbl = Hex2Dbl + 4294967296# ' 16 ^ 8 = 4294967296
End Function
Double
will have rounding precision error for most values above 2 ^ 53 - 1 (about 16 decimal digits), but Decimal
can be used for values up to 16 ^ 12 - 1 (Decimal
uses 16 bytes, but only 12 of them for the number)
Double
对于 2 ^ 53 - 1 以上的大多数值(大约 16 位十进制数字),将有舍入精度误差,但Decimal
可用于高达 16 ^ 12 - 1 的值(Decimal
使用 16 个字节,但只有 12 个用于数字)
Function Hex2Dec(h)
Dim L As Long: L = Len(h)
If L < 16 Then ' CDec results in Overflow error for hex numbers above 16 ^ 8
Hex2Dec = CDec("&h0" & h)
If Hex2Dec < 0 Then Hex2Dec = Hex2Dec + 4294967296# ' 2 ^ 32
ElseIf L < 25 Then
Hex2Dec = Hex2Dec(Left$(h, L - 9)) * 68719476736# + CDec("&h" & Right$(h, 9)) ' 16 ^ 9 = 68719476736
End If
End Function
回答by arcadeprecinct
If you want to go higher than 2^31 you could use Decimal
or LongLong
. LongLong
and CLngLng
only work on 64bit platforms though. Since I only have 32 bit office at the moment, this is for Decimal
and CDec
.
如果你想高于 2^31,你可以使用Decimal
或LongLong
。LongLong
并且CLngLng
只能在 64 位平台上工作。由于我目前只有 32 位办公室,这是为Decimal
和CDec
。
There seems to be an issue when converting 8-digit Hex numbers because apparently signed 32-bit is used somewhere in the process which results in the sign mistake even though Decimal
could handle the number.
转换 8 位十六进制数字时似乎存在问题,因为在过程中的某处使用了明显有符号的 32 位,即使Decimal
可以处理数字,也会导致符号错误。
'only for positive numbers
Function myHex2Dec(hexString As String) As Variant
'cut off "&h" if present
If Left(hexString, 2) = "&h" Or Left(hexString, 2) = "&H" Then hexString = Mid(hexString, 3)
'cut off leading zeros
While Left(hexString, 1) = "0"
hexString = Mid(hexString, 2)
Wend
myHex2Dec = CDec("&h" & hexString)
'correct value for 8 digits onle
If myHex2Dec < 0 And Len(hexString) = 8 Then
myHex2Dec = CDec("&h1" & hexString) - 4294967296#
'cause overflow for 16 digits
ElseIf myHex2Dec < 0 Then
Error (6) 'overflow
End If
End Function
Test:
测试:
Sub test()
Dim v As Variant
v = CDec("&H80000000") '-2147483648
v = myHex2Dec("&H80000000") '2147483648
v = CDec("&H7FFFFFFFFFFFFFFF") '9223372036854775807
v = myHex2Dec("&H7FFFFFFFFFFFFFFF") '9223372036854775807
v = CDec("&H8000000000000000") '-9223372036854775808
v = myHex2Dec("&H8000000000000000") 'overflow
End Sub
回答by SBF
With remark of @arcadeprecinct I was able to create a function for it:
通过@arcadeprecinct 的评论,我能够为它创建一个函数:
Function Hex2UInt(h As String) As Double
Dim dbl As Double: dbl = CDbl("&h" & h)
If dbl < 0 Then
dbl = CDbl("&h1" & h) - 4294967296#
End If
Hex2UInt = dbl
End Function
Some example output:
一些示例输出:
?Hex2UInt("1234")
4660
?Hex2UInt("80000000")
2147483648
?Hex2UInt("FFFFFFFFFFFF")
281474976710655
Maximum value to represent as an integer is 0x38D7EA4C67FFF
表示为整数的最大值是 0x38D7EA4C67FFF
?Hex2UInt("38D7EA4C67FFF")
999999999999999
?Hex2UInt("38D7EA4C68000")
1E+15
回答by h2so4
a proposal, result in h
一个提议,结果是 h
sh = "&H80000000"
h = CDbl(sh)
If h < 0 Then
fd = Hex$(CDbl(Left(sh, 3)) - 8)
sh = "&h" & fd & Mid(sh, 4)
h = CDbl(sh) + 2 ^ 31
End If