2012-02-17 23 views
13

Un numero doppio uguale a un intero viene sempre assegnato a quel numero intero (supponendo che il doppio non sia uno che provoca un overflow). Esempio: Math.ceil() restituirà un doppio uguale a un numero intero. Supponendo che non ci sia un overflow, verrà sempre eseguito lo stesso numero intero a cui è presumibilmente uguale?Un numero doppio uguale a un intero viene sempre assegnato a tale intero?

In caso negativo, come è possibile arrotondare un double a int o long?

+0

+1: domanda interessante. Direi che la risposta è "sì", ma potrebbero esserci alcuni casi limite che non ho considerato. –

risposta

9

Poiché tipi Java sono fissi e Java doubles have a 52 bit mantissa, possono (con sicurezza) rappresentano un int Java a 32 bit senza arrotondamento.

+4

La mantissa rappresenta 53 -bit come il primo bit è implicito essere 1. –

1

Credo di sì, ma si potrebbe provare voi stessi:

public static void main(String... args) throws Exception { 
    int interactions = Integer.MAX_VALUE; 
    int i = Integer.MIN_VALUE; 
    double d = Integer.MIN_VALUE; 
    long init = System.currentTimeMillis(); 
    for (; i < interactions; i++, d++) 
     if (!(i == (int) Math.ceil(d))) 
      throw new Exception("something went wrong with i=" + i + " and d=" + d + ", Math.ceil(d)="+Math.ceil(d)); 

    System.out.println("Finished in: "+(System.currentTimeMillis() - init)+"ms"); 
} 
+0

Sono abbastanza sicuro che se lo fai abbastanza a lungo il tuo errore di arrotondamento causerà un problema. (cioè come 0,1 non può essere rappresentato esattamente) –

+0

-1 utilizzando test empirici per tali iterazioni è malvagio come nella maggior parte dei casi fornisce conclusioni errate. –

1

Tutti i possibili int valori possono essere rappresentati da una doppia senza errori. Il modo più semplice per arrotondare è utilizzare Math.ceil() ad es.

double d = 
long l = (long) Math.ceil(d); // note: could overflow. 
+3

Tutti i valori 'int' possono, ma non tutti i valori' long'. –

1

Empiricamente, la risposta sembra essere sì - si noti che funziona anche con i2 = (int) d;.

public static void main(String[] args) { 
    for (int i = Integer.MIN_VALUE + 1; i < Integer.MAX_VALUE; i++) { 
     double d = i; 
     int i2 = (int) Math.ceil(d); 
     if (i != i2) { 
      System.out.println("i=" + i + " and i2=" + i2); //Never executed 
     } 
    } 
} 
+0

È necessario provare anche numeri negativi, ma funzionano anche. –

+0

modificato per iniziare da Integer.MIN_VALUE – assylias

+0

-1 l'utilizzo di test empirici per tali iterazioni è malvagio in quanto nella maggior parte dei casi fornisce conclusioni errate. –

6

Sì, convertirà esattamente. Questo è descritto in Section 5.1.3 del GLS, che menziona

Altrimenti, se il numero a virgola mobile non è un infinito, il valore a virgola mobile viene arrotondato a un valore intero V, arrotondando verso zero con IEEE 754 round-verso zero mode ...

Dal momento che il double equivale esattamente la int, il valore "arrotondato" è solo lo stesso valore esatto, ma si può leggere le specifiche per i dettagli.

Problemi correlati