Ik kwam deze SO-vraag tegen die vroeg over een manier om grotere hexadecimale waarden om te zetten in een positieve numerieke waarde:

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

Mijn antwoord betrof het een voor een itereren van de tekenreekscijfers en het berekenen van hun respectieve waarde in het resultaat:

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 

Het werkt, maar ik kan ” Ik denk niet dat ik “iets stompzinnigs te ingewikkelds heb gedaan voor iets dat vrij eenvoudig zou moeten zijn.

Er is een betere manier, nietwaar?

Opmerkingen

  • Ik ' ben in de war over wat je wilt bereiken. " Dubbel " betekent gewoonlijk een 64-bits drijvende-kommagetal. Toch zegt uw tekst dat u een " positieve numerieke waarde " wilt, maar dan lijken uw voorbeelden ondertekend 16-bits gehele getallen (meestal een " korte " genoemd). Bovendien lijkt het erop dat mogelijk alleen hele getallen kunnen worden weergegeven in de hexadecimale reeks, dus het retourtype moet Short, Integer zijn, Long, UShort, UInteger, ULong, of Decimal.
  • @ 200_success Daar ' is slechts een zeer beperkte set van gegevenstypen in VBA. Geen niet-ondertekende typen …
  • Mat, wat is er ' mis met Cdbl("&HFFFF")?
  • @Meehow bekijk de update van mijn antwoord waarom ik denk dat CDbl verkeerd is voor dit scenario.
  • @Meehow dat is precies wat ik bedoelde met " Ik ' heb iets stompzinnigs te ingewikkelds gedaan voor iets dat vrij simpel zou moeten zijn " 😉

Antwoord

Van wat ik kan zien aan een string die begint met &H is een hexadecimale letter.

Er bestaat een aantal conversiefuncties die een uitdrukking kunnen converteren naar het gewenste type.

Dus het zou eenvoudig moeten zijn, afhankelijk van het gewenste type:

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 

Valuta versus dubbel

Maximaal nauwkeurig representeerbare positieve gehele waarde:

Dus waarom zou je Currency boven Double gebruiken als de laatste werkt voor een groter bereik van gehele getallen?

Currency is altijd nauwkeurig. Als we een Currency -waarde overschrijden, krijgen we een foutmelding. Als we de maximaal representeerbare integerwaarde van een dubbel overschrijden, krijgen we een geschatte integerwaarde:

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, "#") 

De output van dit voorbeeld is:

 Double before: 9007199254740990 after: 9007199254740990  

En dan een run-time error "6": Overflow wat geweldig is als je afrondingsfouten willen voorkomen. Nu claimt MSDN Double is

opgeslagen als IEEE 64-bit (8-byte) drijvende-kommagetal

maar als je “iets hebt gelezen over de IEEE 754 binary64 , zou je dat moeten zijn een beetje verbaasd over de uitvoer van het voorbeeld. Het werkelijke maximum is &H00038D7EA4C68000 (1.000.000.000.000.000).

Opmerkingen

  • Geweldig! Ik ' heb naar dit antwoord gelinkt bij een bewerking van mijn SO-antwoord 🙂
  • Ik heb het stukje over vs Double een beetje en ontdekte iets interessants.
  • wat dacht je van doubleMax + doubleMax het gooien van een overloopfout?
  • @Meehow Net getest en blijkbaar loopt Double in VBA over. Maar het ' is nog steeds kan niet worden overschreden als het ontlede resultaat een geheel getal is. Ik ' ben blij dat ik niet ' hoeft niet met die taal te werken.
  • De juiste, idiomatische manier om dit te doen is door een van de ingebouwde conversiefuncties te gebruiken, zoals @Meehow opmerkte op het OP – Ik weet niet ' welke hersenscheurt me ertoe bracht om deze functie zelfs maar te schrijven …

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *