Je suis tombé sur cette question SO qui demandait un moyen pour convertir des valeurs hexadécimales plus grandes en une valeur numérique positive:

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

Ma réponse impliquait ditérer les chiffres de la chaîne un par un, et de calculer leur valeur respective dans le résultat:

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 

Cela fonctionne, mais je peux  » t aide à penser que jai fait quelque chose de stupidement trop compliqué pour quelque chose qui devrait être assez simple.

Il ya « une meilleure façon, nest-ce pas?

Commentaires

  • Je ' ne sait pas ce que vous voulez accomplir. " Double " signifie généralement un nombre à virgule flottante de 64 bits. Pourtant, votre texte indique que vous voulez une " valeur numérique positive ", mais vos exemples semblent indiquer signé Entiers 16 bits (généralement appelés " short "). De plus, il semblerait que seuls des nombres entiers puissent éventuellement être représentés dans la chaîne hexadécimale, donc le type de retour doit être Short, Integer, Long, UShort, UInteger, ULong, ou Decimal.
  • @ 200_success Il ' nest quun ensemble très limité de types de données dans VBA. Aucun type non signé …
  • Mat, quel est le problème de ' avec Cdbl("&HFFFF")?
  • @Meehow voir la mise à jour de ma réponse pour savoir pourquoi je pense que CDbl est faux pour ce scénario.
  • @Meehow cest exactement ce que je voulais dire par " Jai ' fait quelque chose de stupidement trop compliqué pour quelque chose qui devrait être assez simple " 😉

Réponse

Daprès ce que je peux dire, une chaîne commençant par &H est un littéral hexadécimal.

Il existe un nombre de fonctions de conversion qui peuvent convertir une expression au type souhaité.

Il devrait donc être simplement, selon le type souhaité:

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 

Devise vs Double

Valeur entière positive maximale représentable avec précision:

Alors pourquoi utiliser Currency sur Double alors que ce dernier fonctionne pour une plus grande plage dentiers?

Currency est toujours précis. Si nous dépassons une valeur de Currency, nous obtenons une erreur. Si nous dépassons la valeur entière maximale représentable dun double, nous obtenons une valeur entière approximative:

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

Le résultat de cet exemple est:

 Double before: 9007199254740990 after: 9007199254740990  

Et puis un run-time error "6": Overflow qui est génial si vous veulent éviter les erreurs darrondi. Maintenant, MSDN affirme que Double est

stocké sous forme de nombre à virgule flottante IEEE 64 bits (8 octets)

mais si vous « avez lu quelque chose sur le IEEE 754 binary64 , vous devriez être un peu surpris par le résultat de lexemple. Le maximum réel est &H00038D7EA4C68000 (1 000 000 000 000 000).

Commentaires

  • Génial! Jai ' lié à cette réponse sur une modification de ma réponse SO 🙂
  • Jai développé le bit sur Currency vs Double un peu et jai découvert quelque chose dintéressant.
  • que diriez-vous de doubleMax + doubleMax jeter un erreur de débordement?
  • @Meehow Je viens de le tester et apparemment Double dans VBA déborde. Mais il ' est toujours pas possible de déborder si le résultat analysé est un entier. Je ' je suis content de ne pas ' Je nai pas besoin de travailler avec cette langue.
  • La façon idiomatique correcte de le faire est dutiliser lune des fonctions de conversion intégrées, comme @Meehow la commenté sur lOP – Je ne ' ne sais pas quel brainfart ma poussé à écrire cette fonction …

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *