2011-10-21 12 views
16

Eventuali duplicati:
Varying behavior for possible loss of precisionJava interrompe la digitazione! Chi può spiegarlo?

ho trovato un'inconsistenza in Java forte controllo di battitura al momento della compilazione. Si prega di guardare il seguente codice:

int sum = 0; 
sum = 1; //is is OK 
sum = 0.56786; //compile error because of precision loss, and strong typing 
sum = sum + 2; //it is OK 
sum += 2; //it is OK 
sum = sum + 0.56787; //compile error again because of automatic conversion into double, and possible precision loss 
sum += 0.56787; //this line is does the same thing as the previous line, but it does not give us a compile error, and javac does not complain about precision loss etc. 

Qualcuno può spiegare a me? È un bug noto o un comportamento desiderato? C++ dà un avvertimento, C# dà un errore di compilazione.

Java interrompe la digitazione? Puoi sostituire + = con - = o * = - tutto è accettabile da un compilatore.

+0

strana è che si memorizzano galleggiante variabile int –

+3

@ KarelFrajtak Un numero decimale senza un modificatore (come 'd' o' f') è un doppio, non un float. Inoltre, penso che potresti perdere il punto .. – nfechner

+1

Java ha chiaramente fatto un errore qui. Dovevano essere più precisi quando è permesso il cast silenzioso. E la ragione per le radici gettate in un'altra cattiva decisione. La specifica sulle operazioni di tipo intero è un pasticcio puzzolente. – irreputable

risposta

28

Questo comportamento è definito dalla lingua (ed è quindi OK). Da the JLS:

15.26.2 operatori composti assegnazione

Un'espressione assegnazione composta del op modulo E1 = E2 è equivalente a E1 = (T) ((E1) op (E2)) , dove T è il tipo di E1, tranne che E1 viene valutato solo una volta. Ad esempio, il seguente codice è corretto:

short x = 3; 
x += 4.6; 

e determina x aventi il ​​valore 7 perché è equivalente a:

short x = 3; 
x = (short)(x + 4.6); 
+4

Questo è qualcosa che viene spesso sottovalutato, tendiamo a pensare + = è solo una versione più breve da scrivere, ma ha altre implicazioni. Buon consiglio da ricordare – Ewald

+0

non va bene. java è sbagliato. non c'è motivo per cui l'esempio debba essere compilato. – irreputable

+4

@irreputable - beh, questo è qualcosa da fare con il designer del linguaggio; il compilatore è conforme alle specifiche. – McDowell

5

compila perché il compilatore è la conversione

sum += 0.56787; 

a

sum = (int)(sum + 0.56787); 
+1

È possibile fornire un collegamento a un documento, che spiega questo comportamento. Ho pensato che il comportamento normale è la conversione automatica in un tipo con maggiore precisione. –

+1

Il cast viene eseguito dopo l'aggiunta, non prima. Vedi la risposta migliore. –

3

Questo non ha nulla a che fare con la tipizzazione forte ma solo con regole diverse per le conversioni implicite.

Stai guardando due diversi operatori qui. Nel primo caso, è presente l'operatore di assegnazione semplice "=" che non consente l'assegnazione di double a int. Nel secondo caso, è disponibile l'operatore di assegnazione composto "+ =" che consente di aggiungere double a int convertendo prima il valore double in uno int.

+0

Sì, ma questo è molto diverso da come funzionano le cose in C++ o C#. –

+0

Certo, si tratta di regole specifiche Java da JLS. –

+1

Eh? La scelta delle regole per le conversioni implicite, per definizione, si basa su una digitazione forte o debole. –

Problemi correlati