Newsgroup: it.comp.lang.c++
Titolo: da uint32 a float

Ciao a tutti,
innanzitutto mi presento visto che è il mio primo post.
Mi chiamo Gavino, sono sardo e da poco sono riuscito a terminare gli 
studi in ingegneria informatica.
Vi spiego un pò il mio problema:
ho un uint32* e vorrei tirar fuori un float*
La struttura uint32* viene fuori dalla libreria libtiff. A me però serve 
una float* perché il software esistente interagisce con questo tipo.
Come posso fare?


Devi convertirti l'area di memoria
ex:
uint32* p_int;
int size;
float* buffer_float = new float[size];
for (int i=0 ; i< size ; i++)
{
	buffer[i]= (float) p_int [i];
}
ricordati di distruggere la variabile una volta utilizzata.
ciao

 ciao

 > però SE riesce a stabilire in modo certo che sulla sua macchina un float
 > ha la stessa dimensione (in byte) di un intero a 32 bit, potrebbe anche
 > fare la conversione in situ, sovrascrivendo il suo array di int senza
 > allocarne uno altrove.
 > ovviamente il puntatore sorgente (uint32*) e destinazione (float*)
 > vengono inizialmente inizializzati a puntare alla stessa area di
 > memoria, e fatti scorrere parallelamente.
Completamente da sconsigliare!
Se il buffer viene caricato dalla libreria (libtif  a quanto dice) poi 
se per caso la reinvochi su quella struttura dati ti fai una bella frittata.
La mia opinione è di cercare di far fare alla libreria il suo lavoro e 
poi mi arrangio in qualche modo. Non è il cado di debuggarsi anche la 
libreria.
 >
 > P.S. io non me lo ricordo, ma non è che potrebbe presentarsi un problema
 > di underflow di precisione ?
 > NElla parte intera di numeri piuttosto grandi, i float dovrebbero avere
 > meno bits riservati alla mantissa, e quindi arrotondare al più prossimo
 > con un errore che, sempre dai vaghi ricordi, poteva già cadere sulla
 > sesta o settima decimale ...
Non so se si chiama underflow ma la perdita di precisione c'è
Un uint32 ha 32 bit di bit significativi mentre un float a 32bit IEEE 
754 ne ha solo 23bit . Sarebbe necessario un double con 52bit significativi.
Il fatto però non è significativo perchè la domanda era sulla 
conversione int to float da una libreria ad un'altra.

Vi ringrazio per le soluzioni proposte.
Dopo un pò di tentativi sono arrivato a questo tentativo
uint32* a;
float* b;
a = (uint32*)malloc(1*sizeof(uint32));
b = (float*)malloc(1*sizeof(float));
*a = 5;
*b = *a;
printf ("%d --> %f",*a,*b);
Per numeri piccoli tutto funziona ma se metto numeri grandi(ahimè 
facenti parte dell'immagine) allora le cose cambiano un pelo.
per esempio se metto *a = 4278584838, *b risulta essere *4278584832
Non c'è proprio modo di risolvere?

Ho appena letto la tua risposta. In effetti è proprio quello che ho 
trovato. Si perde in precisione perché i bit destinati alla parte intera 
sono 23.
Se trovo una soluzione o qualcosa del genere ve lo faccio sapere. Nel 
caso abbiate idee
EDIT : Facendo la prova con i double tutto funziona



con i float ci sono degli errori di rappresentazione.
cerca con google per i dettagli :-)
Per il tuo caso, forse basta usare dei double.
Visto che lavori in c++, dovresti usare
il "new" invece che malloc e cout ...
a.


Se il codice che deve gestire questi float non lo puoi modificare (ex 
altra libreria) allora non c'è alcuna soluzione!
Altrimenti passi da float a duoble e non avrai nessuna perdita di 
precisione.
Altra cosa da tenere in considerazione è il fatto che una perdita di 
precisione di 2^5 / 2^32 può essere del tutto ininfluente nel tuo calcolo.
Per vedere i limiti di una singola precisione è necessario eseguire 
delle routin particolari ex: calcolo del PI .
Non mi preoccuperai troppo subito e valutarie quanto questa perdita di 
precisione poi inferisce sul risultato finale.
Se ad esempio utilizzi un algoritmo FT probabilmente taglieresti qualche 
armonica e nulla di più.
Ora non avendo idea del campo di applicazione non posso essere più preciso.


Non con il tipo di dato di pari ampiezza, anche perché non 
si tratta di un problema o effetto inatteso, ma la 
caratteristica intrinseca di quel tipo di dato.
P.S. una cosa analoga si riproporrebbe convertendo a double 
dei long int (uint64).
ciao
Soviet

 Non c'ï¿œ proprio modo di risolvere?
No, disgraziatamente.
Passando da int a float passi da un numero intero a un logaritmo 
approssimato (se arrotondato o troncato non ricordo), che giocoforza 
sarï¿œ diverso dal numero intero stesso. La differenza ï¿œ sempre minore 
dell'epsilon macchina, per cui facendo int->float->int non te ne 
accorgi, ma comunque esiste e a forza di fare calcoli presto o tardi 
viene fuori. E' il motivo per cui non devi mai, MAI scrivere
if (a = b) {
...
}
se uno dei due ï¿œ float (e pure se lo sono tutti e due).

 se uno dei due float (e pure se lo sono tutti e due).
Ci sono ben 2 motivi per cui non devi MAI scrivere quella cosa :)
(anche se uno dei due spesso il compilatore te lo segnala come
warning :)
Pleg


io vedo solo quello che mi spinge a scrivere sempre
if ( fabs (b-a) < DTOL ) { ; }
ma perché sono abituato a calcoli numerici dove c'è sempre
una certa perdita di precisione. Qual è l'altra ragione??? :O
ciao!
Apx.
-- 
Ci sono tre modi con cui gli industriali possono perdere
enormi capitali: le donne, il gioco e gli ingegneri.
Il primo è il più piacevole; il secondo è il più rapido;
il terzo è il più sicuro.


==
e vabbč, m'č scappata...


L'altra ragione è semplicemente il fatto che tu vuoi fare un test e non 
un assegnamento.
Maurus

Il 22/12/2010 23.24, Pleg ha scritto:

ops, avevo dato per scontato che fosse l'operatore di
confronto, non di assegnazione, e a quel punto è ovvio.
Purtroppo uso i font proporzionali per ragioni estetiche e
per questo NG non sarebbe proprio il caso!
