2008-11-26 11 views
134

Quelle est la meilleure façon de convertir un double en un long sans coulée?Comment convertir un double en long sans coulée?

Par exemple:

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

assurez-vous de ne pas disponible avec les doubles plus de 2^54 ou numéros ne rentrent pas dans la [fraction] (http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3), par exemple des expressions comme 'myLong == (long) (myDouble + 1)' où ' myLong' équivaut à 'myDouble' va évaluer' true' –

+0

Cette méthode ('Double.longValue();') est toujours utile si vous avez des valeurs doubles à partir de choses comme un arraylist comme ceci 'ArrayList ' puisque vous aurez un ne peut pas lancer d'erreur. Je dis juste ceci pour n'importe qui qui est venu ici et a eu un problème légèrement différent. – SARose

+0

Votre titre "double to long conversion" n'est pas correct, votre question nécessite un titre "long to double conversion". –

Répondre

193

En supposant que vous êtes satisfait de tronquant vers zéro, juste jeté:

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

Ce sera plus rapide que passer par les classes d'emballage - et plus important encore, il est plus lisible. Maintenant, si vous avez besoin d'arrondir autre que "toujours vers zéro", vous aurez besoin d'un code légèrement plus compliqué.

+5

Bonne réponse - la partie vers zéro aurait été erronée pour mon application, alors applaudissements pour la mettre en évidence dans votre réponse, et rappelant à mon cerveau de gueule de bois d'utiliser Math.round() ici au lieu de simplement lancer! – Phantomwhale

97

... Et voici le chemin d'arrondi qui ne tronque pas. Se hâta de le chercher dans l'API Java Manuel:

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

Il ne donne pas le même résultat qu'un cast. Cela dépend donc de ce que les riches veulent faire. –

+3

ouais. il a été pensé comme un ajout à ce que Jon a dit :) –

+2

J'aime ça car il fonctionne aussi avec des objets Double et Long plutôt qu'avec des types primitifs. – themanatuf

29

(new Double(d)).longValue() interne ne vient un casting, donc il n'y a aucune raison de créer un objet Double.

0

En d'autres termes, la conversion est plus efficace que la création d'un objet Double.

5

Est-ce que vous voulez avoir une conversion binaire comme

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

C'est le contraire de ce qui est demandé. –

+0

@LucasPhillips Vous avez raison. Je dois avoir mal lu la question, mais je vais laisser ma réponse, car cela pourrait aider les autres. – pvorb

10

Goyave bibliothèque Math a une méthode spécialement conçue pour convertir un double à une longue:

long DoubleMath.roundToLong(double x, RoundingMode mode) 

Vous pouvez utiliser java.math.RoundingMode pour spécifier le comportement d'arrondi.

16

L'approche privilégiée devrait être:

Double.valueOf(d).longValue() 

De l'Double (Java Platform SE 7) documentation:

Double.valueOf(d) 

Renvoie une Double instance représentant la valeur spécifiée double. Si une nouvelle instance Double n'est pas requise, cette méthode doit généralement être utilisée de préférence au constructeur Double(double), car cette méthode est susceptible d'améliorer significativement l'espace et le temps en mettant en cache les valeurs fréquemment demandées.

6

Si vous avez une forte suspicion que le DOUBLE est en fait une longue et que vous voulez

1) obtenir une poignée sur sa valeur EXACT comme LONG

2) lancer une erreur lors de ne est pas un lONG

vous pouvez essayer quelque chose comme ceci:

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 est un sous-ensemble de double, de sorte que vous pourrait obtenir des résultats étranges si vous essayez sans le savoir pour convertir un double qui est en dehors de la gamme 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()); 
} 
Questions connexes