最佳方式将double转换为long而不使用强制类型转换是什么?
例如:
double d = 394.000;
long l = (new Double(d)).longValue();
System.out.println("double=" + d + ", long=" + l);
最佳方式将double转换为long而不使用强制类型转换是什么?
例如:
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
... 这里是四舍五入的方式,它不会截断。赶紧在Java API手册中查找:
double d = 1234.56;
long x = Math.round(d); //1235
首选方法应该是:
Double.valueOf(d).longValue()
根据Java 平台 SE 7 Double文档:
Double.valueOf(d)
返回表示指定的
double
值的Double
实例。 如果不需要创建新的Double
实例,则通常应优先使用此方法而不是构造函数Double (double)
, 因为该方法通过缓存经常请求的值,可能会在空间和时间性能方面产生显着的改进。
(new Double(d)).longValue()
内部只是进行了类型转换,所以没有必要创建一个 Double 对象。
Guava Math库有一种专门设计用于将double转换为long的方法:
long DoubleMath.roundToLong(double x, RoundingMode mode)
您可以使用java.math.RoundingMode
指定舍入行为。
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) {
// https://dev59.com/h2Qo5IYBdhLWcg3wiv7A
return (specifiedNumber % 1 == 0);
}
}
Long是Double的子集,所以如果您无意中尝试将超出Long范围的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());
}
只需按照以下步骤:
double d = 394.000;
long l = d * 1L;
最好使用new BigDecimal(s).longValue()
这是我的测试,s是一个长整型值的原始字符串,有时以.0
结尾
将double强制转换为long((long) DoubleValue
)或使用Double.longValue()
有时会丢失1(为什么?)。
https://dev59.com/PGoy5IYBdhLWcg3wJKkq#8754567
1651465142958862337, s
1.65146514295886234E18, Double.parseDouble(s)
1.65146514295886234E18, Double.valueOf(s)
1651465142958862340, String.format("%.0f", Double.parseDouble(s)).split("\\.")[0]
1651465142958862336, (long) Double.parseDouble(s)
1651465142958862336, Double.valueOf(s).longValue()
1651465142958862336, Math.round(Double.parseDouble(s))
1651465142958862337, new BigDecimal(s).longValue() // correct
1.651465142958862337E18, s
1.65146514295886234E18, Double.parseDouble(s)
1.65146514295886234E18, Double.valueOf(s)
1651465142958862340, String.format("%.0f", Double.parseDouble(s)).split("\\.")[0]
1651465142958862336, (long) Double.parseDouble(s)
1651465142958862336, Double.valueOf(s).longValue()
1651465142958862336, Math.round(Double.parseDouble(s))
1651465142958862337, new BigDecimal(s).longValue() // correct
myLong == (long)(myDouble + 1)
这样的表达式,其中myLong
等于myDouble
,将计算为true
。 - Vitalii FedorenkoDouble.longValue();
)仍然有用,如果你有来自像这样的arraylistArrayList<Double>
的双精度值,因为你会得到一个无法转换的错误。我只是为那些遇到略微不同问题的人提供这个信息。 - SARose