Abstract
a % ngives the remainder whenais divided byn. It’s used for wrap-around (circular buffers, clock arithmetic), hashing into buckets, parity checks, and keeping large numbers small in modular arithmetic. Two things catch people out: negative numbers, where languages disagree on the sign of the result, and performance, where% 2ᵏcan be replaced by& (2ᵏ − 1), but only for non-negative values.
Cue
- What does
-7 % 3give in Java or C, and in Python? →-1in Java/C (truncated),2in Python (floored)- How do you get a non-negative result in Java? →
Math.floorMod(a, n)- When does
x % n == x & (n - 1)hold? → Whennis a power of two andx ≥ 0- Is
num % 2 == 1a safe odd check? → No. It’s-1for negative odd numbers, so usenum % 2 != 0or(num & 1) == 1
Definition
For integers and , division gives a quotient and a remainder with:
The languages disagree on how to round , which decides the sign of :
| Convention | rounds | Sign of follows | -7 % 3 | Languages |
|---|---|---|---|---|
| Truncated | toward 0 | the dividend | -1 | Java %, C/C++, Rust, JavaScript, Go |
| Floored | toward −∞ | the divisor | 2 | Python %, Ruby, Java Math.floorMod |
Mathematicians mean the floored (or Euclidean) version when they say “mod”: the result is always in for positive .
-7 % 3 // -1
Math.floorMod(-7, 3) // 2
((-7 % 3) + 3) % 3 // 2, the classic manual fixParity: num % 2 vs num & 1
num & 1 keeps only the lowest bit: 1 for odd numbers, 0 for even. That works for negative numbers too, because in two’s complement every odd number has its lowest bit set.
boolean isOdd(int num) { return (num & 1) == 1; } // correct for negatives
boolean isOdd(int num) { return num % 2 != 0; } // also correct
boolean isOdd(int num) { return num % 2 == 1; } // BUG: -3 % 2 == -1Is & 1 faster? Only without optimisation, and not by much. Division instructions are slow, but compilers already replace % 2 (and any % 2ᵏ) with shifts and masks:
- For an unsigned value,
x % 2compiles to a singleand, the same asx & 1. - For a signed value,
x % 2needs a few extra instructions to give negative numbers the truncated sign.x % 2 != 0doesn’t, because the sign no longer matters, so the compiler emits a singleand.
Choose the one that reads most clearly. Reach for the mask when you’ve measured a difference or when the bit is what you actually mean.
Compiler Explorer (x86-64 gcc 14.2, no optimisation)
return num & 1; compiles to an and eax, 1, with no division:

This screenshot shows
num % 1, notnum % 2Any integer
% 1is 0, so gcc folds the whole function tomov eax, 0. It doesn’t show the cost of% 2. To compare properly, compilereturn num % 2;next toreturn num & 1;, at-O0and at-O2, for bothintandunsigned.

Powers of two: x % 2ᵏ == x & (2ᵏ − 1)
in binary is ones, so masking with it keeps the low bits, which is the remainder:
int bucket = hash & (capacity - 1); // capacity must be a power of twoThis is why java.util.HashMap keeps its table size a power of two. For negative x the mask gives the floored result (-7 & 3 == 1) while % gives the truncated one (-7 % 4 == -3). That makes the mask useful for array indexes, which must not be negative.
Modular arithmetic
Remainders survive addition, subtraction and multiplication, so you can reduce at each step and never overflow:
That’s why coding challenges ask for answers “mod “. It’s a prime, and fits in a 64-bit long, so one multiplication of two reduced values can’t overflow.
static final int MOD = 1_000_000_007;
long result = (a % MOD) * (b % MOD) % MOD; // with a, b as longDivision doesn’t work this way. Dividing modulo a prime means multiplying by the modular inverse, by Fermat’s little theorem, or using the extended Euclidean algorithm from Algos, Number Theory, GCD.
Related
- Algos, Number Theory, GCD: Euclid’s algorithm is repeated modulo
- Algos, Efficiency