Jeg snublet på dette SO spørsmålet som spurte om en måte for å konvertere større hexverdier til en positiv numerisk verdi:

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

Svaret mitt innebar å itere strengsifrene en etter en, og beregne deres respektive verdi til resultatet:

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 

Det fungerer, men jeg kan » Jeg kan ikke tenke på at jeg har gjort noe dumt for komplisert for noe som skal være ganske enkelt.

Det er en bedre måte, er det ikke?

Kommentarer

  • Jeg ' er forvirret med hensyn til hva du vil oppnå. " Dobbelt " betyr vanligvis et 64-bit flytende nummer. Teksten din sier at du vil ha en " positiv numerisk verdi ", men eksemplene dine ser ut til å vise signert 16-biters heltall (vanligvis kalt " kort "). Videre ser det ut til at bare hele tall muligens kan være representert i hexstrengen, så returtypen skal være Short, Integer, Long, UShort, UInteger, ULong, eller Decimal.
  • @ 200_success Det ' er bare et veldig begrenset sett med datatyper i VBA. Ingen usignerte typer …
  • Mat, hva ' er galt med Cdbl("&HFFFF")?
  • @Meehow se oppdateringen til svaret mitt for hvorfor jeg tror CDbl er feil i dette scenariet.
  • @Meehow det er nøyaktig hva jeg mente med " Jeg ' har gjort noe dumt over-komplisert for noe som skal være ganske enkelt " 😉

Svar

Fra det jeg kan fortelle en streng som begynner med &H er en hekseliteral.

Det finnes et antall konverteringsfunksjoner som kan konvertere et uttrykk til ønsket type.

Så det skal rett og slett være, avhengig av ønsket 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 dobbel

Maksimalt nøyaktig representativt positivt heltall:

Så hvorfor bruke Currency over Double når sistnevnte fungerer for et større utvalg av heltall?

Currency er alltid nøyaktig. Hvis vi overløper en Currency -verdi, får vi en feil. Hvis vi overløper den maksimale representable heltallverdien til en dobbel, får vi en omtrentlig heltallverdi:

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

Resultatet av dette eksemplet er:

 Double before: 9007199254740990 after: 9007199254740990  

Og så en run-time error "6": Overflow som er flott hvis du ønsker å unngå avrundingsfeil. Nå hevder MSDN at Double er

lagret som IEEE 64-biters (8-byte) flytnummer

men hvis du har lest noe om IEEE 754 binary64 , bør du være litt overrasket over resultatet fra eksemplet. Det faktiske maksimumet er &H00038D7EA4C68000 (1.000.000.000.000.000.000).

Kommentarer

  • Kjempebra! Jeg ' har koblet til dette svaret på en redigering av mitt SO-svar 🙂
  • Jeg utvidet litt om Currency vs Double litt og oppdaget noe interessant.
  • hva med doubleMax + doubleMax å kaste et overflow error?
  • @Meehow Bare testet den og tilsynelatende overløper Double i VBA. Men den ' er fortsatt ikke mulig å løpe over hvis det analyserte resultatet er et heltall. Jeg ' er glad for at jeg ikke ' t må jobbe med det språket.
  • Den riktige, idiomatiske måten å gjøre dette på er å bruke en av de innebygde konverteringsfunksjonene, som @Meehow kommenterte OP – Jeg vet ikke ' hva brainfart fikk meg til å skrive denne funksjonen …

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *