Binaire vers nombre long

Résolu
cybercool33 Messages postés 19 Date d'inscription jeudi 12 septembre 2002 Statut Membre Dernière intervention 7 janvier 2009 - 24 nov. 2006 à 15:28
TMONOD Messages postés 256 Date d'inscription mardi 25 novembre 2003 Statut Membre Dernière intervention 6 novembre 2009 - 27 nov. 2006 à 14:11
Bonjour,

Je suis en train de décrypter un fichier binaire. J'essai de recupérer un nombre codé sur 10 octets.
Je pense que le stockage de ce nombre est réalisé avec une mantisse de 64 bits, mais j'en suis pas sur.

Voilà trois valeurs stockés en hexa:
4005 F6E9 78D4 FDF3 C000=123.456
4005 F6E9 FBE7 6C8B 5000=123.457
4005 F6EA 7EF9 DB22 E000=123.458

Quelqu'un aurait un algorithme me permettant de décrypter ces nombres svp?

Merci
Cybercool

12 réponses

cybercool33 Messages postés 19 Date d'inscription jeudi 12 septembre 2002 Statut Membre Dernière intervention 7 janvier 2009
27 nov. 2006 à 10:35
Finalement j'ai compris comment on decodait ces nombres donc je le note ici ca peut servir pour d'autre personnes

Prenons l'exemple du chiffre 3, c'est codé en hexa de la manière suivante
40 00 C0 00 00 00 00 00 00 00

Il faut tout d'abord récuperer le signe. C'est le premier bit.
40= 0100 0000 donc le premier bit c'est 0
-1^S => -1^0 =1   => Signe=1

Ensuite il faut déterminer l'exposant
C'est les 15 bits qui suivent le bit de signe
40 00 => 16384

Ensuite il faut récupérer la mantisse
C'est les 64 bits qui suivent l'exposant
C0 00 00 00 00 00 00 00
Le premier bit represente l'entier de la mantisse
C0 => 1100 0000
La partie entière de la mantisse 1.
Ensuite pour chaque bit qui précedent il faut faire la somme 2^(-1 * Numero du bit) dans notre cas on a que le premier qui est a 1 donc 2^(-1)=0.5
Notre mantisse est donc egale a 1.5

Maintenant nous disposons de tout ce qu'il nous faut pour calculer le nombre:
(-1)^S * (M) * (2^(E-16383))
S=1
M=1.5
E=16384

> 1*1.5*2 > 3

Et voilà
Merci pour votre aide

A+
Cybercool
3
drikce06 Messages postés 2237 Date d'inscription lundi 29 mai 2006 Statut Membre Dernière intervention 29 mai 2008 11
24 nov. 2006 à 15:43
0
cybercool33 Messages postés 19 Date d'inscription jeudi 12 septembre 2002 Statut Membre Dernière intervention 7 janvier 2009
24 nov. 2006 à 16:27
Non je ne trouve pas mon bonheur dans ces sources.

Ces sources donnent le moyen de transcrire de l'hexa vers de l'entier.
J'ai besoin de transcrire de l'hexa en nombres flottant (a virgule^^) stockées sur 10 octets .

Cybercool33
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 41
24 nov. 2006 à 16:32
Es-tu certain que tes nombres sont codés sur 10 octets?

Normalement un nombre à virgule flotante c'est 32bits pour le single et 64bits pour le double soit respectivement 4 et 8 octets.
 Regarde du coté de la norme IEEE754

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
TMONOD Messages postés 256 Date d'inscription mardi 25 novembre 2003 Statut Membre Dernière intervention 6 novembre 2009 1
24 nov. 2006 à 16:33
Bonjour,

Sur Codeproject, un article récent sur la manipulation des trés grands nombres, en anglais (malheuresement) si tu n'y est pas trop allergique :
http://www.codeproject.com/useritems/BN.asp

Jcbé[^]
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 41
24 nov. 2006 à 16:50
Il existe bien des nombres à virgule flottantes de 80bits --> http://fr.wikipedia.org/wiki/Virgule_flottante

