1. Overview
In this quick tutorial, we’ll learn what the modulo operator is, and how we can use it with Java in some common use cases.
2. The Modulo Operator
Let’s start with the shortcomings of simple division in Java.
If the operands on both sides of the division operator have type int, the result of the operation is another int:
@Test
public void whenIntegerDivision_thenLosesRemainder() {
assertThat(11 / 4).isEqualTo(2);
}
The same division gives us a different result when at least one of the operands has type float or double:
@Test
public void whenDoubleDivision_thenKeepsRemainder() {
assertThat(11 / 4.0).isEqualTo(2.75);
}
We can observe that we lose the remainder of a division operation when dividing integers.
The modulo operator gives us exactly this remainder:
@Test
public void whenModulo_thenReturnsRemainder() {
assertThat(11 % 4).isEqualTo(3);
}
The remainder is what remains after dividing 11 (the dividend) by 4 (the divisor), which in this case is 3.
For the same reason a division by zero isn’t possible, it’s not possible to use the modulo operator when the right-side argument is zero.
Both the division and the modulo operation throw an ArithmeticException when we try to use zero as the right side operand:
@Test(expected = ArithmeticException.class)
public void whenDivisionByZero_thenArithmeticException() {
double result = 1 / 0;
}
@Test(expected = ArithmeticException.class)
public void whenModuloByZero_thenArithmeticException() {
double result = 1 % 0;
}
3. Modulo Operator Uses
We can use the modulo operator in different scenarios. We’ll go over these scenarios in the following sections.
Also, since the modulus of a negative number can result in an unexpected negative remainder, we need techniques to handle this.
3.1. Common Use Cases
The most common use case for the modulo operator is to find out if a given number is odd or even.
If the outcome of the modulo operation between any number and two is equal to one, it’s an odd number:
@Test
public void whenDivisorIsOddAndModulusIs2_thenResultIs1() {
assertThat(3 % 2).isEqualTo(1);
}
In contrast, if the result is zero (i.e., there’s no remainder), it’s an even number:
@Test
public void whenDivisorIsEvenAndModulusIs2_thenResultIs0() {
assertThat(4 % 2).isEqualTo(0);
}
Another good use of the modulo operation is to keep track of the index of the next free spot in a circular array.
In a simple implementation of a circular queue for int values, the elements are kept in a fixed-size array.
Any time we want to push an element to our circular queue, we just compute the next free position by computing the modulo of the number of items we’ve already inserted, plus 1 and the queue capacity:
@Test
public void whenItemsIsAddedToCircularQueue_thenNoArrayIndexOutOfBounds() {
int QUEUE_CAPACITY= 10;
int[] circularQueue = new int[QUEUE_CAPACITY];
int itemsInserted = 0;
for (int value = 0; value < 1000; value++) {
int writeIndex = ++itemsInserted % QUEUE_CAPACITY;
circularQueue[writeIndex] = value;
}
}
Using the modulo operator, we prevent writeIndex from falling out of the boundaries of the array; therefore, we’ll never get an ArrayIndexOutOfBoundsException.
However, once we insert more than QUEUE_CAPACITY items, the next item will overwrite the first.
3.2. Modulus of Negative Numbers
In cases where the dividend is negative, Java returns a negative remainder:
@Test
public void whenDividendIsNegativeAndModulusIs2_thenResultIsNegative() {
assertEquals(-1, -9 % 2);
}
However, a negative remainder isn’t always the desired result. Let’s modify the code to give a positive remainder:
@Test
public void whenDividendIsNegativeAndRemainderIsCheckedForNegativeValue_thenResultIsPositive() {
int remainder = -9 % 2;
if (remainder < 0) {
remainder += 2;
}
assertEquals(1, remainder);
}
Here, we check if the remainder is less than 0. Next, we add the remainder and the divisor together to get a positive remainder.
Furthermore, we can use the Math class to compute the modulus of a negative number without needing to check if the remainder is negative or not:
@Test
public void whenDividendIsNegativeAndUsesMathClass_thenResultIsPositive() {
int remainder = Math.floorMod(-9, 2);
assertEquals(1, remainder);
}
In the code above, we invoke the Math.floorMod() method, which accepts two arguments. Then, we assert that the remainder is positive.
4. Conclusion
In this article, we saw that the modulo operator is used to compute the remainder of an integer division that is otherwise lost.
It’s useful for doing simple things, like figuring out if a given number is even or odd, as well as more complex tasks, like tracking the next writing position in a circular array.
As always, the example code is available in the over on GitHub.