Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we’ll explore how to get the absolute difference between two given integers.

2. Using the Math.abs() Method

The problem is pretty straightforward. Let’s understand it quickly with a few examples:

  • num1=3, num2=4: absDiff=1
  • num1=3, num2=-4: absDiff=7
  • num1=-3, num2=-4: absDiff=1

Looking at the examples above, given two integers, num1 and num2, the result is the absolute value of (num1 – num2). Further, Java standard library has provided the Math.abs() method to return the absolute value. Therefore, we can easily translate the calculation into Java code:

int absDiff(int num1, int num2) {
    int result = Math.abs(num1 - num2);
    System.out.println("Absolute diff: " + result);
    return result;
}

As we can see, the absDiff() method returns the result. Also, it prints the result.

For simplicity, let’s use unit test assertions to verify if the method works as expected:

int diff1 = absDiff(100, -200);
assertEquals(300, diff1);
                               
int diff2 = absDiff(100, 200);
assertEquals(100, diff2);

The test passes when we give it a run. So, we’ve solved the problem. However, a potential issue is hidden in this implementation. So, next, let’s figure it out.

3. The Overflow/Underflow Issue

We know that Java’s int is a signed 32-bit integer. In other words, the Java integer’s range is -2147483648 to 2147483647.

Now, let’s revisit our implementation. We have the calculation: num1 – num2. Therefore, the result could exceed Integer.MAX_VALUE, for example, when we pass Integer.MAX_VALUE and -200 to the absDiff() method. Next, let’s call the method with these two integers and see what happens.

First, let’s calculate it manually and see what’s the expected result:

Result = Integer.MAX_VALUE - (-200)
       = 2147483647 + 200
       = 2147483847

However, if we call our absDiff() method, no exception occurs, and we see the output:

Absolute diff: 2147483449

Obviously, the result isn’t correct. This is because integer overflow has happened. Of course, a calculation result could be less than Integer.MIN_VALUE, for instance, absDiff(Integer.MIN_VALUE, 200). In this case, we call it underflow.

Next, let’s see how to solve the overflow/underflow problem.

4. Using a Different Datatype

In Java, there are number types with ranges larger than int, such as long or BigInteger. To avoid overflow/underflow pitfalls, we can convert int parameters to one of those types before performing the calculation. Let’s pick long as an example and implement the logic in a new method:

long absDiffAsLong(int num1, int num2) {
    return Math.abs((long) num1 - num2);
}

Now, let’s test if it gives us the expected result when we pass Integer.MAX_VALUE and -200 to it:

long diff = absDiffAsLong(Integer.MAX_VALUE, -200);
assertEquals(Integer.MAX_VALUE + 200L, diff);

If we run the test, it passes. Therefore, this approach solves the overflow/underflow problem. But, it’s worth mentioning that the return type is long instead of int.

It’s fine if the caller expected the result to be long. Otherwise, if int is required, we must convert the long value into int. This is inconvenient. Further, if we performed long-to-int conversion improperly, overflow/underflow could occur as well.

Next, let’s see if we could keep the result as int and avoid the overflow/underflow problem.

5. Throwing an Exception When Overflow/Underflow Occurrs

Let’s say our program requires the absolute difference result as an int. Then the ideal behavior of the method would be returning an int and raising an exception when overflow/underflow occurs.

However, as we’ve seen earlier, Java doesn’t throw an exception when an overflow occurs during the regular (num1 – num2) calculation. This makes it hard to find the real cause when we detect our program didn’t produce the expected result.

Since Java 8, Java’s Math has introduced new *exact() methods. These methods throw ArithmeticException when overflow/underflow occurs. So next, let’s replace (num1 – num2) in our method with subtractExact():

int absDiff2(int num1, int num2) {
    return Math.abs(Math.subtractExact(num1, num2));
}

Finally, the following test tells absDiff2() works as expected:

int diff1 = absDiff2(100, -200);
assertEquals(300, diff1);

int diff2 = absDiff2(100, 200);
assertEquals(100, diff2);

//overflow -> exception
assertThrows(ArithmeticException.class, () -> absDiff2(Integer.MAX_VALUE, -200));

6. Conclusion

In this article, we’ve explored calculating the absolute difference between two integers. Further, we’ve discussed the overflow/underflow issue.

As usual, all code snippets presented in the article are available over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.