2008-11-26 6 views
134

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

Например:

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

просто убедитесь, что вы не работают с двойниками более 2^54 или номера не будут вписываться в [фракции] (http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3), поэтому, например, выражения типа `myLong == (long) (myDouble + 1)` где ` myLong` равно `myDouble` будет оцениваться как` true` – 2012-01-26 23:55:01

+0

Этот метод (`Double.longValue();`) по-прежнему полезен, если у вас есть двойные значения от таких вещей, как arraylist, вроде этого `ArrayList `, так как вы получите не может выдавать ошибку. Я просто говорю это для всех, кто пришел сюда, и имел немного другую проблему. – SARose 2014-12-30 07:19:03

+0

Ваше название «double to long conversion» неверно, ваш вопрос требует заголовка «long to double conversion». – 2015-11-25 11:52:24

ответ

193

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

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

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

+5

Отличный ответ - в сторону нулевой части было бы неправильно для моего приложения, поэтому аплодисменты за то, что вы выделили это в своем ответе, и напоминая моему голодному мозгу использовать Math.round() здесь, а не просто кастинг! – Phantomwhale 2011-12-09 04:54:13

97

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

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

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

0

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

5

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

double result = Double.longBitsToDouble(394.000d); 
10

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

long DoubleMath.roundToLong(double x, RoundingMode mode) 

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

16

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

Double.valueOf(d).longValue() 

Из Double (Java Platform SE 7) documentation:

Double.valueOf(d) 

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

6

Если у вас есть сильное подозрение, что 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, так что вы могли бы получить какие-то странные результаты, если вы неосознанно пытаются преобразовать 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()); 
} 
Смежные вопросы