skip to content

What does the % operator return in Java, and how does the sign of the result behave for negative operands and for floating-point values?

level: middleimportance: should knowfreq 55%

answer

  1. % = remainder, sign follows the DIVIDEND
  2. -7 % 3 == -1 (not 2)
  3. Math.floorMod follows the DIVISOR -> non-negative wrap
  4. % works on doubles: 5.5 % 2 == 1.5
  5. int % 0 throws; double % 0.0 -> NaN
  6. odd check: n % 2 != 0, not == 1

basics

~20 s

% gives the remainder after division. In Java the result takes the sign of the left operand (the dividend), so -7 % 3 is -1, not 2. It also works on doubles: 5.5 % 2 is 1.5.

solid answer

~40 s

Java's % is the remainder operator, defined so that (a / b) * b + (a % b) == a using integer division that truncates toward zero. A key consequence is that the result's sign follows the dividend (the left operand), not the divisor: -7 % 3 is -1, while 7 % -3 is 1. This is a remainder, not a mathematical modulo, so it can be negative; if you need a non-negative result (e.g. wrapping an index), use Math.floorMod(a, b) instead, which follows the sign of the divisor. Unlike many languages, Java's % also works on floating-point operands, where it computes a truncated remainder (5.5 % 2 == 1.5) rather than the IEEE remainder; for the IEEE-754 rounded remainder use Math.IEEEremainder. Integer % by zero throws ArithmeticException; floating-point % by zero yields NaN.

code

java · 13 lines
java
System.out.println(7 % 3);    //  1
System.out.println(-7 % 3);   // -1  (sign of dividend)
System.out.println(7 % -3);   //  1
System.out.println(-7 % -3);  // -1

System.out.println(Math.floorMod(-7, 3)); // 2  (sign of divisor)

System.out.println(5.5 % 2);  // 1.5  (works on doubles)
System.out.println(5.0 % 0.0);// NaN  (no exception)

// Safe wrap-around index even for negative i:
int i = -1, len = 5;
System.out.println(Math.floorMod(i, len)); // 4, not -1

go deeper

for a junior

Knows % gives the remainder and is used for even/odd and last-digit tricks.

for a middle

States the dividend-sign rule, gives -7 % 3 == -1, and reaches for Math.floorMod for safe wrapping.

for a senior

Distinguishes remainder vs modulo vs Math.IEEEremainder, knows % works on doubles and the NaN/exception split, and avoids the negative-index/odd-check pitfalls.

for a principal

Codifies the floorMod-for-wrapping rule in standards and reviews, and reasons about where remainder-sign assumptions silently break across the codebase.

## What `%` computes `%` is the **remainder** operator: what is left over after dividing. Java pins it down with one identity, using integer division that **truncates toward zero**: ``` (a / b) * b + (a % b) == a // for integers, b != 0 ``` So `a % b = a - (a / b) * b`. From this, everything else follows. ## Sign rule: the result follows the DIVIDEND Because `/` truncates toward zero, the remainder takes the **sign of the left operand** (the dividend `a`), and the divisor's sign is irrelevant to the result's sign: - `7 % 3` -> `1` - `-7 % 3` -> `-1` (not `2`) - `7 % -3` -> `1` - `-7 % -3` -> `-1` This is the difference between a **remainder** (what Java's `%` is) and a **mathematical modulo** (which would always return a result with the divisor's sign, so `-7 mod 3 == 2`). Mixing these up causes real bugs — e.g. `arr[index % arr.length]` can produce a **negative index** and an `ArrayIndexOutOfBoundsException` if `index` is negative. ## When you actually want non-negative: `Math.floorMod` `Math.floorMod(a, b)` gives a result whose sign matches the **divisor** `b`, which is the usual 'wrap around' behaviour: - `Math.floorMod(-7, 3)` -> `2` - `Math.floorMod(7, -3)` -> `-2` Use `floorMod` for clock/index/hash-bucket wrapping with possibly-negative inputs; use `%` when you genuinely want a truncated remainder. ## `%` works on floating-point too Unlike C and many languages where `%` is integer-only, Java allows floating-point operands. It computes a **truncated remainder** consistent with the same identity (using truncating division), NOT the IEEE 754 'remainder' operation: - `5.5 % 2` -> `1.5` - `-5.5 % 2` -> `-1.5` If you need the IEEE-754 remainder (which rounds the quotient to the *nearest* integer and can return a value of magnitude up to half the divisor, with a different sign behaviour), call `Math.IEEEremainder(a, b)`. ## Division-by-zero, mirroring `/` - Integer `a % 0` throws **`ArithmeticException`** (`/ by zero`). - Floating-point `a % 0.0` returns **`NaN`** (never throws). ## Common uses - **Even/odd:** `n % 2 == 0` (but for possibly-negative `n`, test `n % 2 != 0` for odd rather than `== 1`, since `-3 % 2` is `-1`). - **Wrap an index/clock:** prefer `Math.floorMod`. - **Extract last digit:** `n % 10`. Knowing the dividend-sign rule and the `floorMod` alternative is the whole point of this topic.

  • Why can `index % array.length` blow up when index can be negative, and how do you fix it?
    Java's % follows the dividend's sign, so a negative index yields a negative remainder, which is an invalid array index and throws ArrayIndexOutOfBoundsException. Use Math.floorMod(index, array.length), which always returns a value in [0, length).
  • Why is checking `n % 2 == 1` for odd numbers a bug?
    For negative n the remainder is negative: -3 % 2 is -1, not 1, so the check misses negative odd numbers. Use n % 2 != 0 instead.

saying these in an interview costs you the question

  • Saying -7 % 3 is 2 (confusing remainder with mathematical modulo)
  • Believing % only works on integers in Java
  • Using array[i % len] with a possibly-negative i
  • Testing oddness with n % 2 == 1 instead of != 0
  • Assuming double % 0.0 throws

context