J'aurais appris quelque chose aujourd'hui.

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
0
cybercool33 Messages postés 19 Date d'inscription jeudi 12 septembre 2002 Statut Membre Dernière intervention 7 janvier 2009
24 nov. 2006 à 17:05
Oui Casy mes nombres sont stockées sur 10 Octets.

Jcbé, Le site parle des problèmes de calcul sur des grands nombres. Moi je veux juste décoder les nombres binaires qui sont stockées dans un fichier.

Casy, ton dernier lien est vraiment interessant cependant avec la formule :
Grande précision, 80 bits, 1 bit, 15 bits, 64 bits,
Je n'arrive pas a retrouver ma valeur.
Exemple:
4005 F6E9 78D4 FDF3 C000=123.456
Comment connaitre la valeur de mon signe, ma mantisse et mon exposant?

Merci
Cybercool
0
BruNews Messages postés 21041 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 20
24 nov. 2006 à 17:49
Ce genre de conversion me semble totalement hors de portée de tout langage interprété.

A simple fin didactique (sait-on jamais), je viens de te l'écrire.
Tu pourras passer les 2 fonctions dans une DLL qui exportera un appel HexaTenToDbl().

#include <windows.h>
#include <stdio.h>

__declspec(naked) DWORD __fastcall HexaToByte(char *pszhexa)
{
  __asm {
    or      eax, -1   ;// PRESUME ERREUR
    mov     dl, byte ptr[ecx]
    mov     cl, byte ptr[ecx+1]
    cmp     dl, 48
    jb      short btEXIT
    cmp     cl, 48
    jb      short btEXIT
    cmp     dl, 70
    ja      short btEXIT
    cmp     cl, 70
    ja      short btEXIT
    cmp     dl, 65
    jae     short hiAF
    cmp     dl, 57
    ja      short btEXIT
    sub     dl, 48
    jmp     short hiOK
hiAF:
    sub     dl, 55
hiOK:
    cmp     cl, 65
    jae     short loAF
    cmp     cl, 57
    ja      short btEXIT
    sub     cl, 48
    jmp     short loOK
loAF:
    sub     cl, 55
loOK:
    mov     al, dl
    shl     al, 4
    add     al, cl
    and     eax, 0FFh
btEXIT:
    ret     0
  }
}

// FONCTION RETOURNE 0.0 SI CHAINE NON HEXA (0-9, A-F sur 20 caractères)
// PAS EU LE TEMPS DE PRENDRE EN CHARGE LES MINUSCULES
__declspec(naked) double __fastcall HexaTenToDbl(char *pszhexa)
{
  __asm {
    push    esi
    push    ebx
    mov     esi, ecx
    sub     esp, 12
    mov     ebx, 10
fromHEXATEN:
    call    HexaToByte
    test    eax, eax
    js      short errHEXA
    add     esi, 2
    sub     ebx, 1
    mov     ecx, esi
    mov     byte ptr[esp+ebx], al
    jnz     short fromHEXATEN
    fld     tbyte ptr[esp]
    jmp     short tenEXIT
errHEXA:
    fldz
tenEXIT:
    add     esp, 12
    pop     ebx
    pop     esi
    ret     0
  }
}

// PROCEDURE DE TEST
void __stdcall Teste()
{
  char buf[24];
  sprintf(buf, "%.4f", HexaTenToDbl("4005F6EA7EF9DB22E000"));
  MessageBox(0, buf, "OK", 0);
}

// POINT D'ENTREE DU PROG
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE x, PSTR y, int z)
{
  Teste();
  return 0;
}

ciao...
BruNews, MVP VC++
0
BruNews Messages postés 21041 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 20
24 nov. 2006 à 20:39
1 MOV en benef:

