Entra

View Full Version : Problema conversione da binario normalizzato (ieee 754) a esadecimale


SteveVai222
24-11-2009, 15:06
Salve a tutti!!
Qual'è il metodo per "ricomporre" il binario normalizzato (segno|esponente|mantissa) in singola precisione in un numero esadecimale?!?

SteveVai222
25-11-2009, 17:30
up!

nessuno sa aiutarmi?!?!?

bottomap
25-11-2009, 17:57
Ciao,

Ma in che linguaggio? (Tra l'altro se non hai letto l'annuncio in cima alla lista delle discussioni, i thread senza indicazione [linguaggio] in testa vengono chiusi).

In C++ puoi risalire da un float all'intero unsigned a 32bit (e di seguito alla sua rappresentazione esadecimale a schermo) con qualcosa del genere (sfido chiunque a farlo in maniera così pulita con qualsiasi altro linguaggio - ah la potenza del C/C++):
float f=1.2345f;
unsigned int i=*((unsigned int *)&f);
//Per l'esadecimale poi
printf("%04X",i); //lo puoi stampare a video
sprintf(s,"%04X",i); //oppure stampare in una stringa ad esempio

Per altri tipi di dato (double ad esempio) il meccanismo è lo stesso finché hai tipi interi che lo possono contenere... poi la cosa diventa leggermente più complicata (niente di trascendentale, solo bisogna creare un unsigned char* e scorrere byte a byte).

Ciaociao :)

SteveVai222
01-12-2009, 18:47
non ho messo linguaggio perchè la mia richiesta non è in nessun linguaggio!!
è solo un esercizio e non riesco a capire come "ricostruire" in esadecimale un numero binario normalizzato..(segno|esponente|mantissa)

bottomap
02-12-2009, 08:29
Ciao,

Hai un insieme di 32 bit 0/1 e devi stampare o salvare la sua rappresentazione esadecimale? 4 bit sono un nibble, un nibble è una cifra esadecimale (0-f).

Altrimenti non ho chiaro cosa vuoi ottenere e a partire da cosa... fai un esempio concreto casomai...

tomminno
02-12-2009, 10:03
Ciao,

Ma in che linguaggio? (Tra l'altro se non hai letto l'annuncio in cima alla lista delle discussioni, i thread senza indicazione [linguaggio] in testa vengono chiusi).

In C++ puoi risalire da un float all'intero unsigned a 32bit (e di seguito alla sua rappresentazione esadecimale a schermo) con qualcosa del genere (sfido chiunque a farlo in maniera così pulita con qualsiasi altro linguaggio - ah la potenza del C/C++):
float f=1.2345f;
unsigned int i=*((unsigned int *)&f);
//Per l'esadecimale poi
printf("%04X",i); //lo puoi stampare a video
sprintf(s,"%04X",i); //oppure stampare in una stringa ad esempio

Per altri tipi di dato (double ad esempio) il meccanismo è lo stesso finché hai tipi interi che lo possono contenere... poi la cosa diventa leggermente più complicata (niente di trascendentale, solo bisogna creare un unsigned char* e scorrere byte a byte).

Ciaociao :)

Io direi che quello che hai scritto è C, non C++:

float f =1.2345f;
cout << hexfloat << f;

:D

tomminno
02-12-2009, 10:18
Comunque per eseguire diciamo "manualmente" le conversioni, ricordo che si passa tramite la base 2 nel formato segno|mantissa|esponente e poi si converte il valore binario ottenuto in un numero esadecimale.

Sempre che la memoria non mi inganni, sono passati anni da quando ho fatto queste cose su fogli di carta.

bottomap
02-12-2009, 11:54
Io direi che quello che hai scritto è C, non C++:
Beh si... sottintendo C/C++ visto che se parlo di C++ comprendo automaticamente anche il C (chiaramente non è vero il viceversa). Lo stdio (printf, sprintf et similia) fa ancora pienamente parte del C++ nonostante i costrutti del namespace std.

