Як перетворити подвійний на довгий без кастингу?


191

Який найкращий спосіб перетворити дубль на довгий без кастингу?

Наприклад:

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

2
просто переконайтесь, що ви не оперуєте з парними більше 2 ^ 54, або цифри не впишуться в дріб , тому, наприклад, вирази, як, myLong == (long)(myDouble + 1)де оцінюватимуть myLongрівності myDouble,true
Віталій Федоренко,

Цей метод ( Double.longValue();) все ще корисний, якщо у вас є подвійні значення у таких речей, як масив, як це, ArrayList<Double>оскільки ви отримаєте помилку, що не може привести. Я просто говорю це для всіх, хто прийшов сюди і мав дещо іншу проблему.
SARose

Відповіді:


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

Це не дає такого ж результату, як акторський склад. Тож це залежить від того, що хоче зробити багатий.
Кирила Ка

3
так. це було розглянуто як доповнення до того, що сказав Джон :)
Йоганнес Шауб - ліб

2
Мені це подобається, оскільки він також працює з об'єктами Double та Long, а не з примітивними типами.
themanatuf

58

Кращим підходом має бути:

Double.valueOf(d).longValue()

З документації Double (Java Platform SE 7) :

Double.valueOf(d)

Повертає Doubleекземпляр, що представляє вказане doubleзначення. Якщо новий Doubleекземпляр не потрібен, цей метод, як правило, слід використовувати перевагу конструктору Double(double), оскільки цей метод, ймовірно, дає значно кращі показники простору та часу, кешуючи часто запитувані значення.


36

(new Double(d)).longValue() внутрішньо просто виконує акторський склад, тому немає жодної причини створювати об'єкт Double.


13

Бібліотека Guava Math має метод, спеціально розроблений для перетворення подвійних у довгі:

long DoubleMath.roundToLong(double x, RoundingMode mode)

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


7

Якщо ви маєте сильну підозру, що ДВОЙСТВО насправді ДЛЯ, і ви хочете

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, який знаходиться поза діапазоном Лонга:

@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, тому деяка інформація, яку зберігає Лонг, може бути втрачена при перетворенні в Double. Приклад = tio.run/…
Thariq Nugrohotomo

4

Ви хочете мати бінарне перетворення на кшталт

double result = Double.longBitsToDouble(394.000d);

2
Це протилежне тому, що просять.
Лукас Філіпс

@LucasPhillips Ви маєте рацію. Я, мабуть, неправильно прочитав питання, але я залишу свою відповідь, оскільки це може допомогти іншим.
pvorb


0

Простіше кажучи, трансляція є більш ефективною, ніж створення об’єкта Double.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.