2008-11-26 13 views
134

¿Cuál es la mejor manera de convertir un doble a un largo sin fundición?¿Cómo convertir un doble a largo sin fundición?

Por ejemplo:

double d = 394.000; 
long l = (new Double(d)).longValue(); 
System.out.println("double=" + d + ", long=" + l); 
+2

sólo asegúrese de que no se opera con dobles más de 2^54 o números no caben en la tarjeta [fracción] (http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3), por ejemplo, expresiones como 'myLong == (long) (myDouble + 1)' donde ' myLong' es igual a 'myDouble' se evaluará a' true' –

+0

Este método ('Double.longValue();') sigue siendo útil si tiene valores dobles de cosas como una lista de matrices como 'ArrayList ', ya que obtendrá una no puede lanzar el error Solo digo esto para cualquiera que haya venido y haya tenido un problema ligeramente diferente. – SARose

+0

Su título "conversión doble a larga" no es correcto, su pregunta necesita un título "conversión larga a doble". –

Respuesta

193

Suponiendo que estés satisfecho con truncar hacia cero, justo reparto:

double d = 1234.56; 
long x = (long) d; // x = 1234 

Esto será más rápido que ir a través de las clases de contenedor - y lo más importante, es más legible Ahora, si necesita un redondeo que no sea "siempre hacia cero", necesitará un código un poco más complicado.

+5

Excelente respuesta: la parte hacia cero habría sido incorrecta para mi aplicación, así que aplaudir por resaltar esto en su respuesta, y recordarle a mi cerebro hungover que use Math.round() aquí en lugar de simplemente lanzar. – Phantomwhale

97

... Y aquí está el camino de redondeo que no trunca. Corrió a mirar hacia arriba en el Manual de API de Java:

double d = 1234.56; 
long x = Math.round(d); 
+0

No da el mismo resultado que un elenco. Entonces depende de lo que los ricos quieran hacer. –

+3

sí. se pensó como una adición a lo que Jon dijo :) –

+2

Me gusta esto, ya que también funciona con objetos dobles y largos en lugar de tipos primitivos. – themanatuf

29

(new Double(d)).longValue() internamente sólo lo hace un molde, por lo que no hay razón para crear un objeto doble.

0

En pocas palabras, la fundición es más eficiente que la creación de un objeto doble.

5

es lo que quieres tener una conversión binaria como

double result = Double.longBitsToDouble(394.000d); 
+1

Esto es lo opuesto a lo que se solicita. –

+0

@LucasPhillips Tienes razón. Debo haber leído mal la pregunta, pero dejaré mi respuesta, ya que podría ayudar a otros. – pvorb

10
biblioteca

guayaba Matemáticas tiene un método especialmente diseñado para convertir un doble con una larga:

long DoubleMath.roundToLong(double x, RoundingMode mode) 

Usted puede utilizar java.math.RoundingMode para especificar el comportamiento de redondeo.

16

El enfoque preferido debe ser:

Double.valueOf(d).longValue() 

Desde el Double (Java Platform SE 7) documentation:

Double.valueOf(d) 

devuelve una instancia Double que representa la double valor especificado. Si no se requiere una nueva instancia Double, este método debe usarse preferentemente en lugar del constructor Double(double), ya que es probable que este método produzca un mejor espacio y tiempo mejor rendimiento almacenando en caché valores solicitados con frecuencia.

6

Si usted tiene una fuerte sospecha de que el doble es en realidad un largo, y desea

1) tener una idea de su valor exacto como una larga

2) emite un error cuando que no es un lARGO

puede intentar algo como esto:

public class NumberUtils { 

    /** 
    * Convert a {@link Double} to a {@link Long}. 
    * Method is for {@link Double}s that are actually {@link Long}s and we just 
    * want to get a handle on it as one. 
    */ 
    public static long getDoubleAsLong(double specifiedNumber) { 
     Assert.isTrue(NumberUtils.isWhole(specifiedNumber)); 
     Assert.isTrue(specifiedNumber <= Long.MAX_VALUE && specifiedNumber >= Long.MIN_VALUE); 
     // we already know its whole and in the Long range 
     return Double.valueOf(specifiedNumber).longValue(); 
    } 

    public static boolean isWhole(double specifiedNumber) { 
     // http://stackoverflow.com/questions/15963895/how-to-check-if-a-double-value-has-no-decimal-part 
     return (specifiedNumber % 1 == 0); 
    } 
} 

Long es un subconjunto del doble, por lo que podría obtener algunos resultados extraños si inconscientemente intenta convertir un doble que se encuentra fuera del rango de Long:

@Test 
public void test() throws Exception { 
    // Confirm that LONG is a subset of DOUBLE, so numbers outside of the range can be problematic 
    Assert.isTrue(Long.MAX_VALUE < Double.MAX_VALUE); 
    Assert.isTrue(Long.MIN_VALUE > -Double.MAX_VALUE); // Not Double.MIN_VALUE => read the Javadocs, Double.MIN_VALUE is the smallest POSITIVE double, not the bottom of the range of values that Double can possible be 

    // Double.longValue() failure due to being out of range => results are the same even though I minus ten 
    System.out.println("Double.valueOf(Double.MAX_VALUE).longValue(): " + Double.valueOf(Double.MAX_VALUE).longValue()); 
    System.out.println("Double.valueOf(Double.MAX_VALUE - 10).longValue(): " + Double.valueOf(Double.MAX_VALUE - 10).longValue()); 

    // casting failure due to being out of range => results are the same even though I minus ten 
    System.out.println("(long) Double.valueOf(Double.MAX_VALUE): " + (long) Double.valueOf(Double.MAX_VALUE).doubleValue()); 
    System.out.println("(long) Double.valueOf(Double.MAX_VALUE - 10).longValue(): " + (long) Double.valueOf(Double.MAX_VALUE - 10).doubleValue()); 
} 
Cuestiones relacionadas