it-swarm.com.de

Wie konvertiere ich ein Double zu Long ohne Casting?

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

Zum Beispiel:

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

Angenommen, Sie sind zufrieden mit dem Abschneiden auf Null, werfen Sie einfach Folgendes aus:

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

Dies ist schneller als durch die Wrapper-Klassen - und vor allem lesbarer. Wenn Sie eine andere Rundung als "immer gegen Null" benötigen, benötigen Sie etwas komplizierteren Code.

226
Jon Skeet

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

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

Der bevorzugte Ansatz sollte sein:

Double.valueOf(d).longValue()

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

Double.valueOf(d)

Gibt eine Double-Instanz zurück, die den angegebenen double-Wert darstellt Wenn keine neue Double-Instanz erforderlich ist, sollte diese Methode wird im Allgemeinen dem Konstruktor Double(double), .__ vorgezogen. da diese Methode wahrscheinlich wesentlich besseren Raum und Zeit bietet Leistung durch Zwischenspeicherung häufig angeforderter Werte.

40
leogps

(new Double(d)).longValue() führt intern nur eine Besetzung durch, sodass es keinen Grund gibt, ein Double-Objekt zu erstellen.

34
Michael Myers

Die Bibliothek von Guava Math 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 Java.math.RoundingMode können Sie das Rundungsverhalten angeben.

Wenn Sie einen starken Verdacht haben, dass das DOUBLE tatsächlich ein LANG ist, und Sie möchten

1) den EXACT-Wert als LONG in den Griff bekommen

2) einen Fehler auslösen, wenn es 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. Wenn Sie also unwissentlich versuchen, ein Double zu konvertieren, das außerhalb des Bereichs von Long liegt, erhalten Sie möglicherweise seltsame Ergebnisse:

@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

Möchten Sie eine binäre Konvertierung haben?

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

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

0
Vijay Dev

Einfach durch Folgendes:

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