Как конвертировать двойной в длинный без приведения? - PullRequest
171 голосов
/ 26 ноября 2008

Каков наилучший способ конвертировать двойное в длинное без приведения?

Например:

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

Ответы [ 9 ]

232 голосов
/ 26 ноября 2008

Предполагая, что вы довольны усечением до нуля, просто приведите:

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

Это будет быстрее, чем проходить через классы-обертки - и, что более важно, это более читабельно. Теперь, если вам нужно округление, отличное от «всегда к нулю», вам понадобится немного более сложный код.

113 голосов
/ 26 ноября 2008

... А вот способ округления, который не усекается. Поспешил посмотреть его в руководстве по Java API:

double d = 1234.56;
long x = Math.round(d);
45 голосов
/ 10 июня 2014

Предпочтительный подход должен быть:

Double.valueOf(d).longValue()

Из документации Double (Java Platform SE 7) :

Double.valueOf(d)

Возвращает экземпляр Double, представляющий указанное значение double. Если новый экземпляр Double не требуется, этот метод должен обычно используется вместо конструктора Double(double), так как этот метод, вероятно, даст значительно лучшее пространство и время производительность путем кэширования часто запрашиваемых значений.

35 голосов
/ 26 ноября 2008

(new Double(d)).longValue() внутренне просто выполняет приведение, поэтому нет смысла создавать объект Double.

11 голосов
/ 14 августа 2012

В библиотеке Guava Math есть метод, специально разработанный для преобразования двойного в длинное:

long DoubleMath.roundToLong(double x, RoundingMode mode)

Вы можете использовать java.math.RoundingMode для указания поведения округления.

7 голосов
/ 04 мая 2015

Если у вас есть сильное подозрение, что ДВОЙНОЙ на самом деле ДОЛГО, и вы хотите

1) получить указатель на его ТОЧНОЕ значение как ДОЛГО

2) выдает ошибку, когда ее не ДЛИННО

Вы можете попробовать что-то вроде этого:

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, поэтому вы можете получить некоторые странные результаты, если неосознанно попытаетесь конвертировать Double вне диапазона 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());
}
5 голосов
/ 21 мая 2012

Хотите ли вы иметь двоичное преобразование типа

double result = Double.longBitsToDouble(394.000d);
0 голосов
/ 10 сентября 2018

Просто следующим образом:

double d = 394.000;
long l = d * 1L;
0 голосов
/ 26 ноября 2008

Проще говоря, приведение более эффективно, чем создание объекта Double.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...