Comment convertir un double en long sans lancer?

191

Quelle est la meilleure façon de convertir un double en long sans lancer?

Par exemple:

double d = 394.000;
long l = (new Double(d)).longValue();
System.out.println("double=" + d + ", long=" + l);
Traîneau
la source
2
assurez-vous simplement que vous n'opérez pas avec des doubles de plus de 2 ^ 54 ou les nombres ne rentreront pas dans la fraction , donc par exemple des expressions comme myLong == (long)(myDouble + 1)myLongest égal myDoubleàtrue
Vitalii Fedorenko
Cette méthode ( Double.longValue();) est toujours utile si vous avez des valeurs doubles de choses comme une arraylist comme celle-ci, ArrayList<Double>car vous obtiendrez une erreur de conversion impossible. Je dis simplement ceci pour quiconque est venu ici et a eu un problème légèrement différent.
SARose

Réponses:

250

En supposant que vous êtes satisfait de la troncature vers zéro, lancez simplement:

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

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

Jon Skeet
la source
8
Excellente réponse - la partie vers zéro aurait été erronée pour mon application, alors applaudissements pour avoir souligné cela dans votre réponse et rappelé à mon cerveau gueule de bois d'utiliser Math.round () ici au lieu de simplement lancer!
Phantomwhale
123

... Et voici la manière d'arrondir qui ne tronque pas. Dépêché de le rechercher dans le manuel de l'API Java:

double d = 1234.56;
long x = Math.round(d); //1235
Johannes Schaub - litb
la source
Cela ne donne pas le même résultat qu'un casting. Cela dépend donc de ce que les riches veulent faire.
Cyrille Ka
3
Ouais. il a été pensé comme un ajout à ce que Jon a dit :)
Johannes Schaub - litb
2
J'aime cela car cela fonctionne également avec des objets Double et Long plutôt qu'avec des types primitifs.
themanatuf
58

L'approche préférée devrait être:

Double.valueOf(d).longValue()

À partir de la documentation Double (Java Platform SE 7) :

Double.valueOf(d)

Renvoie une Doubleinstance représentant la doublevaleur spécifiée . Si une nouvelle Doubleinstance 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 de générer des performances d'espace et de temps nettement meilleures en mettant en cache les valeurs fréquemment demandées.

léogpes
la source
36

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

Michael Myers
la source
13

La bibliothèque Guava Math a une méthode spécialement conçue pour convertir un double en long:

long DoubleMath.roundToLong(double x, RoundingMode mode)

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

Tyler 傲 来 国 主
la source
7

Si vous avez un fort soupçon que le DOUBLE est en fait un LONG, et que vous voulez

1) obtenir une poignée sur sa valeur EXACT en tant que LONG

2) lancer une erreur quand ce n'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, vous pourriez donc obtenir des résultats étranges si vous essayez sans le savoir de convertir un Double qui est en dehors de la plage 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());
}
NS du Toit
la source
Long is a subset of Doublen'est pas précis. Le nombre de chiffres significatifs pour Long est supérieur à Double, ainsi certaines informations détenues par Long peuvent être perdues lors de la conversion en Double. Exemple = tio.run
Thariq Nugrohotomo
4

C'est le contraire de ce qui est demandé, mais néanmoins, cela pourrait s'avérer utile pour les autres:

Voulez-vous avoir une conversion binaire comme?

double result = Double.longBitsToDouble(394.000d);
pvorb
la source
2
C'est le contraire de ce qui est demandé.
Lucas Phillips
@LucasPhillips Vous avez raison. J'ai dû mal lire la question, mais je laisserai ma réponse car cela pourrait aider les autres.
pvorb
1

Simplement par ce qui suit:

double d = 394.000;
long l = d * 1L;
devll
la source
0

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

Vijay Dev
la source