キャストせずにdoubleをlongに変換する方法は?


191

キャストせずにdoubleをlongに変換する最良の方法は何ですか?

例えば:

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

2
2 ^ 54を超えるmyLong == (long)(myDouble + 1)myLongmyDoubletrue
倍数で演算

このメソッド(Double.longValue();)はArrayList<Double>、キャストできないエラーが発生するため、このようなarraylistのようなものからdouble値がある場合にも役立ちます。ここに来て少し違う問題を抱えた人のために言っているだけです。
SARose 2014

回答:


250

あなたがゼロに向かって切り捨てることに満足していると仮定して、キャストしてください:

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

これは、ラッパークラスを経由するよりも速くなります-さらに重要なことに、より読みやすくなります。ここで、「常にゼロに向かって」以外の丸めが必要な場合は、もう少し複雑なコードが必要になります。


8
素晴らしい答え-私のアプリではゼロに向かっている部分が間違っていたので、これを答えで強調し、二日酔いの頭に、キャストするだけでなく、ここでMath.round()を使用することを思い出させてください!
Phantomwhale

123

...そして、これは切り捨てない丸め方です。Java APIマニュアルで早急に調べてください。

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

キャストと同じ結果にはなりません。だからそれは金持ちが何をしたいかによって異なります。
Cyrille Ka

3
ええ。それはジョンが言ったことへの追加であると考えられました:)
ヨハネス・シャウブ-litb

2
これはプリミティブ型ではなくDoubleおよびLongオブジェクトでも機能するので、私はこれが好きです。
themanatuf

58

推奨されるアプローチは次のとおりです。

Double.valueOf(d).longValue()

ダブル(JavaプラットフォームSE 7)のドキュメント

Double.valueOf(d)

Double指定されたdouble値を表すインスタンスを返します。新しいDoubleインスタンスが不要な場合、このメソッドはDouble(double)、頻繁に要求される値をキャッシュすることにより、スペースと時間のパフォーマンスが大幅に向上する可能性があるため、通常、コンストラクターよりも優先して使用する必要があります。


36

(new Double(d)).longValue() 内部的にはキャストを行うだけなので、Doubleオブジェクトを作成する理由はありません。


13

Guava Mathライブラリには、doubleをlongに変換するために特別に設計されたメソッドがあります。

long DoubleMath.roundToLong(double x, RoundingMode mode)

を使用java.math.RoundingModeして、丸め動作を指定できます。


7

DOUBLEが実際には長いという強い疑念があり、

1)正確な値のハンドルをLONGとして取得します

2)LONGでない場合にエラーをスローする

あなたはこのようなことを試すことができます:

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のサブセットであるため、知らずにLongの範囲外のDoubleを変換しようとすると、奇妙な結果が得られる可能性があります。

@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 Double正確ではありません。Longの有効桁数はDoubleよりも大きいため、Longが保持する一部の情報はDoubleに変換すると失われる可能性があります。例= tio.run
Thariq Nugrohotomo

4

次のようなバイナリ変換が必要ですか?

double result = Double.longBitsToDouble(394.000d);

2
これは、求められていることの逆です。
Lucas Phillips

@LucasPhillipsそうですね。質問を誤解したに違いありませんが、他の人の役に立つかもしれないので、私は答えを残しておきます。
pvorb 14年

1

単に次のように:

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

0

簡単に言うと、Doubleオブジェクトを作成するよりもキャストの方が効率的です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.