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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/321549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 13:09:09  来源:igfitidea点击:

How to convert a double to long without casting?

javatype-conversion

提问by

What is the best way to convert a double to a long without casting?

在不进行强制转换的情况下将 double 转换为 long 的最佳方法是什么?

For example:

例如:

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

回答by Jon Skeet

Assuming you're happy with truncating towards zero, just cast:

假设您对向零截断感到满意,只需投射:

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

This will be faster than going via the wrapper classes - and more importantly, it's more readable. Now, if you need rounding other than "always towards zero" you'll need slightly more complicated code.

这将比通过包装类更快 - 更重要的是,它更具可读性。现在,如果您需要除“始终向零”以外的四舍五入,您将需要稍微复杂的代码。

回答by Johannes Schaub - litb

... And here is the rounding way which doesn't truncate. Hurried to look it up in the Java API Manual:

...这是不截断的舍入方式。赶紧去Java API手册查了一下:

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

回答by Michael Myers

(new Double(d)).longValue()internally just does a cast, so there's no reason to create a Double object.

(new Double(d)).longValue()内部只是做一个演员表,所以没有理由创建一个 Double 对象。

回答by Vijay Dev

Simply put, casting is more efficient than creating a Double object.

简而言之,转换比创建 Double 对象更有效。

回答by pvorb

Do you want to have a binary conversion like

你想进行二进制转换吗

double result = Double.longBitsToDouble(394.000d);

回答by u1516331

Guava Math library has a method specially designed for converting a double to a long:

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

long DoubleMath.roundToLong(double x, RoundingMode mode)

You can use java.math.RoundingModeto specify the rounding behavior.

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

回答by leogps

The preferred approach should be:

首选方法应该是:

Double.valueOf(d).longValue()

From the Double (Java Platform SE 7) documentation:

来自Double(Java Platform SE 7)文档

Double.valueOf(d)

Returns a Doubleinstance representing the specified doublevalue. If a new Doubleinstance is not required, this method should generally be used in preference to the constructor Double(double), as this method is likely to yield significantly better space and time performance by caching frequently requested values.

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

回答by NS du Toit

If you have a strong suspicion that the DOUBLE is actually a LONG, and you want to

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

1) get a handle on its EXACT value as a LONG

1) 将其 EXACT 值作为 LONG 处理

2) throw an error when its not a LONG

2) 当它不是 LONG 时抛出错误

you can try something like this:

你可以尝试这样的事情:

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 is a subset of Double, so you might get some strange results if you unknowingly try to convert a Double that is outside of Long's range:

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

回答by devll

Simply by the following:

只需通过以下方式:

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