2009-04-24 28 views
21

In un altro esercizio di Bruce Eckel, il codice che ho scritto utilizza un metodo e cambia valore in un'altra classe. Ecco il mio codice:Java: double vs float

class Big { 
    float b; 
} 

public class PassObject { 
    static void f(Letter y) { 
    y.c = 'z'; 
    } //end f() 
    static void g(Big z) { 
    z.b = 2.2; 
    } 

    public static void main(String[] args) { 
    Big t = new Big(); 
    t.b = 5.6; 
    System.out.println("1: t.b : " + t.b); 
    g(x); 
    System.out.println("2: t.b: " + t.b); 
    } //end main 
}//end class 

Si sta generando un errore che dice "Possibile perdita di precisione".

PassObject.java:13: possible loss of precision 
found: double 
required : float z.b = 2.2 
passobject.java:20: possible loss of precision 
found : double 
required : float t.b = 5.6 

Non può double s essere float s come bene?

grazie in anticipo

risposta

29

Sì, ma è necessario specificare che sono galleggianti, altrimenti vengono trattati come doppie:

z.b = 2.2f 

La 'f' alla fine del numero lo rende un float invece di un double.

Java non restringerà automaticamente un doppio rispetto a un valore float.

+0

aggiungendo la "f" risolto. Grazie! – phill

17

No, galleggiante può essere automaticamente upcast a doppie, ma non possono mai essere doppie carri senza cast esplicito perché doppie hanno la gamma più ampia.

gamma galleggiante è 1.40129846432481707e-45-3.40282346638528860e+38

doppia gamma è 4.94065645841246544e-324d-1.79769313486231570e+308d

+9

"I galleggianti possono essere doppi, ma i doppi non possono mai essere galleggianti". questo è sbagliato. i doppi possono essere galleggianti se si trovano nel raggio del galleggiante. –

+0

E se volessi memorizzare come '4.1' in un' float', non posso perché non passa la gamma '3.4xxx'? non riesco a capire il motivo per cui il limite superiore inizia a '3.xxx' quando puoi ovviamente memorizzare' 999.99' senza problemi. Sto indovinando i punti decimali che aggiungi e meno puoi usare davanti al punto decimale? quindi perché '3.XX' non dovrebbe essere' 0.XX' come massimo? – SSpoke

+0

@SSpoke (Non ho mai ricevuto la notifica di questo commento, quindi sto solo rispondendo ora) Quelle gamme sono notazione scientifica ... che è approssimativamente 340,282,346,638,528,860,000,000,000,000,000,000,000,0 in decimale per il limite superiore di un float. – Powerlord

9

Per impostazione predefinita, Java sarà il trattamento di un decimale (per esempio "4.3 ") come double a meno che non altrimenti specificato un float aggiungendo un f dopo il numero (ad esempio" 4.3f").

Stai avendo lo stesso problema su entrambe le linee. Innanzitutto, il decimale letterale viene interpretato come un doppio dal compilatore. Quindi tenta di assegnarlo a b, che è di tipo float. Dal momento che un double è a 64 bit e uno float è a soli 32 bit (vedere Java's primitives documentation), Java indica un errore che indica che lo float non può essere contenuto all'interno dello double. La soluzione è aggiungere un f ai valori letterali decimali.

Se stavi cercando di fare il contrario (cioè assegnare un float ad un double), che sarebbe bene dato che è possibile montare un float 's 32 bit all'interno di un double' s 64.

3
can't doubles be floats as well? 

No. Ogni valore o variabile ha esattamente un tipo (doppio, float, int, long, ecc ...). Lo Java Language Specification indica esattamente cosa succede quando si tenta di assegnare un valore di un tipo a una variabile di un altro tipo. Generalmente, le assegnazioni di un valore "minore" a un tipo "più grande" sono consentite e eseguite in modo implicito, ma le assegnazioni in cui le informazioni potrebbero essere perse perché il tipo di destinazione è troppo "piccolo" per contenere tutti i valori del tipo di origine non sono consentite dal compilatore, anche se il valore concreto si adatta al tipo di destinazione.

Ecco perché il compilatore si lamenta che l'assegnazione di un valore doppio (che letteralmente il letterale è) a una variabile float potrebbe perdere informazioni, e si deve placarlo rendendo il valore a virgola mobile o eseguendo il cast esplicito.

Un'area che spesso causa confusione è costituita da calcoli, perché questi sono implicitamente "allargati" a int per motivi tecnici. Quindi se si moltiplicano due cortocircuiti e si tenta di assegnare il risultato a un cortocircuito, il compilatore si lamenterà perché il risultato del calcolo è un int.

6

Non utilizzare il galleggiante. Non c'è quasi mai una buona ragione per usarlo e non lo è da più di un decennio. Basta usare il doppio.

+1

Immagino che tu non abbia mai fatto uno sviluppo correlato a OpenGL via Java ...: P – User

+1

@Manius Ho fatto negli ultimi 8 anni da quando ho scritto questo GPU più potente ma significa che non c'è molta differenza tra l'uso di float o double per i casi d'uso su cui ho lavorato. Il problema principale è stato alimentare i dati con la GPU abbastanza velocemente. –

+1

concordato. Ti sto solo prendendo un po '(si, questa è una VECCHIA risposta che vedo ora). :) Sarebbe davvero bello se potessimo scaricare i float interamente adesso, ma ... – User

0

intervallo di float inferiore al doppio, quindi un float può essere facilmente rappresentato in doppio, ma non è possibile il contrario perché, diciamo che prendiamo un valore fuori intervallo e durante la convenzione perderemo i dati esatti