Explain Codes LogoExplain Codes Logo

How to convert a double to long without casting?

java
math-functions
precision
rounding
Alex KataevbyAlex Kataev·Dec 17, 2024
TLDR

To swiftly convert a double to long in Java without the need for casting, one can simply turn to the Math.round() function:

long parsedLong = Math.round(9.99);

Here, parsedLong magically transforms into 10 because Math.round() takes charge, rounds the double to the nearest long, and skips casting.

Breakdown of conversion methods

Master of precision: Math.round()

The Math.round() function is your go-to guru for rounding off values. Precision? Checked. Nearest integer? Checked. Wow, it even returns a long!

long roundedUp = Math.round(2.50); // Oh hey there, 3! long roundedDown = Math.round(2.49); // 2 it is!

A quick note: Math.round() rounds up the number if the fractional part is greater than or equal to 0.5; otherwise, it goes for rounding down.

Wrapper class hero: Double.longValue()

Ever heard of the Double wrapper class? It's the unsung hero who can convert a double to long without the fuss of casting:

double preciseDouble = 394.000; Long resultingLong = Double.valueOf(preciseDouble).longValue();

This method implicitly converts the double value into an object of the Double wrapper class. The longValue() method then extracts a long representation. Frequent values may find valueOf() helpful as it uses cached values for better performance.

Define your rounding: Math.floor() vs Math.ceil()

Have specific rounding requirements? Say hi to Math.floor() and Math.ceil(). These two methods can be your best buddies:

long floorValue = (long)Math.floor(preciseDouble); // Always rounds down, no exceptions! long ceilValue = (long)Math.ceil(preciseDouble); // Always rounds up, reaching the sky!

The above methods ensure you get your double rounded according to your whims and fancies before it steps into the shoes of a long.

Bumps on the road to conversion

Farewell to fractions

While morphing from double to long, you must bid adieu to any fractional precision. Just be aware that this can be significant if your decimal part carries meaningful data.

Dealing with big guys

For larger-than-life double values, there could be an overflow, which might result in a number that's incorrect and has nothing to do with your original value.

Speed vs Clarity

While avoiding casting might seem like a shortcut, direct casting might be faster in terms of performance. Hence, ponder over the trade-offs between readability and performance depending on your unique requirements.

Additional cases to consider

When things go negative

Math.round() might knock you for a loop when dealing with negative numbers:

long resultNegative = Math.round(-2.5); // Surprise! It returns -2, not -3

In these situations, it pays to understand the rounding mechanics to prevent unexpected turns.

Money matters

Especially in financial calculations where every penny counts, consider using BigDecimal. It gives you better precision:

BigDecimal bigCurrency = new BigDecimal("1234.56"); long bigMoney = bigCurrency.setScale(0, RoundingMode.DOWN).longValueExact();

We are dealing with money here, precision is key!

Say hello to immutability

Java's Long objects are immutable. Modifications to the Long value from Double.valueOf(preciseDouble).longValue() requires a brand new Long object. Sigh, if only numbers could be mutated!