210

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

For example:

double d = 394.000;
long l = (new Double(d)).longValue();
System.out.println("double=" + d + ", long=" + l);
Sled
  • 18,541
  • 27
  • 119
  • 168
  • 2
    just make sure you do not operate with doubles more than 2 ^ 54 or numbers will not fit into the [fraction](http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3), so for example expressions like `myLong == (long)(myDouble + 1)` where `myLong` equals `myDouble` will evaluate to `true` – Vitalii Fedorenko Jan 26 '12 at 23:55
  • This method ( `Double.longValue();` ) is still useful if you have double values from things like an arraylist like this `ArrayList` since you'll get a can't cast error. I'm just saying this for anyone that came here and had a slightly different problem. – SARose Dec 30 '14 at 07:19

9 Answers9

273

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 8
    Great answer - the towards zero part would have been wrong for my app, so applause for highlighting this in your answer, and reminding my hungover brain to use Math.round() here instead of just casting ! – Phantomwhale Dec 09 '11 at 04:54
145

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

double d = 1234.56;
long x = Math.round(d); //1235
Community
  • 1
  • 1
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
69

The preferred approach should be:

Double.valueOf(d).longValue()

From the Double (Java Platform SE 7) documentation:

Double.valueOf(d)

Returns a Double instance representing the specified double value. If a new Double instance 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.

marcelovca90
  • 2,673
  • 3
  • 27
  • 34
leogps
  • 894
  • 7
  • 6
37

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

Michael Myers
  • 188,989
  • 46
  • 291
  • 292
14

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

long DoubleMath.roundToLong(double x, RoundingMode mode)

You can use java.math.RoundingMode to specify the rounding behavior.

CyberPlayerOne
  • 3,078
  • 5
  • 30
  • 51
7

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

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

2) throw an error when its not a 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:

@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());
}
dutoitns
  • 1,949
  • 1
  • 26
  • 32
  • `Long is a subset of Double` is not accurate. The number of significant digits for Long is greater that Double, thus some information held by Long can be lost when converted to Double. Example = https://tio.run/##dY3BCoJAEIbP@hSDECjU0j06eOimJymCiNhcldVxV9xRiPDZt5G6dprh/2a@v5Wz3NmhMq3qvB@mJ@oSSpTOQS61gXcY/EJHknjMVivoGcUFjdo0tzvIsXHJehmgNQ0gwhEy3kSeXh@XNDufDsyUZU8FSjFFXJPi5ajqhZ1IDKwiNDFi8od820Rtx15SHG3Evo62bEvWhyVcvP8A – Thariq Nugrohotomo Nov 15 '18 at 04:52
  • @ThariqNugrohotomo `double` can store a wider range of numerical information than `long`. Take a look at the sections about `long` and `double` on this [site](https://www.w3schools.com/java/java_data_types.asp). – Tech Expert Wizard Oct 30 '20 at 13:38
5

Simply by the following:

double d = 394.000;
long l = d * 1L;
devll
  • 126
  • 1
  • 4
1

better to use new BigDecimal(s).longValue()

this is my test, s is raw string of a long value sometimes end with .0

cast double to long((long) DoubleValue) or Double.longValue() sometimes will losing 1(why?).

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
Colin Wang
  • 771
  • 8
  • 14
0

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

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
Vijay Dev
  • 26,966
  • 21
  • 76
  • 96