Bagaimana mengkonversi ganda menjadi panjang tanpa casting?

191

Apa cara terbaik untuk mengubah ganda menjadi panjang tanpa casting?

Sebagai contoh:

double d = 394.000;
long l = (new Double(d)).longValue();
System.out.println("double=" + d + ", long=" + l);
Kereta luncur
sumber
2
pastikan Anda tidak beroperasi dengan ganda lebih dari 2 ^ 54 atau angka tidak akan masuk ke dalam fraksi , jadi misalnya ekspresi seperti di myLong == (long)(myDouble + 1)mana myLongpersamaan myDoubleakan dievaluasitrue
Vitalii Fedorenko
Metode ini ( Double.longValue();) masih berguna jika Anda memiliki nilai ganda dari hal-hal seperti daftar array seperti ini ArrayList<Double>karena Anda akan mendapatkan kesalahan yang tidak bisa dilemparkan. Saya hanya mengatakan ini untuk siapa pun yang datang ke sini dan memiliki masalah yang sedikit berbeda.
SARose

Jawaban:

250

Dengan asumsi Anda senang memotong nol, cukup masukkan:

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

Ini akan lebih cepat daripada melalui kelas wrapper - dan yang lebih penting, ini lebih mudah dibaca. Sekarang, jika Anda membutuhkan pembulatan selain "selalu menuju nol" Anda akan memerlukan kode yang sedikit lebih rumit.

Jon Skeet
sumber
8
Jawaban yang bagus - bagian nol menuju akan salah untuk aplikasi saya, jadi tepuk tangan untuk menyoroti ini dalam jawaban Anda, dan mengingatkan otak saya untuk menggunakan Math.round () di sini, bukan hanya casting!
Phantomwhale
123

... Dan inilah cara pembulatan yang tidak terpotong. Terburu-buru mencarinya di Java API Manual:

double d = 1234.56;
long x = Math.round(d); //1235
Johannes Schaub - litb
sumber
Itu tidak memberikan hasil yang sama seperti pemain. Jadi itu tergantung pada apa yang ingin dilakukan orang kaya.
Cyrille Ka
3
ya. itu dianggap sebagai tambahan untuk apa yang dikatakan Jon :)
Johannes Schaub - litb
2
Saya suka ini karena ini juga bekerja dengan objek Double dan Long daripada tipe primitif.
themanatuf
58

Pendekatan yang disukai harus:

Double.valueOf(d).longValue()

Dari dokumentasi Double (Java Platform SE 7) :

Double.valueOf(d)

Mengembalikan Doubleinstance yang mewakili nilai yang ditentukan double. Jika Doubleinstance baru tidak diperlukan, metode ini umumnya harus digunakan dalam preferensi untuk konstruktor Double(double), karena metode ini cenderung menghasilkan ruang dan waktu kinerja yang jauh lebih baik dengan caching nilai yang sering diminta.

leogps
sumber
36

(new Double(d)).longValue() secara internal hanya melakukan pemeran, jadi tidak ada alasan untuk membuat objek ganda.

Michael Myers
sumber
13

Perpustakaan Guava Math memiliki metode yang dirancang khusus untuk mengkonversi ganda menjadi panjang:

long DoubleMath.roundToLong(double x, RoundingMode mode)

Anda bisa menggunakan java.math.RoundingModeuntuk menentukan perilaku pembulatan.

Tyler 傲 来 国 主
sumber
7

Jika Anda memiliki kecurigaan yang kuat bahwa GANDA sebenarnya PANJANG, dan Anda ingin

1) dapatkan pegangan pada nilai EXACT sebagai PANJANG

2) melempar kesalahan saat ini bukan PANJANG

Anda dapat mencoba sesuatu seperti ini:

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 adalah himpunan bagian dari Double, jadi Anda mungkin mendapatkan beberapa hasil aneh jika Anda tanpa sadar mencoba mengonversi Double yang berada di luar rentang 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
sumber
Long is a subset of Doubletidak akurat. Jumlah digit signifikan untuk Long lebih besar dari Double, sehingga beberapa informasi yang dimiliki Long dapat hilang ketika dikonversi ke Double. Contoh = tio.run/…
Thariq Nugrohotomo
4

Anda ingin memiliki konversi biner seperti

double result = Double.longBitsToDouble(394.000d);
pvorb
sumber
2
Ini kebalikan dari apa yang ditanyakan.
Lucas Phillips
@LucasPhillips Anda benar. Saya pasti salah membaca pertanyaan, tetapi saya akan meninggalkan jawaban saya karena mungkin membantu orang lain.
pvorb
1

Cukup dengan yang berikut ini:

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

Sederhananya, casting lebih efisien daripada menciptakan objek Double.

Vijay Dev
sumber