programar - vba access pdf
Convertir cadena HEX en INT sin firma(VBA) (4)
Con la observación de @arcadeprecinct, pude crear una función para él:
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
Algunos ejemplos de salida:
?Hex2UInt("1234")
4660
?Hex2UInt("80000000")
2147483648
?Hex2UInt("FFFFFFFFFFFF")
281474976710655
En MSACCESS VBA, convierto una cadena hexadecimal a decimal prefijando la cadena con "& h"
?CLng("&h1234")
4660
?CLng("&h80000000")
-2147483648
¿Qué debo hacer para convertirlo a un entero sin signo?
Usar CDbl tampoco funciona:
?CDbl("&h80000000")
-2147483648
una propuesta, resultado en 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
Si desea ir más allá de 2 ^ 31, puede usar Decimal
o LongLong
. LongLong
y CLngLng
solo funcionan en plataformas de 64 bits. Como solo tengo una oficina de 32 bits en este momento, esto es para Decimal
y CDec
.
Parece que hay un problema al convertir números hexadecimales de 8 dígitos porque el uso de 32 bits aparentemente firmado se usa en algún lugar del proceso, lo que da como resultado el error del signo, aunque Decimal
podría manejar el número.
''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
Prueba:
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
Su versión parece ser la mejor respuesta, pero puede acortarse un poco:
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
tendrá error de precisión de redondeo para la mayoría de los valores superiores a 2 ^ 53 - 1 ( aproximadamente 16 dígitos decimales ), pero el Decimal
se puede usar para valores de hasta 16 ^ 12 - 1 (el Decimal
usa 16 bytes, pero solo 12 para el número )
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