Una volta che hai la forma binaria di 0/1 passare all'esadecimale è banale raggruppando i bit in nibbles.
Per farti un esempio, supponi il seguente numero binario a 32bit (non so se rappresenti un float, ma la cosa è indifferente):
10011100111110101011101010101101
Lo spezzi in nibbles (4bit) per lavorarci più comodamente:
1001 1100 1111 1010 1011 1010 1010 1101
Ogni nibble esprime un valore numerico compreso tra 0 (0000) e 15 (1111). Chiaramente le cifre 10,11,12,13,14,15 saranno espresse in esadecimale con a,b,c,d,e,f

Quindi hai:
9 C F A B A A D
Ossia il numero esadecimale:
9CFABAAD

E'questo che volevi sapere? Oppure ti manca anche il passaggio dal formato reale (xxxx.yyy) in formato binario?

Ciaociao :)

SteveVai222
03-12-2009, 14:49
no questo lo so fare..
faccio un esempio (formato ieee 754 singola precisione):
ho un numero decimale tipo: 45131000 lo converto in binario quindi: 10101100001010010011111000 poi lo normalizzo quindi 1,0101100001010010011111000 x 2^25 quindi 25+127(singola precisione)=152 che in binario è: 10011000(esponente)
quindi il numero binario normalizzo a singola precisione sarebbe:
0|10011000|0101100001010010011111000 (segno|esponente|mantissa) giusto?!?!
ora però da quel numero binario non so convertirlo in esadecimale (sempre formato ieee)

bottomap
03-12-2009, 16:24
Ciao,

Continua a sfuggirmi il senso della cosa...

Alla fine hai il binario normalizzato come hai detto:
quindi il numero binario normalizzo a singola precisione sarebbe:
0|10011000|0101100001010010011111000 (segno|esponente|mantissa) giusto?!?!
Fai conto che ieee prevede 1 bit di segno, 8 di esponente e 23 di mantissa per la precisione singola (totale 32), per cui riguarda la mantissa, ci sono un paio di bit di troppo.

Fatto questo (supponiamo di segare gli ultimi due bit per comodità) raggruppi a nibble e ottieni l'esadecimale corrispondente:
01001100001011000010100100111110
0100 1100 0010 1100 0010 1001 0011 1110
4C2C293E


L'esadecimale, così come il binario, è una rappresentazione... il float rappresentato da quell'insieme di bit è lo stesso float contenente il valore esa 4C2C293E...

Ciaociao :)

SteveVai222
03-12-2009, 16:32
semplicemente cosi?!?
e quindi a cosa serve tutta quest calcoli?!?
a cosa serve calcolare l'esponte dato che nella conversione non si calcola?!?!
grazie anticipatamente e posticipatamente (delle risposte gia date )..

bottomap
03-12-2009, 16:55
Ciao,

Beh, internamente il sistema CPU/FPU lavora con i bit ed è probabile che debba convertire un numero decimale in un numero a virgola mobile o viceversa (e/o è possibile che un tuo programma a basso livello voglia eseguire questo genere di conversione). Chiaramente una normale fpu ha un insieme di istruzioni apposite per la conversione da intero al suo formato in virgola mobile... se però tu dovessi effettuare calcoli in virgola mobile e stessi lavorando su un microprocessore che non ha una FPU dovrai in qualche modo prevedere (virgola fissa a parte) di poter convertire interi e decimali.

A parte i bit, poi ogni altra cosa serve a dare una rappresentazione del numero (ad esempio a schermo, oppure ad una funzione o dispositivo che si aspetta in input la rappresentazione del valore in una base specifica).
Passare alla base 8, alla 10, alla 16 et similia (base32 e base64 ad esempio sono codifiche molto usate... la seconda - una cifra base64=6bit - è la codifica impiegata da ogni programma di mail per l'invio degli allegati) è solo in funzione della necessità di rappresentare un numero in maniera diversa e comunque (bi)univoca.

Ciaociao :)

SteveVai222
03-12-2009, 17:01
ok grazie..