2011-09-02 15 views
64

Quando chiamo Math.ceil(5.2) il ritorno è double6.0. La mia naturale inclinazione era pensare che Math.ceil(double a) restituisse un long. Dalla documentazione:Perché Math.ceil restituisce un doppio?

ceil(double a)

Restituisce il più piccolo (più vicino a infinito negativo) double valore che non sia inferiore l'argomento ed è pari ad una matematica intero.

Ma perché restituire un double piuttosto che un long quando il risultato è un numero intero? Penso che comprenderne la ragione potrebbe aiutarmi a capire un po 'meglio Java. Potrebbe anche aiutarmi a capire se mi metterò nei guai trasmettendo a long, ad es. è

long b = (long)Math.ceil(a);

sempre quello che penso dovrebbe essere? Temo che potrebbero esserci dei casi limite che sono problematici.

+0

Vedere http://stackoverflow.com/questions/3412449/why-does-math-round-return-a-long-but-math-floor-return-a-double – starblue

risposta

61

L'intervallo di double è maggiore di quello di long. Per esempio:

double x = Long.MAX_VALUE; 
x = x * 1000; 
x = Math.ceil(x); 

Che cosa vi aspettate l'ultima riga da fare se Math.ceil restituito long?

Si noti che a valori molto grandi (positivi o negativi) i numeri finiscono per essere distribuiti molto scarsamente - quindi il numero intero successivo maggiore del numero intero x non sarà x + 1 se si vede cosa intendo.

+0

Immagino che nella frase finale tu sia parlando di un po 'di precisione, ma penso che non dipenda dal numero elevato ma dal numero di cifre significative (in binario). Proverò a trovare un esempio. – aalku

+0

@ user270349: il divario assoluto tra i doppi valori consecutivi diventa maggiore man mano che il valore aumenta. Il numero di cifre significative rappresentate rimane lo stesso (diverso da quello per i numeri subnormali). –

+2

Esempio: '2^60' può essere rappresentato come doppio mentre' 2^60 (+/-) 1' non può – aalku

13

Una doppia può essere maggiore di Long.MAX_VALUE. Se chiami Math.ceil() su tale valore, ti aspetteresti di restituire lo stesso valore. Tuttavia, se restituiva un valore lungo, il valore sarebbe errato.

+0

i valori 'double' maggiori di' Long.MAX_VALUE' potrebbero non essere rappresentati esattamente, quindi il risultato 'double' di' ceil (big_double) 'non sarà' big_double + 1'. Quindi è ancora errato ... –

+0

@CiprianTomoiaga hai ragione che non sarà big_double +1 in quanto sarebbe big_double. Qualsiasi valore che è troppo grande per essere rappresentato come 'long' non ha alcuna parte frazionaria. –