Natknąłem się na to pytanie SO , które pytało o sposób aby przekonwertować większe wartości szesnastkowe na dodatnią wartość liczbową:

?Val("&H8000") -32768 Val("&HFFFF") -1 

Moja odpowiedź polegała na iterowaniu kolejnych cyfr w ciągu i przeliczaniu ich wartości na wynik:

Function ConvertHex(ByVal value As String) As Double If Left(value, 2) = "&H" Then value = Right(value, Len(value) - 2) End If Dim result As Double Dim i As Integer, j As Integer For i = Len(value) To 1 Step -1 Dim digit As String digit = Mid$(value, i, 1) result = result + (16 ^ j) * Val("&H" & digit) j = j + 1 Next ConvertHex = result End Function 

Działa, ale mogę ” nie pomyśleć, że zrobiłem coś głupio zbyt skomplikowanego dla czegoś, co powinno być całkiem proste.

Jest lepszy sposób, prawda?

Komentarze

  • Nie ' nie wiem, co chcesz osiągnąć. " Podwójne " zwykle oznacza 64-bitową liczbę zmiennoprzecinkową. Jednak w Twoim tekście jest napisane, że chcesz " dodatnią wartość liczbową ", ale w przykładach wydaje się, że podpisane 16-bitowe liczby całkowite (zwykle nazywane " krótkimi "). Ponadto wydaje się, że w ciągu szesnastkowym można przedstawić tylko liczby całkowite, więc typem zwracanym powinien być Short, Integer, Long, UShort, UInteger, ULong lub Decimal.
  • @ 200_success. ' to tylko bardzo ograniczony zestaw typy danych w VBA. Brak typów bez znaku …
  • Mat, co ' jest nie tak z Cdbl("&HFFFF")?
  • @Meehow zobacz aktualizację mojej odpowiedzi, dlaczego uważam, że CDbl jest błędne w tym scenariuszu.
  • @Meehow to jest dokładnie co miałem na myśli, mówiąc o " ' zrobiłem coś głupio zbyt skomplikowanego w przypadku czegoś, co powinno być całkiem proste " 😉

Odpowiedź

Z tego, co mogę powiedzieć, że ciąg znaków zaczynający się od &H to literał szesnastkowy.

Istnieje liczba funkcji konwersji , które mogą konwertować wyrażenie na żądany typ.

Więc powinno być po prostu, w zależności od pożądanego typu:

Function ConvertHex(ByVal value As String) As Currency Dim result As Currency result = CCur(value) If result < 0 Then "Add two times Int32.MaxValue and another 2 for the overflow "Because the hex value is apparently parsed as a signed Int64/Int32 result = result + &H7FFFFFFF + &H7FFFFFFF + 2 End If ConvertHex = result End Function 

Waluta a podwójna

Maksymalna dokładna dodatnia liczba całkowita:

Po co więc używać Currency zamiast Double, kiedy to drugie działa dla większego zakresu liczb całkowitych?

jest zawsze dokładne. Jeśli przepełnimy wartość Currency, otrzymamy błąd. Jeśli przepełnimy maksymalną możliwą do reprezentacji wartość całkowitą podwójną, otrzymamy przybliżoną wartość całkowitą:

Dim doubleMax As Double Dim doubleAfter As Double doubleMax = CDbl("&H0020000000000000") doubleAfter = doubleMax + 1 MsgBox "Double before: " & Format(doubleMax, "#") & vbNewLine & "after: " & Format(doubleAfter, "#") Dim currencyMax As Currency Dim currencyAfter As Currency currencyMax = CCur("&H000346DC5D638865") currencyAfter = currencyMax + 1 MsgBox "Currency before: " & Format(currencyMax, "#") & vbNewLine & "after: " & Format(currencyAfter, "#") 

Wynik tego przykładu to:

 Double before: 9007199254740990 after: 9007199254740990  

A następnie run-time error "6": Overflow, co jest świetne, jeśli chcą uniknąć błędów zaokrągleń. Teraz oświadczenia MSDN Double

przechowywane jako 64-bitowa (8-bajtowa) liczba zmiennoprzecinkowa IEEE

ale jeśli czytałeś cokolwiek o IEEE 754 binary64 , powinieneś nieco zaskoczony wynikiem z przykładu. Rzeczywiste maksimum to &H00038D7EA4C68000 (1 000 000 000 000 000).

Komentarze

  • Świetnie! ' połączyłem się z tą odpowiedzią podczas edycji mojej odpowiedzi SO 🙂
  • Rozwinąłem trochę o Currency vs Double trochę i odkryłem coś interesującego.
  • co powiesz na doubleMax + doubleMax rzucenie błąd przepełnienia?
  • @Meehow Właśnie go przetestowałem i najwyraźniej Double w VBA powoduje przepełnienie. Ale ' s nadal nie można przepełnić, jeśli przetworzony wynik jest liczbą całkowitą. ' cieszę się, że nie ' nie muszę pracować z tym językiem.
  • Prawidłowym, idiomatycznym sposobem na to jest użycie jednej z wbudowanych funkcji konwersji, jak @Meehow skomentował OP – Nie ' nie wiem, co spowodowało bicie mózgu, że napisałem tę funkcję …

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *