Convertion d'un double en hexadecimal (IEEE-754)

[Résolu]
Signaler
Messages postés
87
Date d'inscription
jeudi 22 juin 2006
Statut
Membre
Dernière intervention
24 septembre 2007
-
Messages postés
87
Date d'inscription
jeudi 22 juin 2006
Statut
Membre
Dernière intervention
24 septembre 2007
-
Salutation a tous.

Je cherche a convertir un double en notation hexadécimale. J'ai deja essayé pour un float (plus simple car il prend que 32 bits), ce qui me donne le code suivant. :

<hr size="2" width="100%" />typedef union  {

    float f;
    int i;

} num;


int main()

{

    num fp_num;

    char temp[100];


    fp_num.f = 1.5;

    printf("%s\n", itoa(fp_num.i, temp, 16)); // affichage correct en base 16

}
<hr size="2" width="100%" />
Maintenant, je voudrais utiliser le même code mais pour un double. Mais les double font 64 bits (donc plus gros que les ints sur platformes 32 bit), ce qui m'interdit d'utiliser l'union d'un double avec en int. Il y a bien un type __int64 sous VC2005 mais la fonction itoi ne semble pas gérer correctement ce type. Si quelqu'un pouvais m'aider a mon problème, je lui en serais très reconnaissant.

13 réponses

Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
Mais enfin il n'y a rien à reconstruire, le double est en forme binaire, suffit de lire les 2 DWORDs le constituant.

char buf[16];
ultoa(*p, buf, 16);
MessageBox(0, buf, "BAS", 0);
ultoa(*(p + 1), buf, 16);
MessageBox(0, buf, "HAUT", 0);

ciao...
BruNews, MVP VC++
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
double d;
DWORD *p;
p = (DWORD*) &d;

now tu peux y aller avec *p.

ciao...
BruNews, MVP VC++
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
24
Salut,

On peut aussi extraire la partie entiere et la partie fractionnée avec :

doublemodf(doubled, double* pDb);
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
24
Désolé, l'éditeur m'a bouffé quelques espaces.
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
Je doute que ça donnerait la représentation hexa du double.

ciao...
BruNews, MVP VC++
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
24
On reconstruit la représentation après bien sur.
Messages postés
87
Date d'inscription
jeudi 22 juin 2006
Statut
Membre
Dernière intervention
24 septembre 2007

Merci beaucoup pour votre aide, ca a l'air de donner les bonnes valeurs mais les ultoa renvoie une valeure sans les 0 superflus. Est-t-il possible de formatter la chaine renvoyée?

Ex : avec 1.5, la valeure renvoyée est 3FF800000 au lieu de 3FF8000000000000, mais avec 1.35, la valeure est correcrte.
Messages postés
87
Date d'inscription
jeudi 22 juin 2006
Statut
Membre
Dernière intervention
24 septembre 2007

C'est bon, j'ai fini :

double d = 1.5;
DWORD *p;
char buf[16];

p = (DWORD*) &d;

printf("%08X", *(p + 1));
printf("%08X", *p);

Encore une fois, merci !!
Messages postés
87
Date d'inscription
jeudi 22 juin 2006
Statut
Membre
Dernière intervention
24 septembre 2007

On peut enlever le char buf[16]; dans le post précédent ^^
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
Allez juste pour le fun, exe final de 2 Ko !!!


#include <windows.h>
#pragma comment(lib, "msvcrt.lib")
// je rassure, aucune dependance sur msvcrt.dll
// juste pour que compilo ne crie pas en voyant du 'double'.


