Каков наилучший способ конвертировать двойной в длинный без литья?Как конвертировать двойной в длинный без кастинга?
Например:
double d = 394.000;
long l = (new Double(d)).longValue();
System.out.println("double=" + d + ", long=" + l);
Каков наилучший способ конвертировать двойной в длинный без литья?Как конвертировать двойной в длинный без кастинга?
Например:
double d = 394.000;
long l = (new Double(d)).longValue();
System.out.println("double=" + d + ", long=" + l);
Предполагая, что вы будете довольны усечения к нулю, просто отбрасывать:
double d = 1234.56;
long x = (long) d; // x = 1234
Это будет быстрее, чем идти через классы обертки - и что еще более важно, это более читаемым. Теперь, если вам нужно округлить, кроме «всегда к нулю», вам понадобится немного более сложный код.
Отличный ответ - в сторону нулевой части было бы неправильно для моего приложения, поэтому аплодисменты за то, что вы выделили это в своем ответе, и напоминая моему голодному мозгу использовать Math.round() здесь, а не просто кастинг! – Phantomwhale 2011-12-09 04:54:13
... И вот круглый способ, который не усекает. Поспешил, чтобы посмотреть его в Руководстве по API Java:
double d = 1234.56;
long x = Math.round(d);
(new Double(d)).longValue()
внутри просто делает бросок, так что нет никаких оснований для создания Double объекта.
Проще говоря, литье более эффективно, чем создание двойного объекта.
Вы хотите иметь двоичное преобразование как
double result = Double.longBitsToDouble(394.000d);
гуавы Math библиотека имеет метод, специально разработанный для преобразования двойной длинный:
long DoubleMath.roundToLong(double x, RoundingMode mode)
Вы можете использовать java.math.RoundingMode
, чтобы указать округление.
Предпочтительный подход должен быть:
Double.valueOf(d).longValue()
Из Double (Java Platform SE 7) documentation:
Double.valueOf(d)
возвращает экземпляр
Double
, представляющую определенныйdouble
значение. Если новыйDouble
экземпляр не требуется, этот метод должен быть , как правило, предпочтительно использовать конструкторDouble(double)
, , так как этот способ может обеспечить значительно лучшее пространство и время производительность путем кэширования часто запрашиваемых значений.
Если у вас есть сильное подозрение, что 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());
}
просто убедитесь, что вы не работают с двойниками более 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
Этот метод (`Double.longValue();`) по-прежнему полезен, если у вас есть двойные значения от таких вещей, как arraylist, вроде этого `ArrayList`, так как вы получите не может выдавать ошибку. Я просто говорю это для всех, кто пришел сюда, и имел немного другую проблему. –
SARose
2014-12-30 07:19:03
Ваше название «double to long conversion» неверно, ваш вопрос требует заголовка «long to double conversion». – 2015-11-25 11:52:24