DOMANDA [C] Decomposzione e ricomposizione di un Float IEE 754

Luc1

Nuovo Utente
101
15
CPU
Ryzen 5 2600
Dissipatore
Stock
Scheda Madre
Asrock B450m pro4
HDD
Samsung 970 EVO, Samsung 850 EVO, WD BLUE
RAM
Corsair vengeance kit 16 GB cl15 3000
GPU
Msi GeForce 1660 TI ventus
Monitor
AOC 24G2
PSU
Cooler master masterwatt 550
Case
Corsair cabride 275R
Periferiche
Corsair harpoon RGB, Corsair K55 RGB
Net
TIM Fttc 100/20 Mbit
OS
Windows 10 home
Salve sono stato fine alle 3 e mezza di notte per cercare di capire dove sto sbagliando nel fare questo semplice esercizio,ho consultato vari siti esterni come stack overflow e wikipedia per cercare di capire dove sto sbagliando ma invano.
Quindi mi rivolgo a voi come ultima spiaggia prima di andare a fare figuracce a ricevimento dal professore/ssa; il quesito da risolvere è di una semplicità assurda :

"[liv.1] Scrivere una function C per visualizzare la rappresentazione binaria (s,e,m) di un numero float.
Verificare che il valore del numero ottenuto coincida con il dato iniziale. "


Bene di seguito il programma scritto in C da me

Codice:
 union{
        float f;
        int i;
    }x;
    x.f=8.5;

Uso la union per allocare una zona di memoria condvisa nel main dove salvo il valore del mio FLOAT.

Creo una funzione per estrarre i bit di mantissa/segno/esponente dello standard mediante uso di MASCHERE esadecimali

Codice:
void extract(int A){
    int exp,e,s,m,masks,maske,maskm,maskbit;
    maske=0x7f800000;
    masks=0x80000000;
    maskm=0x007fffff;
    maskbit=0x00400000;

Rispettivamente esponente,segno,mantissa e bit implicito,

Codice:
    exp=A&maske;
    exp=exp>>23;
    e=exp-BIAS;
    s=A&masks;
    s=s>>31;

Estraggo l'esponente ed il segno, BIAS è definito nel preprocessore da me come 127, shifto a destra i bit per le operazioni necessarie.

Codice:
    m=A&maskm;
    m=m|maskbit;
    printf("e=%d,s=%d,m=%d\n",e,s,m);
    int fp=pow(-1,s)*(m)*pow(2,e);
    printf("%d\n",fp);

Qui credo di commettere l'errore fondamentale , per la mantissa so che ho 22 bit + 1 nascosto, quindi estraggo i 22 e dopo li metto in OR con la maschera del bit implicito per ottenere il valore intero corrispondente della mantissa che utilizzo nella seguente formula di ricostituzione; nel MAIN ho provveduto a printare anche il valore intero del FLOAT da me scelto DOPO la chiamata della funzione per confrontare i due valori interi se combaciano.

L'output è il seguente:

Codice:
e=3,s=0,m=4718592
37748736       // Valore che ottengo dalla mia function dalla formula (-1)^(s)*(l.m)*(2^(e-BIAS))
1091043328  // Valore originale x.i derivante dalla union

Grazie delle risposte e dell'attenzione.
 

signore del tempo

Utente Èlite
3,228
491
CPU
Intel Core i5 4670K
Scheda Madre
Asus Z87-Plus
HDD
WD Caviar Green 500GB
RAM
G.Skill Ares 2x4GB 1600MHz
GPU
Sapphire 7850 1GB @ 1050MHz
Audio
Integrata
Monitor
Acer V193w
PSU
XFX ProSeries 550W Core Edition
Case
CM HAF 912 plus
OS
ArchLinux + KDE - Windows 10
Con le bitmask si lavora con gli unsigned, perché gli int causano problemi; potrebbe essere quello il problema?
 
  • Mi piace
Reazioni: BAT

Luc1

Nuovo Utente
101
15
CPU
Ryzen 5 2600
Dissipatore
Stock
Scheda Madre
Asrock B450m pro4
HDD
Samsung 970 EVO, Samsung 850 EVO, WD BLUE
RAM
Corsair vengeance kit 16 GB cl15 3000
GPU
Msi GeForce 1660 TI ventus
Monitor
AOC 24G2
PSU
Cooler master masterwatt 550
Case
Corsair cabride 275R
Periferiche
Corsair harpoon RGB, Corsair K55 RGB
Net
TIM Fttc 100/20 Mbit
OS
Windows 10 home
No non erano bitmask a rompere le scatole ma come avevo intuito era la mantissa il problema.
Quando la estraggo si ottiene un intero ma al momento di ricomposizione io gli devo passare un numero frazionario altrimenti non seguo la formula : (-1)^s*[l.m]*2^(e-bias)

L.m rappresenta l'hidden bit (L) seguito da 22 cifre frazionarie per cui mi basta un semplice cast e una pow .

Dopo aver estratto con bit mask, porto la mantissa a numero frazionario float

Codice:
Float mf=(float)m*pow (10,-22)+1;

Il +1 è l'hidden bit, così facendo utilizzando la formula precedente ottengo il numero FP iniziale.


Inviato dal mio GT-I8190 utilizzando Tapatalk
 
  • Mi piace
Reazioni: signore del tempo

signore del tempo

Utente Èlite
3,228
491
CPU
Intel Core i5 4670K
Scheda Madre
Asus Z87-Plus
HDD
WD Caviar Green 500GB
RAM
G.Skill Ares 2x4GB 1600MHz
GPU
Sapphire 7850 1GB @ 1050MHz
Audio
Integrata
Monitor
Acer V193w
PSU
XFX ProSeries 550W Core Edition
Case
CM HAF 912 plus
OS
ArchLinux + KDE - Windows 10

Luc1

Nuovo Utente
101
15
CPU
Ryzen 5 2600
Dissipatore
Stock
Scheda Madre
Asrock B450m pro4
HDD
Samsung 970 EVO, Samsung 850 EVO, WD BLUE
RAM
Corsair vengeance kit 16 GB cl15 3000
GPU
Msi GeForce 1660 TI ventus
Monitor
AOC 24G2
PSU
Cooler master masterwatt 550
Case
Corsair cabride 275R
Periferiche
Corsair harpoon RGB, Corsair K55 RGB
Net
TIM Fttc 100/20 Mbit
OS
Windows 10 home
Meglio così. Ci mostri tutto il listato?


Sure

Codice:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define BIAS 127
#define MAX 32
void extract(int );
int main(){

    union{
        float f;
        int i;
    }x;
    x.f=8.5;
    extract(x.i);
    printf("%f",x.f);
    puts("\n");
    return 0;
}
void extract(int A){
    
    int B[32],i;
    int exp,e,s,m,masks,maske,maskm,maskbit;
    maske=0x7f800000;
    masks=0x80000000;
    maskm=0x007fffff;
    exp=A&maske;
    exp=exp>>23;
    e=exp-BIAS;
    s=A&masks;
    s=s>>31;
    m=A&maskm;
    float g=(float)m*pow(2,(-23))+1;
    printf("e=%d,s=%d,m=%f\n",e,s,g);
    float fp=pow(-1,s)*(g)*pow(2,e);
    printf("%f\n",fp);
    
}
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!