__declspec(naked) DWORD __fastcall HexaToByte(char *pszhexa)
{
  __asm {
    or      eax, -1   ;// PRESUME ERREUR
    mov     dl, byte ptr[ecx+1]
    mov     al, byte ptr[ecx]
    cmp     al, 48
    jb      short btEXIT
    cmp     dl, 48
    jb      short btEXIT
    cmp     al, 70
    ja      short btEXIT
    cmp     dl, 70
    ja      short btEXIT
    cmp     al, 65
    jae     short hiAF
    cmp     al, 57
    ja      short btEXIT
    sub     al, 48
    jmp     short hiOK
hiAF:
    sub     al, 55
hiOK:
    cmp     dl, 65
    jae     short loAF
    cmp     dl, 57
    ja      short btEXIT
    sub     dl, 48
    jmp     short loOK
loAF:
    sub     dl, 55
loOK:
    shl     al, 4
    add     al, dl
    and     eax, 0FFh
btEXIT:
    ret     0
  }
}

ciao...
BruNews, MVP VC++
0
BruNews Messages postés 21041 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 20
24 nov. 2006 à 20:54
Bon allez, à la demande générale voici version définitive:

SUPPRIMER fonction HexaToByte() devenur inutile.
Ne conserver que ceci:

__declspec(naked) double __fastcall HexaTenToDbl(char *pszhexa)
{
  __asm {
    push    ebx
    sub     esp, 12
    mov     ebx, 10
fromHEXATEN:
    mov     dl, byte ptr[ecx+1]
    mov     al, byte ptr[ecx]
    cmp     al, 48
    jb      short errHEXA
    cmp     dl, 48
    jb      short errHEXA
    cmp     al, 70
    ja      short errHEXA
    cmp     dl, 70
    ja      short errHEXA
    cmp     al, 65
    jae     short hiAF
    cmp     al, 57
    ja      short errHEXA
    sub     al, 48
    jmp     short hiOK
hiAF:
    sub     al, 55
hiOK:
    cmp     dl, 65
    jae     short loAF
    cmp     dl, 57
    ja      short errHEXA
    sub     dl, 48
    jmp     short loOK
loAF:
    sub     dl, 55
loOK:
    shl     al, 4
    add     ecx, 2
    add     al, dl
    sub     ebx, 1
    mov     byte ptr[esp+ebx], al
    jnz     short fromHEXATEN
    fld     tbyte ptr[esp]
    jmp     short tenEXIT
errHEXA:
    fldz
tenEXIT:
    add     esp, 12
    pop     ebx
    ret     0
  }
}

ciao...
BruNews, MVP VC++
0
BruNews Messages postés 21041 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 20
24 nov. 2006 à 21:20
Promis c'est la dernière...
Celle ci est en stdcall donc directement exportable par DLL et utilisable depuis tout langage.


__declspec(naked) double __stdcall HexaTenToDbl(char *pszhexa)
{
  __asm {
    sub     esp, 12
    push    ebx
    mov     ecx, [esp+20]
    mov     ebx, 10
fromHEXATEN:
    mov     dl, byte ptr[ecx+1]
    mov     al, byte ptr[ecx]
    cmp     al, 48
    jb      short errHEXA
    cmp     dl, 48
    jb      short errHEXA
    cmp     al, 70
    ja      short errHEXA
    cmp     dl, 70
    ja      short errHEXA
    cmp     al, 65
    jae     short hiAF
    cmp     al, 57
    ja      short errHEXA
    sub     al, 48
    jmp     short hiOK
hiAF:
    sub     al, 55
hiOK:
    cmp     dl, 65
    jae     short loAF
    cmp     dl, 57
    ja      short errHEXA
    sub     dl, 48
    jmp     short loOK
loAF:
    sub     dl, 55
loOK:
    shl     al, 4
    add     ecx, 2
    add     al, dl
    sub     ebx, 1
    mov     byte ptr[esp+ebx], al
    jnz     short fromHEXATEN
    fld     tbyte ptr[esp]
    jmp     short tenEXIT
errHEXA:
    fldz
tenEXIT:
    pop     ebx
    add     esp, 12
    ret     4
  }
}

ciao...
BruNews, MVP VC++
0
TMONOD Messages postés 256 Date d'inscription mardi 25 novembre 2003 Statut Membre Dernière intervention 6 novembre 2009 1
27 nov. 2006 à 14:11
Merci, en effet ca peut servir.

Jcbé[^]
0