Belebotlottam e SO kérdésbe, amely egy utat kérdezett nagyobb hexadecimális értékek pozitív számértékre konvertálása:

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

Válaszomban a karakterlánc számjegyeinek egyenkénti iterálását és a megfelelő érték kiszámítását eredményeztem:

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 

Működik, de tudom ” Nem segít abban, hogy azt gondoljam, valami hülyén túl bonyolult dolgot tettem valamiért, aminek elég egyszerűnek kell lennie.

Van jobb módszer, nincs?

Megjegyzések

Válasz

Abból, amit meg tudok mondani egy karakterláncról, amelynek kezdete &H egy hexa betűs szó.

Létezik egy számú konverziós függvény , amely képes átalakítani egy kifejezést a kívánt típusra.

Tehát egyszerűen annak kell lennie, a kívánt típustól függően:

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 

Pénznem vs dupla

Maximálisan pontosan ábrázolható pozitív egész érték:

Akkor miért használja a Currency -t a Double fölött, ha ez utóbbi az egész szám nagyobb tartományában működik?

Currency mindig pontos. Ha túlcsordulunk egy Currency értéket, hibát kapunk. Ha túllépjük a duplája maximálisan reprezentálható egész értékét, hozzávetőleges egész értéket kapunk:

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

A példa kimenete:

 Double before: 9007199254740990 after: 9007199254740990  

És akkor egy run-time error "6": Overflow, ami nagyon jó, ha el akarják kerülni a kerekítési hibákat. Az MSDN azt állítja, hogy a Double

IEEE 64 bites (8 bájtos) lebegőpontos számként van tárolva

de ha valamit olvasott az IEEE 754 bináris64 fájlról, akkor kissé meglepődött a példa kimenetén. A tényleges maximum &H00038D7EA4C68000 (1 000 000 000 000 000).

Megjegyzések

  • Félelmetes! Én ' összekapcsoltam ezt a választ egy SO válaszom szerkesztésénél 🙂
  • kibővítettem a következőt: Currency vs Double egy kicsit, és valami érdekeset fedezett fel.
  • hogy doubleMax + doubleMax túlcsordulási hiba?
  • @ Valahogy csak teszteltem, és látszólag a VBA Double túlcsordul. De ' még mindig nem lehet túlcsordulni, ha az elemzett eredmény egész szám. I ' örülök, hogy nem ' nem kell dolgoznia az adott nyelvvel.
  • Ennek helyes, idiomatikus módja a beépített konverziós függvények egyikének használata, amint a @Meoud módon kommentálta az OP-t – Nem tudom, hogy ' nem tudom, mi okozott egy ötletet arra, hogy meg is írjam ezt a funkciót …

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük