Ich bin auf dieser SO-Frage gestoßen, die nach einem Weg fragte So konvertieren Sie größere Hex-Werte in einen positiven numerischen Wert:
?Val("&H8000") -32768 Val("&HFFFF") -1
Meine Antwort bestand darin, die Zeichenfolgen nacheinander zu wiederholen und ihren jeweiligen Wert in das Ergebnis zu berechnen:
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
Es funktioniert, aber ich kann “ Ich glaube nicht, dass ich etwas Dummes getan habe, das für etwas, das ziemlich einfach sein sollte, überkompliziert ist.
Es gibt einen besseren Weg, nicht wahr?
Kommentare
- Ich ' bin verwirrt darüber, was Sie erreichen möchten. " Double " bedeutet normalerweise eine 64-Bit-Gleitkommazahl. Ihr Text besagt jedoch, dass Sie einen " positiven numerischen Wert " wünschen, aber dann scheinen Ihre Beispiele signiert 16-Bit-Ganzzahlen (normalerweise als " short " bezeichnet). Darüber hinaus scheint es, dass möglicherweise nur ganze Zahlen in der Hex-Zeichenfolge dargestellt werden könnten, sodass der Rückgabetyp
Short
,Integer
sein sollte.Long
,UShort
,UInteger
,ULong
oderDecimal
. - @ 200_success ' gibt es nur eine sehr begrenzte Menge von Datentypen in VBA. Keine vorzeichenlosen Typen …
- Mat, was ' ist falsch an
Cdbl("&HFFFF")
? - @Meehow siehe das Update zu meiner Antwort, warum ich denke, dass
CDbl
für dieses Szenario falsch ist. - @Meehow das ist genau Was ich mit " gemeint habe Ich ' habe etwas dumm überkompliziertes für etwas getan, das ziemlich einfach sein sollte " 😉
Antwort
Nach allem, was ich einem String sagen kann, der mit &H
ist ein Hex-Literal.
Es gibt eine Anzahl von Konvertierungsfunktionen , die einen Ausdruck konvertieren können auf den gewünschten Typ.
So sollte es einfach sein, abhängig vom gewünschten Typ:
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
Währung gegen Doppel
Maximal genau darstellbarer positiver ganzzahliger Wert:
-
&H0020000000000000
(9.007.199.254.740.992) für Double ( IEEE 754 binary64 ) -
&H000346DC5D638865
(922.337.203.685.477) für Währung
Warum also Currency
über Double
verwenden, wenn letzteres für einen größeren Bereich von Ganzzahlen funktioniert?
Currency
ist immer genau. Wenn wir einen Currency
-Wert überlaufen, wird ein Fehler angezeigt. Wenn wir den maximal darstellbaren Ganzzahlwert eines Double überlaufen, erhalten wir einen ungefähren Ganzzahlwert:
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, "#")
Die Ausgabe dieses Beispiels lautet:
Double before: 9007199254740990 after: 9007199254740990
Und dann eine run-time error "6": Overflow
, die großartig ist, wenn Sie Rundungsfehler vermeiden wollen. Jetzt behauptet MSDN, dass Double
als IEEE 64-Bit-Gleitkommazahl (8 Byte) gespeichert ist
aber wenn Sie etwas über die IEEE 754 binary64 gelesen haben, sollten Sie es sein Ein bisschen überrascht über die Ausgabe des Beispiels. Das tatsächliche Maximum ist &H00038D7EA4C68000
(1.000.000.000.000.000).
Kommentare
- Super! Ich ' habe bei einer Bearbeitung meiner SO-Antwort auf diese Antwort verlinkt 🙂
- Ich habe das Bit über vs
Double
ein wenig und entdeckte etwas Interessantes. - wie wäre es mit
doubleMax + doubleMax
werfen eines Überlauffehler? - @Meehow Gerade getestet und anscheinend
Double
in VBA läuft über. Aber es ' ist immer noch Überlauf nicht möglich, wenn das analysierte Ergebnis eine Ganzzahl ist. Ich ' bin froh, dass ich nicht ' muss nicht mit dieser Sprache arbeiten. - Die richtige, idiomatische Methode hierfür ist die Verwendung einer der integrierten Konvertierungsfunktionen, wie @Meehow das OP kommentiert hat – Ich weiß nicht, ', warum Brainfart mich veranlasst hat, diese Funktion überhaupt zu schreiben …