web-dev-qa-db-fra.com

Comment convertir un double en long sans casting?

Quel est le meilleur moyen de convertir un double en long sans casting?

Par exemple:

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

En supposant que vous soyez satisfait de tronquer 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'arrondi autre que "toujours vers zéro", vous aurez besoin d'un code légèrement plus compliqué.

226
Jon Skeet

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

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

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

Double.valueOf(d).longValue()

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

Double.valueOf(d)

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

40
leogps

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

34
Michael Myers

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

long DoubleMath.roundToLong(double x, RoundingMode mode)

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

Si vous soupçonnez fort que le DOUBLE est en réalité un LONG, et que vous voulez

1) avoir une idée de sa valeur exacte en tant que LONG

2) jeter 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 pouvez donc obtenir des résultats étranges si vous essayez inconsciemment 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());
}
7
NS du Toit

Voulez-vous avoir une conversion binaire comme

double result = Double.longBitsToDouble(394.000d);
5
pvorb

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

0
Vijay Dev

Simplement par ce qui suit:

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