Newsgroup: it.comp.lang.c++
Titolo: Volete rimanere a bocca asciutta?

//    Primo "stupimento" :
double v1 = 69.82;
double v2 = 69.20;
double v3 = 0.62;
double v4 = v2 + v3;
BOOL e = (v4 == v1);
////////////////////////////////////////////////////////////////////////////
///////////////////
//    e se non bastasse... :
double x1 = 301.84 - 301;
////////////////////////////////////////////////////////////////////////////
///////////////////
Questo č impegnativo, vediamo chi mi sa dare la spiegazione giusta... (non
che non sappia il perchč, intendiamoci...)

 //    Primo "stupimento" :
Stai programmando qualcosa che lavori con la valuta Euro usando i 
double???
AHI AHI AHI...
Spero che quel qualcosa sia solo a livello hobbistico...
;)
-- 
Luc.

 ha scritto nel messaggio
news:MPG.17f503d67...@tornado.fastwebnet.it...


 //    Primo "stupimento" :
Ti mancano le basi.  E' ovvio che i numeri reali non possono essere
rappresentati tutti esattamente con un numero finito di bits; e che in
una architettura a base due, numeri non potanza di due non possono
avere una rappresentazione esatta.  Prova a fare sul web una ricerca
per "errori di approssimazione" ed "errori di arrotondamento"
(approximation/rounding errors).
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy          loreti at pd dot infn dot it

 ha scritto nel messaggio
news:8a8z1x5...@mlinux.pd.infn.it...


 > > //    Primo "stupimento" :
Quello che si conosce non stupisce  ==>  se ti stupisci non sai.
E quanto alle basi, quanto meno ti mancano quelle della netiquette; e'
considerata pessima educazione quella di quotare il messaggio
precedente DOPO il proprio; infatti, nel caso di una catena di tre o
quattro risposte, il tutto diventa illeggibile.


 ha scritto nel messaggio
news:8aznud3...@mlinux.pd.infn.it...


 Quello che si conosce non stupisce  ==>  se ti stupisci non sai.
DON'T FEED THE TROLL!!!!
*** Azimuth ***

 DON'T FEED THE TROLL!!!!
Il Prof. Loreti?!?!?!?
;)
-- 
Luc.

 Il Prof. Loreti?!?!?!?
DON'T PRESS THE REPLY ON THE WRONG MESSAGE!
*** Azimuth ***

 (approximation/rounding errors).
Domanda ... ma il tipo double ha un range di numeri rappresentabili
preciso (conseguenza della sua natura binaria e finita) ... resta il
fatto che un semplice calcolo fatto con due valori che rientrano in
tale range non viene eseguito correttamente ... perche ?

 tale range non viene eseguito correttamente ... perche ?
In un intervallo tra due numeri finiti e distinti esistono infinti
numeri reali. Quindi esistono infinitamente piu' numeri reali di quanti
siano rappresentabili nel range dei double.
In particolare i soli numeri rappresentabili sono quelli la cui parte
frazionaria e' esprimibile come somma di potenze negative di due: ad es.
1/5 + 1/25 + 1/125 + ...
Ciao,
Nicola

 tale range non viene eseguito correttamente ... perche ?
Il fatto è che il range non è continuo! I numeri reali si rappresentano
secondo uno standard IEEE . Tale standard prescrive una rappresentazione
esponenziale del tipo che prevede (nel caso dei float, ma è una cosa analoga
per i double) un bit per il segno, 23 bit di mantissa, e 8 di esponente tale
che vale
 x = (s)1.m * 2 ^ (exp-bias)
dove x è un qualsiasi numero rappresentabile, s è il bit di segno, m è la
mantissa (l'uno è implicito e non si memorizza), exp è l'esponente che viene
rappresentato senza segno ma a cui va poi sottratto bias che è una costante
pari a 127 per avere il range -127:128 (è solo una comodità di
memorizzazione).
Ora la rappresentazione esponenziale crea dei buchi tra i valori. Ovvero
considera per semplicità dove la mantissa ha solo 4 bit
1.101*2^2
1.110*2^2
tra questi due numeri la matematica ci insegna che ne esistono infiniti (il
famoso assioma di completezza di Dedekind), ma sulla nostra macchina non può
esserne rappresentato correttamente neanche uno. Notare che nelle vicinanze
dello zero questi buchi tra i valori sono piccoli ma crescono con numeri più
alti (se non sbaglio 2000000001 viene troncato a 2000000000). Adesso se il
numero che inserisci è perfettamente rappresentabile non ai problemi
altrimenti viene arrotondato e quindi il risultato di un operazione su un
elaboratore può differire seppur di un niente dalla reale operazione
matematica. Nel caso della sottrazione però c'è un problema in più, che
prende il nome di cancellazione catastrofica. Si verifica quando si esegue
una sottrazione tra due numeri macchina molto vicini.
I test di uguaglianza vanno quindi verificati diversamente, comunque basta
fare una ricerca su google oppure procurarsi un testo di metodi numerici per
approfondire un po'.
In definitiva non c'è da rimanere a bocca asciutta, è un esame che gli
studenti di ingegneria informatica svolgono al secondo anno (io lo faccio
martedì)!
Spero di essere stato chiaro!
Fulvio

 tale range non viene eseguito correttamente ... perche ?
Un esempio: 0.5 decimale in binario e' 2^{-1}, quindi 0.1 in binario.
0.1 decimale in binario e' un numero periodico: 0.0(0011) , con la
sequenza in parentesi che si ripete infinite volte; quindi non si puo'
rappresentare in binario con un numero _finito_ di bits.  Pero' 0 e 10
sono rappresentabili esattamente.  Morale: non e' detto che il
risultato di un'operazione aritmetica (divisione in questo caso) tra
due numeri esatti dia un risultato esatto (e questi sono gli errori di
approssimazione - il fatto che dei numeri non siano rappresentabili
esattamente.
Poi, il prodotto tra due numeri, ognuno dei quali rappresentabile
esattamente ad esempio con 32 bits, puo' consistere di un numero di
cifre significative tale da non poter essere rappresentato esattamente
con 32 bits: il prodotto va troncato ed approssimato.  Questi sono gli
errori di arrotondamento.
