java 如何在不进行强制转换的情况下将double转换为long?

l7wslrjt  于 2023-05-21  发布在  Java
关注(0)|答案(9)|浏览(109)

什么是最好的方法来转换一个双到一个长期没有铸造?
例如:

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

7nbnzgx91#

假设你对向零截断很满意,那么就投:

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

这将比通过 Package 器类更快-更重要的是,它更具可读性。现在,如果您需要舍入而不是“总是向零”,则需要稍微复杂一些的代码。

7cwmlq89

7cwmlq892#

...这是一个不截断的圆化方法。赶紧在Java API手册中查找它:

double d = 1234.56;
long x = Math.round(d); //1235
mo49yndu

mo49yndu3#

最好的办法应该是:

Double.valueOf(d).longValue()

从Double(Java Platform SE 7)文档中:

Double.valueOf(d)

返回表示指定double值的Double示例。如果不需要新的Double示例,通常应该优先使用此方法而不是构造函数Double(double),因为此方法可能会通过缓存频繁请求的值来产生更好的空间和时间性能。

nimxete2

nimxete24#

(new Double(d)).longValue()在内部只进行强制转换,因此没有理由创建Double对象。

lmyy7pcs

lmyy7pcs5#

Guava Math库有一个专门设计用于将double转换为long的方法:

long DoubleMath.roundToLong(double x, RoundingMode mode)

可以使用java.math.RoundingMode指定舍入行为。

rks48beu

rks48beu6#

如果你强烈怀疑DOUBLE实际上是多头,并且你想
1)获取其EXACT值的句柄作为LONG
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的一个子集,因此如果您无意中尝试转换超出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());
}
cwxwcias

cwxwcias7#

简单地说就是:

double d = 394.000;
long l = d * 1L;
z18hc3ub

z18hc3ub8#

简单地说,造型比创建Double对象更有效。

yizd12fk

yizd12fk9#

最好使用new BigDecimal(s).longValue()
这是我的测试,s是一个长值的原始字符串,有时以.0结尾
将double转换为long((long) DoubleValue)或Double.longValue()有时会丢失1(为什么?).
https://stackoverflow.com/a/8754567/6494418

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

相关问题