W poprzednim artykule HexToDec pisałem
o problemach konwersji z zapisu postaci heksadecymalnej na postać dziesiętną przy użyciu funkcji Val(ciąg)
.
Aby ustrzec się błędów podczas konwersji z postaci heksadecymalnej na postać dziesiętną powinniśmy pilnować typów liczb,
jakie powinna zwrócić funkcja konwertująca, poprzez stosowanie znaków deklaracji typu liczby
(sufiksów %, &, ^.
Zaproponowałem, by zamiast używać funkcji Val(ciąg)
i sufiksów typu
liczby (%, &, ^)
w funkcjach konwertujących, używać funkcji konwersji typu według poniższego schematu:
Debug.Print "CByte", CByte("&H" & sHex)
Debug.Print "CInt", CInt("&H" & sHex)
Debug.Print "CLng", CLng("&H" & sHex)
Debug.Print "CSng", CSng("&H" & sHex)
Debug.Print "CDbl", CDbl("&H" & sHex)
Debug.Print "CDec", CDec("&H" & sHex)
Debug.Print "CCur", CCur("&H" & sHex)
#If VBA7 Then
Debug.Print "CLngLng", CLngLng("&H" & sHex)
Debug.Print "CLngPtr", CLngPtr("&H" & sHex)
#End If
Public Function HexToDec(ByVal sHex As String) Debug.Print "CByte", CByte("&H" & sHex) Debug.Print "CInt", CInt("&H" & sHex) Debug.Print "CLng", CLng("&H" & sHex) Debug.Print "CSng", CSng("&H" & sHex) Debug.Print "CDbl", CDbl("&H" & sHex) Debug.Print "CDec", CDec("&H" & sHex) Debug.Print "CCur", CCur("&H" & sHex) #If VBA7 Then Debug.Print "CLngLng", CLngLng("&H" & sHex) Debug.Print "CLngPtr", CLngPtr("&H" & sHex) #End If End Function
Na podstawie powyższego schematu, napisałem funkcją testującą konwersję z zapisu postaci heksadecymalnej na postać dziesiętną:
Public Function testHexToDec(ByVal sHex As String) On Error GoTo ErrHandler Const errOVERFLOW = 6 Const errMISMATCH = 13 Debug.Print "CByte", CByte("&H" & sHex) Debug.Print "CInt", CInt("&H" & sHex) Debug.Print "CLng", CLng("&H" & sHex) Debug.Print "CSng", CSng("&H" & sHex) Debug.Print "CDbl", CDbl("&H" & sHex) Debug.Print "CDec", CDec("&H" & sHex) Debug.Print "CCur", CCur("&H" & sHex) #If VBA7 Then Debug.Print "CLngLng", CLngLng("&H" & sHex) Debug.Print "CLngPtr", CLngPtr("&H" & sHex) #End If ExiHere: Exit Function ErrHandler: If Err.Number = errOVERFLOW Or Err.Number = errMISMATCH Then Debug.Print "Błąd nr " & Err.Number & " " & Err.Description Resume Next Else MsgBox "Błąd nr " & Err.Number & vbNewLine & Err.Description Resume ExiHere End If End Function
Poniżej wyniki przykładowych wywołań funkcji konwersji typu:
&HFFFF,
&HFFFF FFFF,
&HFFFF FFFF FFFF,
&HFFFF FFFF FFFF FFFF,
&H8000,
&H8000 0000,
&H8000 0000 0000,
&H8000 0000 0000 0000 0000,
oraz test konwersji dolnej i górnej granicy zakresu liczbu typu Long
Hex$
(-2 147 483 648) i Hex$
(2 147 483 647)
Test w 64-bitowym środowisku VBA7 na konwersję do postaci heksadecymalnej i potem powrotną konwersję na postać dziesiętną, liczby 2 147 483 647 będącej górnym zakresem liczby typu Long
' górna granica zakresu Long = 2 147 483 647
Hex$
(2147483647) = 7FFFFFFF
CLng
("&H" & "7FFFFFFF") = 2147483647
' w wersji skróconej test ma postać:
CLng
("&H" &Hex$
(2147483647)) = 2147483647
' i równość ta jest prawdziwa
oraz liczby -2 147 483 648 będącej dolną granicą zakresu liczby typu Long
' dolna granica zakresu Long = -2 147 483 648
Hex$
(-2147483648) = FFFFFFFF80000000
CLng
("&H" & "FFFFFFFF80000000") = Błąd nr 13. Type mismatch
' wynik nieznany, gdyż MS Access wyświetla komunikat:
' MS Access podczas konwersji na postać heksadecymalną potraktował liczbę -2147483648 jako typ LongLong i aby otrzymać prawidłową wartość, musimy przekonwertowanej liczbę z postaci heksadecymalnej na typ LonLong
CLngLng
("&H" & "FFFFFFFF80000000") = -2147483648
Wcześniej pisałem, by ustrzec się błędów podczas konwersji z postaci heksadecymalnej na postać dziesiętną powinniśmy pilnować typów liczb, jakie powinna zwrócić funkcja konwertująca. Jak widać, powinniśmy pilnować także typu liczby poddawanej konwersji na postać heksadecymalną.
' dolna granica zakresu Long = -2 147 483 646
Hex$
(CLng
(-2147483648)) = 80000000
CLng
("&H" & "80000000") = -2147483648
' w wersji skróconej test ma postać:
CLng
("&H" &Hex$
(CLng
(-2147483648))) = -2147483648
' i równość ta jest prawdziwa
Brak komentarzy:
Prześlij komentarz