web-dev-qa-db-ja.com

キャストせずにダブルをロングに変換する方法は?

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

例えば:

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

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

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

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

232
Jon Skeet

...そして、これが切り捨てられない丸め方法です。 Java APIマニュアルを参照してください:

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

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

Double.valueOf(d).longValue()

Double(Java Platform SE 7)ドキュメント から:

Double.valueOf(d)

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

45
leogps

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

35
Michael Myers

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

long DoubleMath.roundToLong(double x, RoundingMode mode)

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

DOUBLEが実際にはLONG​​であるという強い疑念があり、

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());
}
7
NS du Toit

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

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

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

0
Vijay Dev

単に次の方法で:

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