Convertir hexa vers double

Bonjour à toutes et tous,

J'ai un soucis, j'ai une chaîne de caractère dans ce style la : "C056600000000000" en hexa, et je souhaiterai la convertir en double et donc qu'elle me retourne -89.5.

Sauf que je n'ai pas trouvé de fonction pour le faire, et je ne sais pas du tout comment faire.

Merci d'avance de votre aide.
Cordialement.
Zapsalis

Bonjour

Il me semble qu'il y a un problème

"C056600000000000" en hexa

(C056600000000000)₁₆ = (12 × 16¹⁵) + (0 × 16¹⁴) + (5 × 16¹³) + (6 × 16¹²) + (6 × 16¹¹) + (0 × 16¹⁰) + (0 × 16⁹) + (0 × 16⁸) + (0 × 16⁷) + (0 × 16⁶) + (0 × 16⁵) + (0 × 16⁴) + (0 × 16³) + (0 × 16²) + (0 × 16¹) + (0 × 16⁰) = (13859370456395546624)₁₀

bonjour, convertir vers un integer ou long, oui, mais vers un double = 89.5 ????

si c'est négatif = complément +1

Bonjour,

Oui C056600000000000 converti en double correspond à -89.5.
Comme vous pouvez le voir sur le screen joint.

image

Cordialement.
Zapsalis

Bonjour,

à mon avis change de site, il est débordé là.
Hexa en décimal ne peut donner qu'un entier, et là ça ne peut être qu'un très gros nombre, bien loin de -89
eric

Edit :yal_excel. C=1100 en binaire.
Si c'est signé le premier 1 est le bit de signe et ne doit pas compter dans le nombre.
Maintenant, signé ou pas, c'est l'utilisateur qui décide

Bonjour,

"C056600000000000" n'est que la représentation hexadécimale du format "Double" de 64 bits, se décomposant comme suit :

- premier bit pour le signe

- 11 bits suivants pour l'exposant

- 52 bits pour la mantisse

Pour notre cas, la composition des bits est donc la suivante :

capture d ecran 2022 11 05 120637

Le calcul est donc le suivant :

1- signe =1 : - (signe =0 :+)

2- exposant = 1024 +4+1 = 1029

3- mantisse = 2-2+2-3+2-6+2-7

4- nombre = 2exposant-1023 x (1+mantisse) = 26 x (1 + 0,4) = 89,5

5- nombre signé = -89,5

Bonjour thev,

mantisse+exposant, ce que tu nous présentes là c'est la représentation d'un nombre flottant (décimal).
Fort possible que ce soit ça mais ce n'est plus de l'hexa. Le demandeur devait être perdu
eric

Bonjour Eriiic,

Le nombre de bits est bien 64 : signe(1bit) + exposant (11bits) + mantisse (52 bits)

Le type de données "Double" contient des nombres à virgule flottante à double précision signés IEEE 64 bits.

Le calcul IEEE 64 bits correspondant à la représentation hexadécimale redonne bien : - 89,5

Bonjour Zapsalis, Le Fil,

image

Le demandeur devait être perdu

Pour qu'il ne le soit pas, le site: Double(IEEE754...

Il suffit de placer en fin la valeur "Hexa" pour obtenir la conversion en double.

Bonjour,

en VBA

Debug.print val("&H" & "C056600000000000")

bonjour,

voici une fonction de conversion d'une chaîne hexadécimale en nombre décimal en virgule flottante selon la norme IEEE 754 (norme expliquée par Thev)

Function converthex2dbl(hex As String)
    Dim a As Byte, n As Double
    If Len(hex) <> 16 Then converthex2dbl = CVErr(1): Exit Function
    For i = 0 To 7
        a = "&H" & Mid(hex, i * 2 + 1, 2)
        s = s & Right("00000000" & Application.Dec2Bin(a), 8)
    Next
    signe = Left(s, 1)
    exposant = Mid(s, 2, 11)
    mantisse = Right(s, 52)
    For i = 1 To 11
        If Mid(exposant, i, 1) = "1" Then e = e + 2 ^ (11 - i)
    Next i
    For i = 1 To 52
        If Mid(mantisse, i, 1) = "1" Then m = m + 2 ^ (-i)
    Next i
    n = 2 ^ (e - 1023) * (1 + m) * IIf(signe = "1", -1, 1)
    converthex2dbl = n
End Function

Sub test()
    MsgBox converthex2dbl("C056600000000000")
End Sub

une autre méthode en passant par un fichier pour forcer VBA à interpréter les 64 bits comme étant un nombre en double précision

Function cvthex2dbl(hex As String)
    Dim n As String * 8
    Dim d As Double
    For i = 0 To 7
        s = Chr("&h" & Mid(hex, i * 2 + 1, 2)) & s
    Next i
    n = s
    Open "fichiercvt.bin" For Random As 1 Len = 8
    Put #1, 1, n
    Get #1, 1, d
    Close 1
    cvthex2dbl = d
