Safely Casting Long to Int in Java

Safely casting long to int in Java

A new method has been added with Java 8 to do just that.

import static java.lang.Math.toIntExact;

long foo = 10L;
int bar = toIntExact(foo);

Will throw an ArithmeticException in case of overflow.

See: Math.toIntExact(long)

Several other overflow safe methods have been added to Java 8. They end with exact.

Examples:

  • Math.incrementExact(long)
  • Math.subtractExact(long, long)
  • Math.decrementExact(long)
  • Math.negateExact(long),
  • Math.subtractExact(int, int)

How does casting long to integer work?

If Long.parseLong(Num) returns a value higher than Integer.MAX_VALUE or lower than Integer.MIN_VALUE, casting it to int will result in an incorrect value.

For positive longs, casting them to int simply means assigning the 32 lowest bits to the integer variable. I'm not sure if it's the same for negative longs (I'll have to check).

Converting long to int in Java

Your cast syntax is incorrect. You need also be aware that longs can be much bigger that the max value for int.

int y;
if ( enable_beacon_timestamp > (long)Integer.MAX_VALUE ) {
// long is too big to convert, throw an exception or something useful
}
else {
y = (int)enable_beacon_timestamp;
}

Try something like this perhaps...

Long to int conversion in Java gives incorrect result

Expression evaluation rules lead to this problem.

when you did

(int)temp%10

Actually the big long value temp being casted to int which leads to integer overflow ,

you meant

(int)(temp%10)

Convert Long into Integer

Integer i = theLong != null ? theLong.intValue() : null;

or if you don't need to worry about null:

// auto-unboxing does not go from Long to int directly, so
Integer i = (int) (long) theLong;

And in both situations, you might run into overflows (because a Long can store a wider range than an Integer).

Java 8 has a helper method that checks for overflow (you get an exception in that case):

Integer i = theLong == null ? null : Math.toIntExact(theLong);

Explicit casting a long into an int and implicit casting a long to a float

Long.MAX_VALUE = (2^63)-1

Float.MAX_VALUE= 2^127

So, Long value always fits into Float value.

Compiler doesn't analyse real values from your code. It never verifies if the value may fit.

Convert a long to an int cutting off the overflow

An improvement would be

int intVar = (int) Math.min(Math.max(longVar, Integer.MIN_VALUE),
Integer.MAX_VALUE));

Math.max would make [Long.Min,Long.Max] => [Int.Min, Long.Max] and whatever outcome of that, if it is greater than Int.Max will be trimmed down by the outer Math.min to [Int.Min, Int.Max].

I don't know of a ready-to-go method doing this included in java.

The java 8 method Math.toIntExact will throw an exception on overflow. And using that to do this - well, I'd consider it a misuse of exceptions. And probably less efficient than above construct.

The specifics of casting to int, from double and long

The logic of these conversions is part of the Java language specification, Item 5.1.3.

You can see there, that when converting from long to int, most significant bits are discarded, leaving the least significant 32 bits.

And also, that if the result of rounding a double or float is a number that is too small or too large to represent as an int (or long), the minimal or maximal representable number will be chosen.

There is no way for us here to answer "why" for a decision that has been made long ago. But this is the way the language is defined, and you can rely on it being the same in any Java environment you work in.



Related Topics



Leave a reply



Submit