2015-08-27 5 views
6

Mit dem folgenden Code:Java implizite Konvertierung

Float a = 1.2; 

gibt es einen Fehler, weil es die Dezimalzahl als Doppelwert annimmt und double ist ein größerer Datentyp als float.

Jetzt dauert es Integer als Standard int Typ. Warum gibt der folgende Code keinen Fehler?

Byte b = 20; 
+0

Ich weiß nicht, warum Sie meine Frage nicht verstehen ... Sie sagten, dass der Compiler schlau genug ist, um 20 in Byte zu setzen .... warum setzt der Compiler 1.2 nicht in float .... meine einfachen Fragen war ... ich lese, dass in java alle dezimal als doppelt behandelt werden, während alle Integer standardmäßig als int behandelt werden ...... dann wenn im 20 zu einem Byte zuweisen, warum gibt es keinen Fehler ... –

Antwort

7

Der Compiler ist intelligent genug, um herauszufinden, dass die Bit-Darstellung von 20 (ein int Wert) in ein byte ohne Verlust von Daten passen. Vom Java Language Specification §5.1.3:

Eine Verengung primitive Umwandlung von double zu float wird durch die IEEE 754 Rundungsregeln (§4.2.4) geregelt. Diese Umwandlung kann die Genauigkeit verlieren, aber auch die Reichweite verlieren, was dazu führt, dass eine float Null von 0 bis double und float unendlich von einem endlichen Doppel ist. A double NaN wird in eine float NaN umgewandelt und eine double Unendlichkeit wird in die gleich signierte float Unendlichkeit umgewandelt.

Eine verkleinerte Umwandlung einer vorzeichenbehafteten Ganzzahl in einen ganzzahligen Typ T verwirft einfach alle Bits außer der n niedrigster Ordnung, wobei n die Anzahl der zur Darstellung von Typ T verwendeten Bits ist. Zusätzlich zu einem möglichen Verlust von Informationen über die Größe des numerischen Werts kann dies dazu führen, dass das Vorzeichen des resultierenden Werts vom Vorzeichen des Eingabewerts abweicht.

Siehe auch this thread.

+0

The Bit-Darstellung von 200 passt auch in die 8 Bits von Byte ohne Datenverlust. Wichtig ist, dass derselbe numerische Wert im Zieltyp dargestellt werden kann. – Joni

+0

@Joni - Nun, ja und nein. Weil "Byte" -Werte in Java signiert sind, bedeutet "passen in" wirklich "passen in 7 Bits", nicht 8 Bits. Das Bitmuster von 200 ist '1100 1000'. Wenn dies in einen 8-Bit- "Byte" -Wert gesetzt wird, stellt es den Wert -56 dar, nicht den Wert 200. Dies liegt daran, dass die Darstellung von 200 in das Vorzeichen-Bit eines "Byte" überläuft. Sie haben absolut Recht damit, dass die Repräsentation des gleichen Wertes wichtig ist. –

1

Es gibt keine implizite Verengung Umwandlungen im allgemeinen - konstanten Ausdrücke die einzige Ausnahme ist, und sie werden von JLS ausdrücklich erlaubt 5.2:

Darüber hinaus, wenn der Ausdruck ein konstanter Ausdruck ist (§15.28) von type byte, short, char oder int:

* Eine verengte primitive Konvertierung kann verwendet werden, wenn der Typ der Variablen byte, short oder char ist und der Wert des konstanten Ausdrucks im Typ der Variablen dargestellt werden kann Variable.

Es wird nicht erwähnt, dass implizite verkleinerte Konvertierungen für Fließkommazahlen erlaubt sind, daher sind sie gemäß der allgemeinen Regel verboten.

+0

+1 für den Teil der Spezifikation zitiert, die angibt, warum sich 'float' /' double' anders verhält als 'byte' /' int'. (Abgesehen von der Eingrenzung gibt es im spezifischen Beispiel von OP einen Informationsverlust, weil 1.2 im Fließkomma nicht genau darstellbar ist. Der Compiler würde sich jedoch beschweren, selbst wenn der Wert 1.0 oder etwas anderes genau als "float" darstellbar wäre.) –