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);
}
}
@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());
}
9条答案
按热度按时间7nbnzgx91#
假设你对向零截断很满意,那么就投:
这将比通过 Package 器类更快-更重要的是,它更具可读性。现在,如果您需要舍入而不是“总是向零”,则需要稍微复杂一些的代码。
7cwmlq892#
...这是一个不截断的圆化方法。赶紧在Java API手册中查找它:
mo49yndu3#
最好的办法应该是:
从Double(Java Platform SE 7)文档中:
返回表示指定
double
值的Double
示例。如果不需要新的Double
示例,通常应该优先使用此方法而不是构造函数Double(double)
,因为此方法可能会通过缓存频繁请求的值来产生更好的空间和时间性能。nimxete24#
(new Double(d)).longValue()
在内部只进行强制转换,因此没有理由创建Double对象。lmyy7pcs5#
Guava Math库有一个专门设计用于将double转换为long的方法:
可以使用
java.math.RoundingMode
指定舍入行为。rks48beu6#
如果你强烈怀疑DOUBLE实际上是多头,并且你想
1)获取其EXACT值的句柄作为LONG
2)抛出一个错误,当它不是一个长
你可以试试这样的方法:
Long是Double的一个子集,因此如果您无意中尝试转换超出Long范围的Double,可能会得到一些奇怪的结果:
cwxwcias7#
简单地说就是:
z18hc3ub8#
简单地说,造型比创建Double对象更有效。
yizd12fk9#
最好使用
new BigDecimal(s).longValue()
这是我的测试,s是一个长值的原始字符串,有时以
.0
结尾将double转换为long(
(long) DoubleValue
)或Double.longValue()
有时会丢失1(为什么?).https://stackoverflow.com/a/8754567/6494418