Wie konvertiere ich ein Double in Long ohne Casting?

190

Was ist der beste Weg, um ein Double in ein Long ohne Casting umzuwandeln?

Beispielsweise:

double d = 394.000;
long l = (new Double(d)).longValue();
System.out.println("double=" + d + ", long=" + l);
Schlitten
quelle
2
stellen Sie sicher , Sie arbeiten nicht mit Doppel mehr als 2 ^ 54 oder Zahlen nicht in die passen Fraktion , so zum Beispiel Ausdrücke wie , myLong == (long)(myDouble + 1)wo myLongequals myDoubleevaluieren zutrue
Vitalii Fedorenko
Diese Methode ( Double.longValue();) ist immer noch nützlich, wenn Sie doppelte Werte von Dingen wie einer Arrayliste wie dieser haben, ArrayList<Double>da Sie einen Fehler erhalten, der nicht gewirkt werden kann. Ich sage das nur für jeden, der hierher gekommen ist und ein etwas anderes Problem hatte.
SARose

Antworten:

250

Angenommen, Sie sind zufrieden mit dem Abschneiden in Richtung Null, dann werfen Sie einfach:

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

Dies ist schneller als das Durchlaufen der Wrapper-Klassen - und was noch wichtiger ist, es ist besser lesbar. Wenn Sie eine andere Rundung als "immer gegen Null" benötigen, benötigen Sie etwas komplizierteren Code.

Jon Skeet
quelle
8
Tolle Antwort - der Teil gegen Null wäre für meine App falsch gewesen, also Applaus dafür, dass Sie dies in Ihrer Antwort hervorgehoben und mein verkatertes Gehirn daran erinnert haben, Math.round () hier zu verwenden, anstatt nur zu gießen!
Phantomwal
123

... und hier ist der Rundungsweg, der nicht abschneidet. Beeilte sich, es im Java API-Handbuch nachzuschlagen:

double d = 1234.56;
long x = Math.round(d); //1235
Johannes Schaub - litb
quelle
Es gibt nicht das gleiche Ergebnis wie eine Besetzung. Es kommt also darauf an, was die Reichen tun wollen.
Cyrille Ka
3
Ja. es wurde als Ergänzung zu dem gedacht, was Jon sagte :)
Johannes Schaub - litb
2
Ich mag das, da es auch mit Double- und Long-Objekten anstatt mit primitiven Typen funktioniert.
themanatuf
57

Der bevorzugte Ansatz sollte sein:

Double.valueOf(d).longValue()

Aus der Double-Dokumentation (Java Platform SE 7) :

Double.valueOf(d)

Gibt eine DoubleInstanz zurück, die den angegebenen doubleWert darstellt. Wenn keine neue DoubleInstanz erforderlich ist, sollte diese Methode im Allgemeinen dem Konstruktor vorgezogen werden Double(double), da diese Methode wahrscheinlich eine erheblich bessere räumliche und zeitliche Leistung liefert, indem häufig angeforderte Werte zwischengespeichert werden.

Leogps
quelle
36

(new Double(d)).longValue() Intern wird nur eine Besetzung durchgeführt, sodass es keinen Grund gibt, ein Double-Objekt zu erstellen.

Michael Myers
quelle
13

Die Guava Math-Bibliothek verfügt über eine Methode, die speziell für die Konvertierung eines Double in ein Long entwickelt wurde:

long DoubleMath.roundToLong(double x, RoundingMode mode)

Mit können Sie java.math.RoundingModedas Rundungsverhalten festlegen.

Tyler 傲 来 国 主
quelle
7

Wenn Sie den starken Verdacht haben, dass das DOPPELTE tatsächlich LANG ist, und Sie möchten

1) Den GENAUEN Wert als LANG erfassen

2) Wirf einen Fehler, wenn er nicht lang ist

Sie können so etwas versuchen:

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 ist eine Teilmenge von Double, sodass Sie möglicherweise seltsame Ergebnisse erzielen, wenn Sie unwissentlich versuchen, ein Double zu konvertieren, das außerhalb des Bereichs von Long liegt:

@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
quelle
Long is a subset of Doubleist nicht genau. Die Anzahl der signifikanten Stellen für Long ist größer als Double. Daher können einige von Long gehaltene Informationen bei der Konvertierung in Double verloren gehen. Beispiel = tio.run/…
Thariq Nugrohotomo
5

Möchten Sie eine binäre Konvertierung wie haben

double result = Double.longBitsToDouble(394.000d);
pvorb
quelle
1
Dies ist das Gegenteil von dem, was gefragt wird.
Lucas Phillips
@ LucasPhillips Du hast recht. Ich muss die Frage falsch verstanden haben, aber ich werde meine Antwort hinterlassen, da sie anderen helfen könnte.
pvorb
1

Einfach durch folgendes:

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

Einfach ausgedrückt ist das Casting effizienter als das Erstellen eines Double-Objekts.

Vijay Dev
quelle