Posted by: Airtower | 2014-10-28

New in Java 8: Catching Integer Overflows

I’ve recently discovered a nice new feature in Java 8: methods to properly handle integer overflows. Consider the following example:

public class OverflowTest
{
	public static void main(String[] args)
	{
		int a = Integer.MAX_VALUE;
		int b = 1;

		int c = a + b;
		System.out.println(a + " + " + b + " = " + c);
	}
}

When you compile and run it, this is the result:

$ javac OverflowTest.java
$ java OverflowTest
2147483647 + 1 = -2147483648

Quite obviously, this can’t be mathematically right. The problem occurs because an int has a limited size of 4 byte. When this size is too small to store a number, the value will overflow and wrap around from the largest to the smallest possible value (or vice versa if the number is too small).

If you wanted to catch possible overflows in previous Java versions, you had to write your own checks. In Java 8, java.lang.Math offers new methods that will take care of that for you.

public class OverflowTest
{
	public static void main(String[] args)
	{
		int a = Integer.MAX_VALUE;
		int b = 1;

		int c = Math.addExact(a, b);
		System.out.println(a + " + " + b + " = " + c);
	}
}
$ javac OverflowTest.java
$ java OverflowTest
Exception in thread "main" java.lang.ArithmeticException: integer overflow
	at java.lang.Math.addExact(Math.java:790)
	at OverflowTest.main(OverflowTest.java:8)

If an overflow occurs, Math.addExcact(int,int) throws an ArithmeticException, which you can catch and handle. Similar methods exist for other operations and the long type. What to do in case of an exception depends on your application, and may be quite complicated. This post is just about mentioning these shiny new methods. 😉

Anyway, if I want to print the correct result in my example, I can simply fall back to long. At 8 bytes length it can definitely store the result of adding two ints. Note that I have to cast at least one summand to long before adding them, or the intermediate result would still be an int and overflow.

public class OverflowTest
{
	public static void main(String[] args)
	{
		int a = Integer.MAX_VALUE;
		int b = Integer.MAX_VALUE;

		try
		{
			int c = Math.addExact(a, b);
			System.out.println(a + " + " + b + " = " + c);
		}
		catch (ArithmeticException ex)
		{
			System.err.println("int is too small, falling back to long.");
			long c = (long) a + (long) b;
			System.out.println(a + " + " + b + " = " + c);
		}
	}
}
$ javac OverflowTest.java
$ java OverflowTest
int is too small, falling back to long.
2147483647 + 2147483647 = 4294967294

If you need a way to handle numbers of (almost) unlimited length, take a look at java.math.BigInteger. Also note that catching possible overflows influences performance, so using *Exact everywhere instead of simple operators is probably a bad idea. Anyway, this is not one of the biggest news in Java 8 (lambda expressions!), but I think it’s neat, and also about the right scope for a quick blog post. 😀

Advertisements

Responses

  1. Die Anführungszeichen in den Code-Beispielen werden falsch dargestellt.

    • Sollte jetzt wieder richtig sein. Danke für den Hinweis!


Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: