将HEX字符串转换为无符号INT(VBA)

时间:2016-10-24 08:24:33

标签: vba access-vba

在MSACCESS VBA中,我通过在字符串前加上"& h"

将十六进制字符串转换为十进制
?CLng("&h1234")
4660
?CLng("&h80000000")
-2147483648 

如何将其转换为无符号整数?

使用CDbl也不起作用:

?CDbl("&h80000000")
-2147483648 

5 个答案:

答案 0 :(得分:2)

如果您想要高于2 ^ 31,可以使用DecimalLongLongLongLongCLngLng仅适用于64位平台。由于我目前只有32位,这适用于DecimalCDec

转换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

测试:

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

答案 1 :(得分:2)

通过@arcadeprecinct的评论,我能够为它创建一个函数:

data: {name: localStorage.getItem('name')}

一些示例输出:

 recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL));

表示为整数的最大值为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

?Hex2UInt("1234")
4660 
?Hex2UInt("80000000")
2147483648 
?Hex2UInt("FFFFFFFFFFFF")
281474976710655 

答案 2 :(得分:2)

你的版本似乎是最好的答案,但可以缩短一点:

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
对于大于2 ^ 53 - 1(about 16 decimal digits)的大多数值,

Double会出现舍入精度误差,但Decimal可用于最多16 ^ 12 - 1的值(Decimal {1}}使用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

答案 3 :(得分:0)

提案,结果为h

.exe

答案 4 :(得分:0)

我在这里找到Word VBA解决方案的方法,但是我发现的内容可能也适用于其他Office应用程序。我意识到这是一个非常老的问题,并且有一些巧妙的解决方案,但令我惊讶的是,没有人解释这似乎是问题的根本原因,因此可能是一个问题在线解决方案在许多情况下。当我是1970年代的汇编语言程序员时,他在二进制和八进制上的工作比其他任何事情都要多,这是一个非常常见的问题,称为“ 2s补码”。

我将从最基本的原则以最简单的形式来说明它的字节处理方式,以便即使是绝对的初学者也可以理解它。

通常,最高有效位是左侧的第7位,其值为128,最低有效位是右侧的第0位,其值为1。因此,如果所有位都为最高可能值设置为255。但是在2s补码中,位7是“符号位”。这仅保留从0到6的七个位来保留实际值,从而使它们的最大值为127。符号位的值为-128。如果所有8位都被置位,则字节值变为(-128 + 127),其负十进制值为-1。 8位值的2s补码范围是-128(仅设置了7位)到+127(仅设置了0至6位)。如果符号位被置位,则字节的值是-128加上位0到6中存储的值的正值。二进制11111101 =十六进制FD =十进制(-128 + 125)= -3,10110100 =十六进制B4 =十进制(-128 + 52)= -76。

2s补码在每个增加的8位边界上应用相同的效果,因此对于16位,符号位为15位(值为-32,768),正值为0至14位,从而给出16位值的范围是-32768到32767。24位范围是-8388608到8388607,依此类推。

我最近在一些代码中遇到了这种转换问题,该代码正在转换十六进制RGB颜色值,这些颜色值是在Word文档中由6个字符的文本字符串产生的。成功处理了成千上万个错误后,突然出现了“超出范围”错误弹出窗口。导致该问题的字符串是“ 008080”。命令... = Val("&H" + variable)已将其转换为-32896,该无效值将作为color属性传递。 Val()函数删除了前导零,并将8080视为带符号的2s补码16位值。

就我而言,解决方案很简单。因为我知道我将一直处理24位,6个字符的十六进制值。我只是在十六进制代码的前面添加了一个额外的"1"文本字符(因此使其长度超过16位),然后实际上减去了相同的值。因此,使用变量HexCode中保留的原始6个字符的十六进制RGB代码,我使用命令获得了正确的十进制结果

DecCode = Val("&H" + "1" + HexCode) - Val("&H" + "1000000")

仅在现有行中添加一些额外的代码即可解决问题。我希望我对问题原因的解释有助于其他人在适当的情况下设计自己的解决方案。