generic ejemplo java double boxing

ejemplo - java generics



Java firmó cero y boxeo (3)

Últimamente escribí un proyecto en Java y noté una característica muy extraña con la implementación doble / doble. El tipo doble en Java tiene dos 0, es decir, 0.0 y -0.0 (firmados con cero). Lo extraño es que:

0.0 == -0.0

se evalúa como true , pero:

new Double(0.0).equals(new Double(-0.0))

evalúa a false . ¿Alguien sabe la razón detrás de esto?


Al usar la declaración == está comparando valores. Con iguales estás comparando objetos.


Es importante entender el uso del cero firmado en la clase Doble. (Un montón de experimentados programadores de Java no).

La respuesta corta es que (por definición) "-0.0 es menor que 0.0" en todos los métodos proporcionados por la clase doble (es decir, igual a (), comparar (), comparar a (), etc.)

El doble permite que todos los números de punto flotante estén "totalmente ordenados en una línea numérica". Los primitivos se comportan de la manera en que un usuario piensa las cosas (una definición del mundo real) ... 0d = -0d

Los siguientes fragmentos ilustran el comportamiento ...

final double d1 = 0d, d2 = -0d; System.out.println(d1 == d2); //prints ... true System.out.println(d1 < d2); //prints ... false System.out.println(d2 < d1); //prints ... false System.out.println(Double.compare(d1, d2)); //prints ... 1 System.out.println(Double.compare(d2, d1)); //prints ... -1

Hay otras publicaciones que son relevantes y explican muy bien el fondo ...

1: ¿Por qué los números de coma flotante tienen ceros firmados?

2: ¿Por qué se implementa Double.compare de Java (doble, doble) de la forma en que está?

Y una palabra de precaución ...

Si no sabe que, en la clase doble, "-0.0 es menor que 0.0" , puede quedar atrapado al usar métodos como equals () y comparar () y compareTo () desde el doble en pruebas lógicas. Por ejemplo, mira ...

final double d3 = -0d; // try this code with d3 = 0d; for comparison if (d3 < 0d) { System.out.println("Pay 1 million pounds penalty"); } else { System.out.println("Good things happen"); // this line prints } if (Double.compare(d3, 0d) < 0) { //use Double.compare(d3, -0d) to match the above behaviour System.out.println("Pay 1 million pounds penalty"); // this line prints } else { System.out.println("Good things happen"); }

y para iguales puedes probar ... nuevo Double (d3) .equals (0d) || nuevo Double (d3) .equals (-0d)


Todo se explica en el javadoc :

Tenga en cuenta que en la mayoría de los casos, para dos instancias de la clase Double, d1 y d2, el valor de d1.equals (d2) es verdadero si y solo si

d1.doubleValue() == d2.doubleValue()

también tiene el valor verdadero. Sin embargo, hay dos excepciones:

  • Si d1 y d2 representan ambos Double.NaN, el método equals devuelve true, aunque Double.NaN == Double.NaN tiene el valor false.
  • Si d1 representa +0.0 mientras d2 representa -0.0, o viceversa, la prueba igual tiene el valor falso, aunque +0.0 == - 0.0 tiene el valor verdadero.

Esta definición permite que las tablas hash funcionen correctamente.

Ahora puede preguntar por qué 0.0 == -0.0 es verdadero. De hecho no son estrictamente idénticos. Por ejemplo:

Double.doubleToRawLongBits(0.0) == Double.doubleToRawLongBits(-0.0); //false

Es falso. Sin embargo, el JLS requiere (" de acuerdo con las reglas de la norma IEEE 754 ") que:

Cero positivo y cero negativo se consideran iguales.

por lo tanto, 0.0 == -0.0 es verdadero.