Nasıl döküm olmadan bir çift uzun dönüştürmek için?


191

Bir çifte döküm olmadan uzun bir dönüştürmek için en iyi yolu nedir?

Örneğin:

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

2
Sadece çiftlerde ile çalıştırmayın emin olun fazla 2 ^ 54 veya içine sığmaz sayılar kesir şöyle örnek ifadeleri, myLong == (long)(myDouble + 1)nerede myLongeşittir myDoubledeğerlendirecektrue
Vitalii Fedorenko

Bu yöntem ( Double.longValue();), böyle bir arraylist gibi şeylerden çift değerleriniz varsa, ArrayList<Double>çünkü bir yayınlama hatası alamayacağınız için yararlıdır . Bunu buraya gelen ve biraz farklı bir problemi olan herkes için söylüyorum.
SARose

Yanıtlar:


250

Sıfıra doğru kesmekten memnun olduğunuzu varsayarsak, sadece yayınlayın:

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

Bu, sarmalayıcı sınıflarından geçmekten daha hızlı olacaktır - ve daha da önemlisi, daha okunabilir. Şimdi, "her zaman sıfıra doğru" dışında bir yuvarlamaya ihtiyacınız varsa, biraz daha karmaşık bir koda ihtiyacınız olacaktır.


8
Harika cevap - sıfır bölüme doğru benim app için yanlış olurdu, bu yüzden cevabınızda bunu vurgulamak için alkışlamak ve sadece döküm yerine burada hungover beynim Math.round () kullanmak için hatırlatmak!
Phantomwhale

123

... Ve burada kısalmayan yuvarlama yolu. Java API Kılavuzu'nda aramak için acele edin:

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

Oyuncularla aynı sonucu vermez. Bu yüzden zenginlerin ne yapmak istediğine bağlı.
Cyrille Ka

3
Evet. Jon'un söylediklerine ek olarak düşünülüyordu :)
Johannes Schaub - litb

2
İlkel türler yerine Çift ve Uzun nesnelerle de çalıştığı için bunu seviyorum.
themanatuf

58

Tercih edilen yaklaşım şöyle olmalıdır:

Double.valueOf(d).longValue()

Gönderen Çift (Java Platform SE 7) belgelerinde :

Double.valueOf(d)

DoubleBelirtilen doubledeğeri temsil eden bir örnek döndürür . Yeni bir Doubleörnek gerekli değilse, bu yöntem genellikle yapıcı yerine tercih edilmelidir Double(double), çünkü bu yöntem sıkça istenen değerleri önbelleğe alarak önemli ölçüde daha iyi alan ve zaman performansı sağlar.


36

(new Double(d)).longValue() dahili olarak sadece bir döküm yapar, bu nedenle bir Double nesnesi oluşturmak için bir neden yoktur.


13

Guava Math kütüphanesi, bir çiftin uzunluğa dönüştürülmesi için özel olarak tasarlanmış bir yönteme sahiptir:

long DoubleMath.roundToLong(double x, RoundingMode mode)

java.math.RoundingModeYuvarlama davranışını belirtmek için kullanabilirsiniz .


7

ÇİFTİN aslında UZUN olduğuna dair güçlü bir şüpheniz varsa ve

1) UZUN olarak EXACT değerine sahip olun

2) UZUN olmadığında bir hata atın

böyle bir şey deneyebilirsiniz:

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, Double'in bir alt kümesidir, bu nedenle bilmeden Long aralığının dışındaki bir Double'i dönüştürmeye çalışırsanız garip sonuçlar alabilirsiniz:

@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());
}

Long is a subset of Doubledoğru değil. Long için anlamlı basamak sayısı Double değerinden daha fazladır, bu nedenle Long tarafından tutulan bazı bilgiler Double'e dönüştürüldüğünde kaybolabilir. Örnek = tio.run/…
Thariq Nugrohotomo

4

Gibi bir ikili dönüşüm yapmak ister misiniz?

double result = Double.longBitsToDouble(394.000d);

2
Bu sorulanın tam tersidir.
Lucas Phillips

@LucasPhillips Haklısın. Soruyu yanlış okumalıydım, ama başkalarına yardımcı olabileceğinden cevabımı bırakacağım.
14'te

1

Sadece aşağıdakiler yoluyla:

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

0

Basitçe söylemek gerekirse, döküm bir Double nesnesi oluşturmaktan daha verimlidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.