|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 584
|
java come non troncare numeri
leggendo dei numeri da un file e convertendoli in double usando num = Double.parseDouble(linea); ho notato che quando li stampo questi non sono uguali ad esempio
-0.01976446502439700405 diventa -0.0197644650243970040 oppure 4512014.1482265731234567890 diventa 4512014.148226573 come posso risolvere, mi servono come numeri senza essere troncati perchè poi devo sommarli/sottrarli???
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Usa BigDecimal
Per le operazioni ha dei metodi al posto degli operatori. Sono immutable quindi i metodi-operatori non alterano il valore dell'istanza ma restituiscono nuovi BigDecimal che contengono il risultato. A parte questo sono una gioia
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 584
|
grazie!!! ho provato ma ho alcuni problemi, ecco il codice:
import java.math.BigDecimal; public class Grandi { public static void main(String[] args) { BigDecimal num1 = new BigDecimal("6666665.2222222224"); BigDecimal num2 = new BigDecimal("2222223.2222222224"); BigDecimal num3 = new BigDecimal("1234567.0987654321"); BigDecimal num4 = new BigDecimal("2.0"); System.out.println("num1 = " +num1); System.out.println("num2 = " +num2); BigDecimal somma = num1.add(num2); System.out.println("somma = " +somma); BigDecimal moltiplica = num1.multiply(num2); System.out.println("moltiplicazione = " +moltiplica); BigDecimal divisione_1 = somma.divide(num4); System.out.println("divisione_1 = " +divisione_1); BigDecimal test = moltiplica; System.out.println("test deve essere uguale a moltiplica = " +test); BigDecimal divisione_2 = num1.divide(num2); System.out.println("divisione_2 = " +divisione_2); } } ho questo errore: Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. at java.math.BigDecimal.divide(BigDecimal.java:1513) at Grandi.main(Grandi.java:24) inoltre se volessi fare (num1+num2+test )/3 come dovrei fare ??? grazie |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Se dividi allora devi specificare un tipo di arrotondamento perchè il meccanismo predefinito è ultra-conservativo: se non può calcolare un risultato esatto allora spara un'eccezione.
C'è un metodo ad hoc in BigDecimal, il divide che accetta un RoundingMode. In pratica anzichè: BigDecimal r = a.divide(b); fai BigDecimal r = a.divide(b, RoundingMode.HALF_EVEN); O un altro RoundingMode, devi vedere tu qual'è il più adatto.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 584
|
ho provato con
BigDecimal divisione_2 = num1.divide(num2, BigDecimal.ROUND_HALF_UP); che ha arrotondato il risultato a 3 senza avere nessuna eccezione ma per fare (num1+num2+test+ ...)/3 come dovrei fare perchè tutti gli esempi che ho trovato fanno sempre operazioni soltanto tra due valori, inoltre posso dividere direttamente per 3 oppure questo dovrà essere inizializzato in qualche altra variabile. grazie mille!!! |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Supponendo che a, b, c e d siano BigDecimal dirai:
BigDecimal r = a.add(b).add(c).divide(d, RoundingMode.HALF_EVEN); che tradotto in simboli sarebbe: (a + b + c) / d
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 584
|
grazie!!!
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 584
|
se a, b, c sono BigDecimal e vorrei dividerli per 3
posso fare soltanto così: BigDecimal tre_ = new BigDecimal("3"); BigDecimal risultato = a.add(b).add(c).divide(tre_, RoundingMode.HALF_EVEN); cioè non c'è un modo più veloce, tipo come per i float float a=1; float b=2; float tot=(a+b)/2; System.out.println(tot);
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
No ... i metodi sono quelli!
Per costruire BigDecimal con valori predefiniti (costanti), parti da un int/long/double, non da una stringa (se vai a vedere BigDecimal ha una caterva di costruttori!)
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 584
|
se faccio così e corretto
import java.math.BigDecimal; public class Prova { public static void main(String[] args) { int i = 8; BigDecimal bd = new BigDecimal(String.valueOf(i)); System.out.println(bd); } } |
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Ma sei andato a vedere i costruttori di BigDecimal???
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Usa sempre il costruttore che richiede una stringa e sei a posto.
BigDecimal bd = new BigDecimal("1"); BigDecimal bg = new BigDecimal("9.0"); eccetera.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 584
|
Quote:
ma BigDecimal bd = new BigDecimal("8"); BigDecimal bd = new BigDecimal(8); int i=8; BigDecimal bd = new BigDecimal(String.valueOf(i)); è la stessa cosa oppure no? puoi suggerirmi un link per lo studio dei costruttori? grazie |
|
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Sui concetti relativi ai costruttori?? Qualunque buon libro o tutorial online! http://www.google.it/search?hl=it&q=...n+Google&meta=
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Per valori interi l'uso di un primitivo (byte, short, int, long) o di una stringa è uguale.
Per valori che hanno una parte frazionaria (float, double) l'uso di un valore double o float, sia esso una variabile piuttosto che un letterale, è problematico perchè BigDecimal assume l'esatto valore del numero che gli passi. Tale valore può non corrispondere a quello espresso dal letterale numerico. BigDecimal(8.1) è all'incirca 8.1 mentre BigDecimal("8.1") è esattamente 8.1. Considera inoltre l'ovvio rilievo che inizializzare un numero a precisione arbitraria con un valore a precisione limitata è un caso non banale di schizofrenia
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 584
|
cosa vuol dire inizializzare un numero a precisione arbitraria con un valore a precisione limitata ? mi fai un esempio?
|
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Era una facezia. Ammazza, tutti allegri eh?
Un double ha 16 cifre significative. Prendi il numero: 4512014.1482265731234567890 e conta fino a 16, a partire da sinistra (la prima cifra diversa da zero). Quello è il double. 4512014.148226573 il resto 1234567890 è fuffa. Puoi dire: double x = 4512014.1482265731234567890; BigDecimal v = new BigDecimal(x); ma è "schizofrenico" perchè tra il valore di x e il valore di v non c'è differenza, dal punto di vista della coincidenza tra il letterale scritto (4512014.1482265731234567890) ed il valore assunto. Solo 16 cifre del double sono significative: le altre sai già (perchè hai usato un double) che non saranno rappresentate correttamente. E' la stringa il pane del BigDecimal. Perchè è coerente con l'intenzione. Io voglio un numero che vale esattamente questo: e vomiti un improperio di cifre. E' ok, BigDecimal serve (anche) a quello: a prescindere dal numero di cifre che scrivi sai già che tutto il numero che hai scritto sarà rappresentato, che ogni cifra sarà correttamente assunta perchè la precisione di un BigDecimal è arbitraria. Perchè tu hai chiesto di BigDecimal? Be', perchè vuoi che un numero con una quantità arbitraria di cifre sia correttamente rappresentato e double non può farlo. Se mi usi un double per inizializzare il BigDecimal siamo punto e a capo
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! Ultima modifica di PGI-Bis : 14-05-2007 alle 23:31. Motivo: ehh, scrivere. Mica facile. |
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 584
|
grazie per la spiegazione!!!
|
|
|
|
|
|
#19 |
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 584
|
ma se faccio 3/2 con i BigDecimal come faccio ad ottenere 1.5
perchè se faccio così arrotonda a 1 oppure a 2: BigDecimal num1 = new BigDecimal("3"); BigDecimal num2 = new BigDecimal("2"); BigDecimal divisione_1 = num1.divide(num2, BigDecimal.ROUND_UP); BigDecimal divisione_2 = num1.divide(num2, BigDecimal.ROUND_DOWN);
|
|
|
|
|
|
#20 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Devi specificare quante cifre dopo la virgola vuoi che siano rappresentate. Puoi farlo in costruzione (con la stringa):
BigDecimal num1 = new BigDecimal("3.0"); //1 cifra dopo la virgola o con il metodo setScale, che restituisce un nuovo BigDecimal: BigDecimal num1 = new BigDecimal("3").setScale(1); //1 cifra dopo la virgola
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 12:48.



















