Newsgroup: it.comp.java
Titolo: Java ed i decimali

Ciao a tutti,
Non ho ben compreso in che modo Java "manipola" i numeri. In
particolare, sto cercando di calcolare delle percentuali, e metto il
risultato in un array di tipo float[]. Però "lui" arrotonda per
difetto; quindi, ad esempio, il risultato di ((22/116)*100) mi viene
dato come 18,0 ,  mentre il valore effettivo è 18,96. Come posso
fargli capire che deve darmi il risultato corretto? Con un array
double[] le cose non cambiano... 
Eppoi proprio mi sfugge il motivo - se ne esiste uno - per il quale
Java esegue questo grossolano arrotondamento per difetto...
Bye!
-----------------------------------------------------
NICOLA "Magic touch" FOCCI - 
n.f...@libero.it
http://digilander.iol.it/pumait
http://www.gruppopro.it/proqualitas
-----------------------------------------------------
"Life is what happens when you're making other plans"
				(John Lennon)

Bye!
Per prima cosa, escludiamo l'errore banale: sei sicuro di non assegnare, da 
qualche parte, valori double ad interi? scrivere
 int a = 0.5 * 0.5;
provoca a=0. 
Se il problema non e' di questo tipo, per trovare seriamente le risposte che 
cerchi dovresti consultare qualche buon testo di calcolo numerico.
float usa una rappresentazione segno-mantissa-esponente a 32 bit, mentre double 
a 64 bit. 
In particolare, le operazioni si comportano secondo una specifica IEEE (di cui 
non mi ricordo il numero, ma trovi tutto sulla JLS) - si approssima al valore 
rappresentabile piu' vicino e, in caso la distanza sia identica, si guarda 
dov'e' il primo bit di zero e si sceglie il numero per cui tale bit e' meno 
significativo.
Questo per le definizioni: in pratica, quando esegui calcoli, devi sempre 
verificare che il tuo algoritmo non produca overflow o underflow nei passaggi 
intermedi, o che non sia in qualche modo instabile o mal condizionato.
Dovendo trattare numeri molto grandi (o molto piccoli), le strade sono quelle 
di sviluppare un algoritmo ad hoc (efficiente) o usare una libreria numerica a 
precisione arbitraria (ce n'e' una dell'IEEE in C, non so se esiste il port in 
java); quest'ultima soluzione e' di solito meno efficiente, per "number 
crunching" pesanti.
-- 
God is Real, unless declared Integer.
ObjectZone - 
http://space.tin.it/computer/csadun

Bye!
1) sei sicuro che ((22/116)*100) faccia 18,0?
Probabilemente sono coinvolte variabili di altro tipo perchè il
risultato corretto è 0 (o 0,0 se archivi il tutto in un float e Java
risponde correttamente).
Ciò nasce dal fatto che Java tratta le operazioni di prima come
operazioni tra interi e dunque si ha:
22/116 = 0 con resto 22
0*100 = 0
Per avere il risultato corretto devi forzare un casting esplicito del
tipo e scrivere (((float)22/(float)116)*(float)100). Ora siccome Java
promuove automaticamente le variabili al tipo più alto fino ad ora
incontrato (e siccome quanto sopra è illeggibile) ti conviene
"castare" solo il 22 così: (((float)22/116)*100) java promuoverà
automaticamente prima il 116 e poi il 100.
Ora otterrani il tuo 18,96 circa.
Prova questi per chiarire il tutto:
class  Interi {
  static float output;
  public static void main(String[] args)  	{
    output=((22/116)*100);
    System.out.println(output);
  }
}
class  Interi {
  static float output;
  public static void main(String[] args)  	{
    output=(((float)22/116)*100);
    System.out.println(output);
  }
}
		Ciao Feyd
S.V.B.E.E.V.
Feyd-Rautha
feyd....@tiscalinet.it
rimuovi NOSPAM per rispondere
remove NOSPAM for reply