__declspec(naked) char* __fastcall bnqwordtox(unsigned __int64 inum, char *szdst)
{ // [esp+4] = LOinum, [esp+8] = HIinum, ECX = szdst
  __asm {
    mov     eax, [esp+4]
    add     ecx, 16
    mov     dl, al
    shr     al, 4
    and     dl, 15
    add     al, 48
    add     dl, 48
    cmp     dl, 57
    jbe     short L1
    add     dl, 7
L1:
    cmp     al, 57
    jbe     short L2
    add     al, 7
L2:
    mov     byte ptr[ecx-1], dl
    mov     byte ptr[ecx-2], al
    mov     byte ptr[ecx], 0
    shr     eax, 8
    mov     dl, al
    shr     al, 4
    and     dl, 15
    add     al, 48
    add     dl, 48
    cmp     dl, 57
    jbe     short L3
    add     dl, 7
L3:
    cmp     al, 57
    jbe     short L4
    add     al, 7
L4:
    mov     byte ptr[ecx-3], dl
    mov     byte ptr[ecx-4], al
    shr     eax, 8
    mov     dl, al
    shr     al, 4
    and     dl, 15
    add     al, 48
    add     dl, 48
    cmp     dl, 57
    jbe     short L5
    add     dl, 7
L5:
    cmp     al, 57
    jbe     short L6
    add     al, 7
L6:
    mov     byte ptr[ecx-5], dl
    mov     byte ptr[ecx-6], al
    shr     eax, 8
    mov     dl, al
    shr     al, 4
    and     dl, 15
    add     al, 48
    add     dl, 48
    cmp     dl, 57
    jbe     short L7
    add     dl, 7
L7:
    cmp     al, 57
    jbe     short L8
    add     al, 7
L8:
    mov     byte ptr[ecx-7], dl
    mov     byte ptr[ecx-8], al
    mov     eax, [esp+8]
    mov     dl, al
    shr     al, 4
    and     dl, 15
    add     al, 48
    add     dl, 48
    cmp     dl, 57
    jbe     short L9
    add     dl, 7
L9:
    cmp     al, 57
    jbe     short L10
    add     al, 7
L10:
    mov     byte ptr[ecx-9], dl
    mov     byte ptr[ecx-10], al
    shr     eax, 8
    mov     dl, al
    shr     al, 4
    and     dl, 15
    add     al, 48
    add     dl, 48
    cmp     dl, 57
    jbe     short L11
    add     dl, 7
L11:
    cmp     al, 57
    jbe     short L12
    add     al, 7
L12:
    mov     byte ptr[ecx-11], dl
    mov     byte ptr[ecx-12], al
    shr     eax, 8
    mov     dl, al
    shr     al, 4
    and     dl, 15
    add     al, 48
    add     dl, 48
    cmp     dl, 57
    jbe     short L13
    add     dl, 7
L13:
    cmp     al, 57
    jbe     short L14
    add     al, 7
L14:
    mov     byte ptr[ecx-13], dl
    mov     byte ptr[ecx-14], al
    shr     eax, 8
    mov     dl, al
    shr     al, 4
    and     dl, 15
    add     al, 48
    add     dl, 48
    cmp     dl, 57
    jbe     short L15
    add     dl, 7
L15:
    cmp     al, 57
    jbe     short L16
    add     al, 7
L16:
    mov     byte ptr[ecx-15], dl
    mov     byte ptr[ecx-16], al
    shr     eax, 8
    mov     dl, al
    shr     al, 4
    and     dl, 15
    add     al, 48
    add     dl, 48
    cmp     dl, 57
    jbe     short L17
    add     dl, 7
L17:
    cmp     al, 57
    jbe     short L18
    add     al, 7
L18:
    mov     byte ptr[ecx-17], al
    mov     byte ptr[ecx-18], dl
    mov     eax, ecx
    ret     8
  }
}


void __stdcall bnTestDblToHex()
{
  double d = 1.5;
  char buf[32];
  bnqwordtox(*((unsigned __int64 *) &d), buf);
  MessageBox(0, buf, "hex", 0);
 
}




#pragma comment(linker, "/entry:myWinMain")
__declspec(naked) void __stdcall myWinMain()
{
  __asm {
    call    bnTestDblToHex
    push    0
    call    dword ptr ExitProcess
  }
}

ciao...
BruNews, MVP VC++
Messages postés
87
Date d'inscription
jeudi 22 juin 2006
Statut
Membre
Dernière intervention
24 septembre 2007

Voila, en C ainsi :

    double d = nombre_a_virgule;
    unsigned int *p;
    p = (unsigned int*) &d;

    printf("Representation hexa IEEE-754 64 bit : %08x%08x ;1.5", *(p + 1), *p);
Messages postés
87
Date d'inscription
jeudi 22 juin 2006
Statut
Membre
Dernière intervention
24 septembre 2007

Merci pour l'asm, je vais étudier ca de plus près. Ca a l'air interessant ^^.
Messages postés
87
Date d'inscription
jeudi 22 juin 2006
Statut
Membre
Dernière intervention
24 septembre 2007

Bon ba tout compte fais, il faut quand même utiliser des DWORD dans le code 2 post avant. Mais de toute facon, je pourrais faire sans pour mon projet ^^.