End Function

Sub test()
    MsgBox cvthex2dbl("C056600000000000")
End Sub

Bonjour,

Je ne pense pas qu'il existe de fonction standard. J'ajouterai à la contribution de h2so4, la fonction que j'ai développée :

Function convert_to_double(hexa As String) As Double
    Dim i As Integer, j As Integer
    Dim tb_demi_octets()
    Dim signe As String, exposant As String, signe_exposant As String
    Dim valeur_exposant As Long, valeur_mantisse As Double

    '// transformation de hexa en binaire des demi_octets
    For i = 1 To Len(hexa)
        ReDim Preserve tb_demi_octets(i): tb_demi_octets(i) = Application.Hex2Bin(Mid(hexa, i, 1), 4)
    Next i

    '// détermination signe, mantisse, exposant
    For i = 1 To UBound(tb_demi_octets)
        If Not i > 3 Then signe_exposant = signe_exposant & tb_demi_octets(i) _
        Else mantisse = mantisse & tb_demi_octets(i)
    Next i
    signe = Left(signe_exposant, 1): exposant = Mid(signe_exposant, 2, 11)

    '// calcul du nombre

    'valeur de l'exposant
    valeur_exposant = 0: j = 0
    For i = Len(exposant) To 1 Step -1
        valeur_exposant = valeur_exposant + Mid(exposant, i, 1) * 2 ^ j
        j = j + 1
    Next i

    'valeur de la mantisse
    valeur_mantisse = 0
    For i = 1 To Len(mantisse)
        valeur_mantisse = valeur_mantisse + Mid(mantisse, i, 1) * 2 ^ -i
    Next i

    'détermination nombre
    convert_to_double = 2 ^ (valeur_exposant - 1023) * (1 + valeur_mantisse)
    convert_to_double = IIf(signe = "1", convert_to_double * -1, convert_to_double)

End Function

:

Bonjour,

Merci à tous pour vos réponses et vos contributions.

Désolé de ma réponse tardive, je n'avais malheureusement pas eu le temps de me replonger dedans.
Néanmoins ce matin, j'ai finalement réussi à convertir un hexa de 64 bits en double.

Voilà comment j'ai fait :

J'ai converti mon hexa en binaire, et ensuite j'ai décodé en fonction de l'exposant et du mantisse.

Voici mon code :

Function HEX2DOUBLE(strHex As String) As Double

    Dim strBin As String
    Dim result As Double

    strBin = HEX2BIN(strHex)
    result = BIN2DOUBLE(strBin)

    HEX2DOUBLE = result

End Function

Function BIN2DOUBLE(strBin As String) As Double

    Dim signe As Integer
    Dim exponent As Integer
    Dim i As Integer
    Dim result As Double

    If Left(strBin, 1) = 0 Then
        signe = 1
    Else
        signe = -1
    End If

    exponent = BIN2DEC(Mid(strBin, 2, 11)) - 1023

    strBin = Mid(strBin, 13, Len(strBin) - 12)
    strBin = "1" & strBin

    If exponent >= 1 Then

        For i = 0 To Len(strBin)

            If Mid(strBin, i + 1, 1) = 1 Then

                result = result + 2 ^ (exponent - i)

            End If

        Next

    Else

        For i = 0 To exponent * -1
            strBin = "0" & strBin
        Next

        For i = 0 To Len(strBin)

            If Mid(strBin, i, 1) = 1 Then

                result = result + 2 ^ (0 - i)

            End If

        Next

    End If

    BIN2DOUBLE = result * signe

End Function

Public Function HEX2BIN(strHex As String) As String
    Dim c As Long, i As Long, b As String * 4, j As Long
    For c = 1 To Len(strHex)
        b = "0000"
        j = 0
        i = Val("&H" & Mid$(strHex, c, 1))
        While i > 0
            Mid$(b, 4 - j, 1) = i Mod 2
            i = i \ 2
            j = j + 1
        Wend
        HEX2BIN = HEX2BIN & b
    Next
    HEX2BIN = RTrim$(HEX2BIN)
End Function

Function BIN2DEC(sMyBin As String) As Long

    Dim x As Integer
    Dim iLen As Integer

    iLen = Len(sMyBin) - 1
    For x = 0 To iLen
        BIN2DEC = BIN2DEC + _
          Mid(sMyBin, iLen - x + 1, 1) * 2 ^ x
    Next
End Function

Il y avait surement plus rapide et plus facile, mais cela fonctionne très bien pour moi, et est assez rapide à s'exécuter.

Encore merci pour vos réponses.

Cordialement,
Zapsalis

Rechercher des sujets similaires à "convertir hexa double"