How to convert a double to long without casting?

JavaType Conversion

Java Problem Overview


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

Java Solutions


Solution 1 - Java

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.

Solution 2 - Java

... 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

Solution 3 - Java

The preferred approach should be:

Double.valueOf(d).longValue()

From the [Double (Java Platform SE 7) documentation][1]:

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.

[1]: http://docs.oracle.com/javase/7/docs/api/java/lang/Double.html#valueOf(double

Solution 4 - Java

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

Solution 5 - Java

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.

Solution 6 - Java

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

Solution 7 - Java

Simply by the following:

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

Solution 8 - Java

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrichView Question on Stackoverflow
Solution 1 - JavaJon SkeetView Answer on Stackoverflow
Solution 2 - JavaJohannes Schaub - litbView Answer on Stackoverflow
Solution 3 - JavaleogpsView Answer on Stackoverflow
Solution 4 - JavaMichael MyersView Answer on Stackoverflow
Solution 5 - JavaCyberPlayerOneView Answer on Stackoverflow
Solution 6 - JavadutoitnsView Answer on Stackoverflow
Solution 7 - JavadevllView Answer on Stackoverflow
Solution 8 - JavaVijay DevView Answer on Stackoverflow