Newsgroup: it.comp.java
Titolo: double..... questo sconosciuto !!!

Ciao a tutti,
lavorando con dei numeri decimali mi sono accorto di quanto segue:
se sommo due valori double:
double a=225.24;
double b=19.27;
ottengo come risultato: 244.51000000000002
anzichč: 244.51
Perchč?
Sapete spiegarmelo?
Ciao,
Carlo
 

 
è una quatione legata alla rappresentazione interna dei numeri si pc.
per fare in fretta diciamo che quello che ti propone è il risultato più 
accurato che può fornirti visto che lui non usa numeri decimali ma 
binati. questo è un pò riduttivo, ma ora non ho sotto mano le specifiche 
ieee dei double per andare nei dettagli.
Ciao
Alex

 double per andare nei dettagli.
Qualcosa non mi torna.
Non è difficile realizzare un algoritmo che, somando i valori indicati, 
restituisca un risultato preciso.
Io stesso, che non sono un guru di Java, sarei ingrado di farlo:
double ris=(a*100+b*100)/100;
E allora perchè la SUN, che di juru ne ha quanti ne vuole,  non ha 
rimediato?
Ciao.
Carlo 

Lo standard IEEE 754 prevede che i numeri double siano memorizzati nella forma
1.SSSSSSSS x 2^(exp-1023)
dove SSSSSSSS è il "significando" (52 bit). SOno poi usati 11 bit per 
l'esponente e 1 bit per il segno. QUando si sommano numeri con esponenti diversi 
deve essere fatta una normalizzazione che in genere comporta perdita di 
precisione. Il discorso è complesso. Un ottimo documento, che spiega 
dettagliatamente ogni aspetto, è alla URL 
http://docs.sun.com/source/806-3568/ncg_goldberg.html
Tieni anche presente che il numero 0.1 (un decimo) in binario è un numero 
periodico, che necessita dunque di infinite cifre per una rappresentazione corretta.
Ciao
FAbrizio


cc wrote:

Benvenuto nel fantastico mondo della virgola mobile :P
Si tratta di un noto problema di precisione nelle operazioni fra 
floating point dovuto alla loro rappresentazione binaria.
Riduci esplicitamente il risultato alla precisione voluta, oppure usa 
java.math.BigDecimal.

 rimediato?
Perchè non è un problema da rimediare, è così perchè questi sono i 
floating point.

 floating point.
Questa è una cavolata, perchè la matematica non è un opinione.
Il risultato dell'addizione che ho indicato è matematicamente sbagliato, su 
questo non ci piove.
Poi, se vuoi, possiamo anche rassegnarci perchè tanto i floating funzionano 
cosi........ ma rimane un errore.
Ciao,
Carlo

 cosi........ ma rimane un errore.
Carlo, il problema e' quasi filosofico. Tu hai un microprocessore che
ragiona con il numero incriminato del cazzo.
Java e' un linguaggio. Il linguaggio e' un mezzo per comunicare. In questo
caso l'uomo usa il linguaggio per comunicare col processore nei dui versi.
Io chiedo delle operazioni al processore tramite java e il processore mi
risponde sempre attraverso java.
A questo punto , rigorosamente ci trasmette il numero errato. perche' cosi'
gli viene trasmesso.
Da un punto di vista pratico io posso arrotondare il numero con facilita0'
come gia' hai dettotu, mentre se arrotondasse lui, io non saprei mai il
numero che il processore mi vuole dare. quindi avrei perdita di
informazione.
Nicola
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/


Cosa significa "rassegnarsi"? I floating point ti garantiscono una certa 
precisione che fra l'altro è abbondantemente superiore a quello che ti 
serve, visto che il risultato di una somma fra due numeri precisi alla 
seconda decimale *deve* avere una precisione di due cifre decimali (e 
non di più).
Anche questa è matematica.

 Anche questa č matematica.
L'esempio che ho fatto era solo un esempio.
Ho usato due decimali, ma lo stesso problema lo avrei avuto anche se ne 
avessi usati 10.
Per me č molto importante che la somma di due double sia corretta perchč sto 
lavorando su un navigatore GPS.
E i dati che devo gestire hanno 10 numeri decimali.
Ora capisci che se faccio una trasformazione e il risultato non č 
matematicamente corretto potrei indicare, su una piantina, una posizione 
errata.
Ciao,
Carlo 

 errata.
Se hai bisogno di una precisione definita, non devi usare i tipi floating
point, ma quelli fixed point. Nella Java API una classe che rappresenta
numeri a virgola fissa e' BigDecimal.
-- 
Lucio Benfante
Java User Group Padova: 
http://www.jugpadova.it
Brainbench MVP for Java 1: 
http://www.brainbench.com
MyTranscript: 
http://www.brainbench.com/transcript.jsp?pid=167064

 wrote in message news:cmdirg$msn$1...@lacerta.tiscalinet.it...

