Newsgroup: it.comp.lang.c++
Titolo: Float: spiegatemi questo!!!

Allora, avevo precedentemente sollevato delle perplessita' sulla conversione
dei float senza trovare un valido esempio.
Ora chiaritemi perche' per il C++Builder, 4 diviso 5 non fa 0.8 come in
tutte le calcolatrici del mondo (che non hanno un Pentium II 450 come
processore).
{
float Num1, Num2;
Num1 = 4.0;
Num2 = 5.0;
if (Num1/Num2 == 0.8)
    Label1->Caption = "OK";
else
    Label1->Caption = "Not OK";
}
--
Byez.
Stefano Tempesta
s.tem...@usa.net
http://tempesta.freeweb.org
--------------------------------
<<< Think indipendent, cos' indipendent you can't be >>>

processore).
Senza dubbio perche`, in base binaria, si possono rappresentare
esattamente solo le frazioni che hanno come denominatore una
potenza di due, e 0.8 non e` fra queste.  Una calcolatrice, che non
ha tutto sommato grosse esigenze di velocita`, puo` scegliere
ad esempio di mantenere i numeri in base dieci, e risparmiarsi
le difficolta` di spiegare ad utenti senza nessuna cultura in campo
informatico i perche` e i percome della situazione.
Un informatico, naturalmente, sa che due numeri in virgola mobile
non vanno mai paragonati per eguaglianza, perche` normalmente
l'eguaglianza non si verifica a fronte di qualsiasi differenza sulla
sequenza di calcoli.  Ad esempio, in virgola mobile, sommare a
con b, poi sommare al tutto c, da' spesso risultati diversi di quelli
che si ottengono sommando invece prima b con c, e poi sommando 
a al risultato (la procedura di somma di N numeri che da` il
risultato piu` preciso e` naturalmente ben nota dall'analisi
numerica; una ragionevole approssimazione, mantendendo
la caratteristica O(N) del calcolo, si puo` ad esempio avere 
usando due accumulatori separati, uno per gli addendi positivi
e uno per quelli negativi, e sommando i due solo come ultima
operazione).  Tornando ai confronti di eguaglianza: quel che
si puo` fare al loro posto e` verificare che il valore assoluto
della differenza fra i numeri sia "abbastanza piccolo" rispetto
alla precisione di calcolo che ci si puo` aspettare (stimare
questa precisione, nel caso generale, e` un esercizio non
banale di analisi numerica; ma per una singola operazione,
come una divisione, si puo` andare "a braccio" e far conto
ad esempio su almeno 5 cifre significative per un float, o 
10 per un double -- l'unica singola operazione che puo`
distruggere la precisione e` la differenza fra numeri molto
vicini fra loro).
Se, per qualche ragione, ti serve l'aritmetica decimale, invece
della normale aritmetica binaria del computer, puoi sicuramente
trovare in rete un pacchetto gia` realizzato a questo scopo.  Non
che questo semplifichi i problemi di analisi numerica connessi
alla aritmetica in virgola mobile, naturalmente, ma puo` lo stesso
essere necessario in certi casi (ad esempio, puo` essere un
vincolo di legge per certi calcoli finanziari).
Alex

Grazie Alex, sono d'accordo su tutto, pero' e' parecchio limitante il non
poter confrontare
per uguaglianza una banale operazione come 4 / 5 :-(((
Io ha avuto problemi in BC++ 3.1 con sin(x) = 0 quando x = 0 perche' questa
uguaglianza non
si verifica MAI !   E' parecchio frustrante perdere del tempo a cercare
questi errori.
Non esistono opzioni del compilatore per avere maggiorer accuratezza nei
risultati ? (non so,
uso del processore matematico, arrotondamento automatico, qualcosa del
genere, insomma)



Problemi di questo tipo non possono essere risolti con una qualche opzione poiche` sono
legati alla rappresentazione in base con un numero finito di cifre.
D'altronde nessun matematico che si rispetti direbbe che 1.414213 sia uguale a sqrt(2),
per quante cifre decimali tu possa utilizzare non sarai mai in grado di rappresentare quel
valore in modo esatto (in base 10).
L'unica cosa fattibile e` utilizzare opportune tecniche per tenere sotto controllo gli
errori di approssimazione.
Paolo

genere, insomma)
Il processore matematico viene usato automaticamente, ma
di per se, ahime`, non risolve la questione, esattamente come
non lo risolveva quello del CDC 6600 o 7600, con tutto che
l'avesse progettato Seymour Cray in persona prima di mettersi
in proprio:-).  Non so se il Borland ha qualche strana opzione che
ti automatizzi la cosa come un tempo faceva APL -- ne dubito --
secondo me l'unica e` abituarsi ad usare una qualche funzione
di confronto diversa da operator== per i double, sigh:-(.
Alex

Se utilizzi ancora Borland, dovresti avere la classe BCD che fa proprio al
caso tuo (uso il condizionale perche non so se sia presente anche in
CBuilder .... comunque fino al 5.02 c'era)
Ciao
Andrea
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
per rispndere rimuovere NOSPAM dall'indirizzo
to reply please remove NOSPAM from the address
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
** La nuvoletta del Ragioniere e' ben poca cosa se confrontata con
l'anticiclone del Programmatore! **

di confronto diversa da operator== per i double, sigh:-(.
Ok, mi avete convinto. Penso proprio che non ci sia altro da fare :-(
Grazie a tutti.
