Insel: Fließkommazahlen im Hashcode
Anhängig von den Datentypen sehen die Berechnungen immer etwas unterschiedlich aus. Während Ganzzahlen direkt in einen Ganzzahlausdruck für den Hashcode eingebracht werden können, ist im Fall von double die Konvertierungsfunktion Double.doubleToLongBits() beziehungsweise Float.FloatToIntBits() im Einsatz.
Die Datentypen double und float habe eine weitere Spezialität, da NaN und das Vorzeichen der 0 zu beachten sind, wie das Kapitel 5 näher ausführt. Zusammenfassend gesagt: Sind x = +0.0 und y = -0.0, gilt x == y, aber Double.doubleToLongBits(x) != Double.doubleToLongBits(y). Sind x = y = Double.NaN gilt x != y aber Double.doubleToLongBits(x) == Double.doubleToLongBits(y). Wollen wir die beiden Nullen nicht unterschiedlichen behandeln, sondern als gleich werten, ist ein übliches Idiom:
x == 0.0 ? 0L : Double.doubleToLongBits( x )
Es liefert Double.doubleToLongBits(0.0) die Rückgabe 0, aber Double.doubleToLongBits(-0.0) würde -9223372036854775808 geben.
Die Datentypen double und float habe eine weitere Spezialität, da NaN und das Vorzeichen der 0 zu beachten sind, wie das Kapitel 5 näher ausführt. Zusammenfassend gesagt: Sind x = +0.0 und y = -0.0, gilt x == y, aber Double.doubleToLongBits(x) != Double.doubleToLongBits(y). Sind x = y = Double.NaN gilt x != y aber Double.doubleToLongBits(x) == Double.doubleToLongBits(y). Wollen wir die beiden Nullen nicht unterschiedlichen behandeln, sondern als gleich werten, ist ein übliches Idiom:
x == 0.0 ? 0L : Double.doubleToLongBits( x )
Es liefert Double.doubleToLongBits(0.0) die Rückgabe 0, aber Double.doubleToLongBits(-0.0) würde -9223372036854775808 geben.

1 Comments:
Ouch - that's a nasty Gotcha. Very useful to know.
The Java Puzzlers book by Bloch and Gafter has some similar problems.
By
Richard Rodger, at Juli 03, 2006 4:17 PM
Kommentar veröffentlichen
<< Home