Bene, a quel che ne so io, il double ti da una precisione di 15 decimali o giu' di li'.
Se a te ne bastano 10, sei larghissimamente coperto e le tue indicazioni sulla cartina
avranno errori non visibili. Questo, nella stragrande maggioranza dei casi, e' esattamente
cio' che serve.
Pretendere la precisione assoluta nei calcoli pratici e' come pretendere misure senza
errore. L'errore va solo tenuto inferiore alla soglia di accettabilita' (normalmente
contenuta nelle specifiche).
Saluti
Mino Saccone

 avessi usati 10.
No, anzi ni.
Sapendo che i floating point sono rappresentati come mantissa e 
esponente, sai anche che una rappresentazione id questo genere ti 
garantisce un certo numero di cifre significative che se non erro nei 
double sono 15. Quindi la decima cifra decimale puoi averla a patto di 
rimanere nelle cifre significative garantite dal tipo di dato. Se hai 
bisogno di più di 15 cifre significative vuol dire che sbagli ad usare 
il double, tutto quà.

 contenuta nelle specifiche).
Su questo sono d'accordo. Nell'esprimere un risultato l'incertezza deve 
essere solo e soltanto sull'ultima cifra.

 Altro che dieci decimali... :-)
Infatti mi sono espresso male e intendevo "cifre significative" che e' esattamente cio'
che il floating point garantisce.
Scusate
Mino Saccone

 double b=19.27;
Devi sempre tener conto che alcuni numeri decimali con rappresentazione 
finita in base 10 diventano periodici in base 2.

cc wrote:
 >>Perchè non è un problema da rimediare, è così perchè questi sono i
 >>floating point.
 >
 >
 > Questa è una cavolata, perchè la matematica non è un opinione.
No, la matematica non è un opinione, ma lo diventa se non è chiaro il 
contesto in cui si opera. Perfino 2+2 non fa sempre 4.
 > Il risultato dell'addizione che ho indicato è matematicamente 
sbagliato, su
 > questo non ci piove.
 > Poi, se vuoi, possiamo anche rassegnarci perchè tanto i floating 
funzionano
 > cosi........ ma rimane un errore.
No, non è matematicamente sbagliato ne' è un errore. Il problema è che 
tu vorresti che si comportassero come i numeri reali, ma questi numeri 
non sono dei reali.
I numeri reali, così come i razionali e i naturali, non sono 
rappresentabili all'interno di un computer (qui' non si parla solo di 
java o di un altro linguaggio), se non altro perché tutti questi insiemi 
sono infiniti, mentre un computer può memorizzare e gestire solo un 
numero finito di valori.
Pertanto si deve scegliere un loro sottoinsieme (finito) da trattare. Le 
possibilità sono due:
1) Numeri in virgola mobile
A questa categoria appartengono i float e i double di Java cosi' come i 
numeri in virgola mobile trattati da qualunque processore della famiglia 
intel.
Si ha un numero fisso di cifre significative (in base 2, ulteriore 
imprecisione deriva dal fatto che si deve convertire da base 10 a base 
2). Hanno il vantaggio di avere un range molto elevato.
2) Numeri in virgola fissa
Lo sono gli int di java e tutti i tipi interi gestiti dai processori (0 
cifre decimali).
In java esistono classi per gestire valori con un certo numero di cifre 
decimali (BigDecimal) ma in genere (non e' sempre vero) non sono 
supportati direttamente dal processore.
A parità di bit utilizzati per la loro memorizzazione hanno un range di 
valori più ristretto.
Andrea
P.S.
Cerca di moderare il tono dei tuoi post. Sei tu a non conoscere il 
funzionamento dei double e di come i computer trattano i numeri e quindi 
affermazioni saccenti come "è una cavolata", "la matematica non è 
un'opinione" e "è matematicamente sbagliato" possono solo irritare chi 
legge.

 Questa č una cavolata, perchč la matematica non č un opinione.
Ma scusa: prima di questa scoperta pensavi che i computer potessero 
operare con i numeri reali? :)


Scusa non per essere pignolo, ma la precisione che te chiami "assoluta" 
non puň esistere. se fai il pignolo anche le funzioni seno, coseno, 
tangente e tutte le altre sono in realta tratte da delle successioni che 
sono imprecise. quindi la precisione di cui ti lamenti č forse la cosa 
che ti va meglio.
Alex


Il perché te lo hanno spiegato, e se vuoi leggi qui un paio di cazzate:
http://megadix.users.mcs2.netarray.com/calcoli_impossibili.html
Se vuoi la precisione di quel tipo, prova con i BigDecimal !!!