Newsgroup: it.comp.lang.c++
Titolo: Conversione float

Help, il C++Builder mi fa girare le palle... degli occhi !!!
Sentite questa: in una StringGrid formatto dei valori monetari in modo da
mettere il puntino separatore tra le migliaia, in questo modo:
FormatFloat("#,##0.", value)
Siccome alla fine della griglia vorrei visualizzare i totali, con un loop
sulle righe mi calcolo la somma finale, pero' l'amico Builder non mi
riconosce piu' il valore immesso nella cella poiche' c'e' il puntino (ossia
4.500 per lui non e' un numero :-(((
Si puo' essere piu' deficienti di cosi'??? Chi ha risolto questo problema?
Aiutatemi.
Grazie.
--
Stefano Tempesta
s.tem...@usa.net
http://tempesta.freeweb.org
--------------------------------
<<< Think indipendent,
cos' indipendent you can't be >>>

Help, il C++Builder mi fa girare le palle... degli occhi !!!
Usa VC++ cosi scoprirai cosa fa girare le ...

>Usa VC++ cosi scoprirai cosa fa girare le ...
Interessante, ma a proposito delle conversioni float? Niente da dire?
Io ho scelto Borland proprio perche' speravo di non complicarmi troppo la
vita :-(((
Inoltre, avete mai notato che in alcuni casi il Builder non e' preciso nella
memorizzazione dei valori in floating point? Io per esempio scrivo 80,45 e
lui mi riporta 80,4490039909. Ma insomma, cerchiamo di essere seri!!! La
gente spende soldi per comprare qualcosa che spera di poter utilizzare senza
problemi... e invece guarda qui che casino!
(ora si desteranno tutti i sostenitori dei vari djgpp e compilatori
freeware... fate bene. W IL FREEWARE, soprattutto se funziona meglio delle
zozzerie di Inprise e M$.
A proposito, sapete cosa ha detto la moglie di Bill la prima notte di
matrimonio?
"Ora ho capito perche' hai chiamato la tua azienda Microsoft..."
Va be', va be', e' vecchia, non scaldatevi, era giusto per distendermi i
nervi...
Ciao.


lui mi riporta 80,4490039909. Ma insomma, cerchiamo di essere seri!!! La
Quattro cifre significative sono veramente poche (dovrebbero
esserne garantite almeno sei), pero` la tua osservazione mi
lascia assai perplesso.  Quello che vedo io con C++ Builder 3:
    80.4500000000000028    per un double (80.45),
    80.4499969482421875    per un float (80.45f)
cioe` 16 cifre di precisione nel primo caso, 7 nel secondo, il
che in entrambi i casi e' perfettamente normale e corretto come
precisione di una rappresentazione floating-point doppia/semplice.
Risultati molto simili, e del tutto analoghi, con VC++ 5.0:
     80.4500000000000030
     80.4499969482421880
e con gcc (egcs-2.90.27 980315, egcs-1.0.2 release; mingw32):
     80.4500000000000030
     80.4499969482421880
rigorosamente identici a quelli del VC++.  Sospetto fortemente
che tutti e tre i compilatori tengano 80.45 in memoria nella stessa
forma binaria in ciascuno dei due casi (presumibilmente LA forma
binaria, compatibile con lo standard IEEE per il floating point, che
Intel adotta da molti, MOLTI anni nei suoi [co-]processori FP), e
la minuscola differenza in stampa sia dovuta a un diverso algoritmo
di arrotondamento nelle librerie runtime (e mingw32 usa quelle di
sistema, come certo fa anche il compilatore Microsoft).  Comunque,
tutti e tre i compilatori si stanno qui comportando in maniera
perfettamente accettabile.
"Cerchiamo di essere seri", tu dici; benissimo, replico volentieri,
cerchiamo eccome -- comincia, per favore, col precisare meglio
la tua specifica obiezione, poiche` non si riesce a riprodurre il
problema esatto che dici di avere.
Alex

 forma binaria in ciascuno dei due casi [....]
Il problema e' infatti quello: il numero e' tenuto in memoria
codificato in binario, usando "a pieno" i bit. "Anticamente" (come ad
esempio il mio Atari) si usava mezzo byte per ogni cifra decimale,
potendo quindi avere una rappresentazione esatta dei numeri decimali
al prezzo di usare piu' memoria per ogni numero.
Anche senza sapere i dettagli di come un float venga codificato, si
puo' immaginare che ci siano dei valori "belli" in decimale che pero'
non hanno un corrispettivo binario che corrisponde esattamente al
valore dato. In questo senso il problema non e' nella routine di
conversione, ma e' un problema intrinseco della codifica dei numeri.
Infatti, come anche fa' notare Alex, il "problema" appare  proprio al
limitare della precisione float.
Anche i double hanno lo stesso problema, che pero' colpisce cifre piu'
"lontane".
Ho guardato un po' in rete ma non ho trovato granche'...
Qualcosa sulla codifica dei float pero' c'e' a:
http://suburbia.net/~billm/floating-point/
http://www.farmington.k12.mo.us/CIE/RFC/1832/9.htm
Ciao,
Alberto
-- 
Alberto BARSELLA
PGP fingerprint = 13 3F 22 D2 0B 0A D3 25  F1 89 FE B5 82 AD 75 2A
** Beliefs are dangerous. Beliefs allow the mind to stop functioning.
A non-functioning mind is clinically dead.  Believe in nothing... **

valore dato.
In effetti le cause di tale comportamento sono 2:
1) Esistono valori (reali) che non possono essere rappresentati in
base in modo preciso, i cosi` detti valori irrazionali (sqrt(2),
sqrt(3) ecc. in base 10); passando da una base ad un'altra accade che
valori che prima non potevano essere rappresentati con precisione ora
lo sono e viceversa... In soldoni valori che con la base 10 noi
rappresentiamo con un numero finito di cifre possono non esserlo in
binario. 
2) A cio` va aggiunto che la rappresentazione interna di un
calcolatore e` necessariamente fatta con un numero finito di cifre
e quindi ad un certo punto bisogna approssimare il valore....
In pratica se consideriamo l'intervallo dei valori che un float
(double) puo` assumere, esso non e` certo un segmento della retta
dei numeri reali, ma i sui valori risultano frastagliati. In
particolare nella rappresentazione in virgola mobile c'e` una maggiore
concentrazione ("precisione") di valori rappresentabili intorno allo 0
che non verso valori lontani da esso.
Saluti,
Paolo 

problema esatto che dici di avere.
Non capisco il tono di questa tua affermazione: mi stavo solo lamentando del
fatto che il compilatore
non mantiene memorizzato un valore in maniera precisa, nessuna polemica.
Questo mi e' capitato con alcuni valori memorizzati in un file .db. Ora,
siccome non ricordo quali erano
questi valori per cui non veniva effettuata la giusta conversione, mi e'
difficile riprodurre il problema.
Se ho altri problemi ve li comunico.
Grazie a tutti per le informazioni.
--
Byez.


non mantiene memorizzato un valore in maniera precisa, nessuna polemica.
Non ci hai ancora mostrato quello che torni ad asserire, cioe` che
il compilatore "non mantiene memorizzato un valore in maniera
precisa".  Non intenderai per caso lamentarti del fatto che il tuo
compilatore (come praticamente tutti gli altri al mondo) tiene i
dati float (e double) in base binaria piuttosto che decimale, spero...?
Se per qualche ragione _devi_ gestire dei dati numerici in base
decimale, o anche con frazioni generali (o persino, ma e` assai
computazionalmente costosa, con aritmetica d'intervallo), allora,
magari, diccelo, invece di lamentarti, e qualche puntatore a varie
librerie di classi disponibili sulla rete te lo si passera` di certo
volentieri...!
Alex