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


190

在不强制转换的情况下将双精度型转换为长型的最佳方法是什么?

例如:

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

2
只要确保您使用的双精度数不能超过2 ^ 54,否则数字将不适合小数,例如myLong == (long)(myDouble + 1)myLong等于myDoubletrue
等值的

Double.longValue();如果您从诸如此类的数组列表中ArrayList<Double>获取双精度值,则此方法()仍然有用,因为您会遇到无法转换的错误。我只是对那些来这里但有稍微不同的问题的人说这句话。
SARose 2014年

Answers:


250

假设您对截断为零感到满意,请执行以下操作:

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

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


8
很好的答案-我的应用程序朝零的方向前进是错误的,因此鼓掌欢迎您在答案中突出显示此内容,并提醒我的宿醉大脑在此处使用Math.round()而不是仅仅投射!
幻影鲸鱼

123

...这是不会截断的舍入方式。急于在Java API手册中进行查找:

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

它所产生的结果与强制转换不同。因此,这取决于富人想要做什么。
Cyrille Ka

3
是的 它被认为是乔恩所说内容的补充:)
约翰内斯·绍布

2
我喜欢它,因为它也适用于Double和Long对象而不是原始类型。
themanatuf

57

首选方法应该是:

Double.valueOf(d).longValue()

Double(Java Platform SE 7)文档中

Double.valueOf(d)

返回Double表示指定double值的实例。如果Double不需要新实例,则通常应优先于构造方法使用Double(double)此方法,因为通过缓存经常请求的值,此方法可能会产生明显更好的空间和时间性能。


36

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


13

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

long DoubleMath.roundToLong(double x, RoundingMode mode)

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


7

如果您强烈怀疑DOUBLE实际上是一个LONG,并且您想

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());
}

Long is a subset of Double是不准确的。Long的有效位数大于Double,因此Long保留的某些信息在转换为Double时可能会丢失。示例= tio.run/…
Thariq Nugrohotomo,

5

您是否想要像这样的二进制转换

double result = Double.longBitsToDouble(394.000d);

1
这与要求的相反。
卢卡斯·菲利普斯

@LucasPhillips你是对的。我一定对这个问题有误读,但是我会留下我的答案,因为它可能会帮助其他人。
pvorb

1

只需通过以下方式:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.