Как конвертировать двойной в длинный без кастинга?

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

Например:

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

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

long DoubleMath.roundToLong(double x, RoundingMode mode)

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

Ответ 5

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

Double.valueOf(d).longValue()

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

Double.valueOf(d)

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

Ответ 6

Если у вас есть сильное подозрение, что DOUBLE на самом деле LONG, и вы хотите

1) получить дескриптор его EXACT значения как 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, поэтому вы можете получить некоторые странные результаты, если вы неосознанно попытаетесь преобразовать Double, который находится за пределами Long range:

@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

Вы хотите иметь двоичное преобразование, например

double result = Double.longBitsToDouble(394.000d);

Ответ 8

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