Table of Contents
If it is 9 o'clock now, what time will it be in 5 hours? Nobody says 14 o'clock. You say 2 o'clock, because clock time wraps around after 12. That everyday calculation is modular arithmetic, and it is one of the most useful ideas in mathematics. It solves olympiad problems that look impossible, explains why the divisibility rules you learned at school actually work, keeps your calendar straight, catches typing mistakes in book codes and bank numbers, and underpins the encryption that protects the internet.
This guide builds modular arithmetic from the clock up, then applies it to four very different problems. Every calculation was checked by running it, in Python, and in one case in Java too, because the two languages give different answers to the same modular question, which is worth knowing before it bites you.
What "mod" means
a mod n is the remainder when a is divided by n. So 17 mod 5 is 2, because 17 = 3 x 5 + 2. Two numbers are congruent modulo n if they leave the same remainder when divided by n. We write 17 ≡ 2 (mod 5), read "17 is congruent to 2 mod 5".
On a clock, everything is mod 12. On a calendar, days of the week are mod 7. In programming, the % operator gives you mod directly:
print("9 o'clock + 5 hours ->", (9 + 5) % 12, "o'clock")
print("17 mod 5 =", 17 % 5, " because 17 = 3 x 5 + 2")
days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
print("100 days after a Monday is a", days[(0 + 100) % 7])
from datetime import date, timedelta
start = date(2026, 9, 28)
print("check with a calendar:", start.strftime("%A"), "->", (start + timedelta(days=100)).strftime("%A %d %B %Y"))
9 o'clock + 5 hours -> 2 o'clock
17 mod 5 = 2 because 17 = 3 x 5 + 2
100 days after a Monday is a Wednesday
check with a calendar: Monday -> Wednesday 06 January 2027
The calendar check confirms it: 100 days is 14 weeks and 2 days, so the weekday moves on by exactly 2. You never need to count through 100 days, only the remainder.
The rules that make it powerful
Modular arithmetic works because remainders behave well under addition and multiplication. If you only care about the remainder at the end, you can take remainders at every step along the way:
- Addition: (a + b) mod n = ((a mod n) + (b mod n)) mod n.
- Multiplication: (a x b) mod n = ((a mod n) x (b mod n)) mod n.
- Powers: follow from multiplication, so you can reduce as you go instead of computing a gigantic number.
That last point is the secret behind the next problem.
Problem: the last digit of a huge power
What is the last digit of 7 to the power 2026? The last digit of a number is just the number mod 10. Multiplying by 7 each time, the last digits run 7, 9, 3, 1, and then repeat, because 1 x 7 brings you back to 7. The cycle has length 4, so you only need 2026 mod 4, which is 2. The answer is the same as the last digit of 7², which is 9.
print("last digits of powers of 7:", [pow(7, k) % 10 for k in range(1, 9)])
print("the pattern repeats every", 4, "so 7^2026 ends in the same digit as 7^" + str(2026 % 4))
print("last digit of 7^2026:", pow(7, 2026, 10))
print("how many digits 7^2026 has:", len(str(7 ** 2026)))
last digits of powers of 7: [7, 9, 3, 1, 7, 9, 3, 1]
the pattern repeats every 4 so 7^2026 ends in the same digit as 7^2
last digit of 7^2026: 9
how many digits 7^2026 has: 1713
The actual number has over 1,700 digits, but you never need to see it. Python's pow(7, 2026, 10) uses the same idea, reducing at each step, and it is how computers work with the enormous numbers used in encryption.
A pattern worth remembering
Last digits of powers always cycle with a length of 1, 2 or 4. For example, powers of 2 end in 2, 4, 8, 6, and powers of 9 end in 9, 1. Find the cycle, reduce the exponent, done. This exact type of question appears regularly in school olympiads.
Why the divisibility rules work
You probably learned that a number is divisible by 9 if its digits add up to a multiple of 9. Modular arithmetic explains why. 10 leaves remainder 1 when divided by 9, so 100 does too, and 1000, and every power of 10. That means a number like 4,527, which is 4 x 1000 + 5 x 100 + 2 x 10 + 7, leaves the same remainder as 4 + 5 + 2 + 7. The digit sum and the number always agree mod 9.
For 11 the trick is that 10 behaves like −1, because it is one less than 11. So powers of 10 alternate between +1 and −1, which is why the rule for 11 uses an alternating sum of the digits. Checking both on real numbers:
n = 987654321123456785
print("digit sum:", sum(map(int, str(n))), "->", sum(map(int, str(n))) % 9, "mod 9")
print("the number itself: ", n % 9, "mod 9")
# alternating sum for 11, starting from the last digit
digits = list(map(int, str(918082)))[::-1]
alternating = sum(d if i % 2 == 0 else -d for i, d in enumerate(digits))
print("918082: alternating sum", alternating, "->", "divisible by 11" if alternating % 11 == 0 else "not divisible",
"| check:", 918082 % 11)
digit sum: 86 -> 5 mod 9
the number itself: 5 mod 9
918082: alternating sum -22 -> divisible by 11 | check: 0
Check digits: catching typos in real life
Book codes, bank account numbers, credit cards and many ID numbers end in a check digit, chosen so that some modular calculation comes out to zero. If a digit is mistyped, the calculation almost always fails, and the system knows the number is wrong before it is used. The older 10-digit ISBN for books multiplies the digits by 10, 9, 8 and so on down to 1, and requires the total to be a multiple of 11:
def isbn10_valid(isbn):
digits = [10 if ch == "X" else int(ch) for ch in isbn if ch.isdigit() or ch == "X"]
return sum((10 - i) * d for i, d in enumerate(digits)) % 11 == 0
print("0-306-40615-2", isbn10_valid("0-306-40615-2"), " (a correctly printed ISBN)")
print("0-306-40616-2", isbn10_valid("0-306-40616-2"), " (one digit mistyped)")
print("0-306-46015-2", isbn10_valid("0-306-46015-2"), " (two digits swapped)")
0-306-40615-2 True (a correctly printed ISBN)
0-306-40616-2 False (one digit mistyped)
0-306-46015-2 False (two digits swapped)
Because 11 is prime and the weights are all different, a single wrong digit or two neighbouring digits swapped always changes the remainder, which are exactly the two most common typing errors people make.
A trap for programmers: negative numbers
What is −7 mod 3? Mathematicians usually say 2, because −7 = −3 x 3 + 2 and remainders are kept between 0 and 2. Python agrees. But many other languages, including Java, C and C++, give −1 for the % operator, because they round the division towards zero instead of down.
print(-7 % 3)
print(7 % -3)
2
-2
public class Mod {
public static void main(String[] args) {
System.out.println(-7 % 3);
System.out.println(Math.floorMod(-7, 3));
}
}
-1
2
Java's Math.floorMod gives the mathematical answer. This difference causes real bugs, especially in code that wraps around, such as array positions or clock times going backwards. When the left side can be negative, check which rule your language uses. Our guide to floor division in Python covers the related // operator.
Wrapping backwards
Moving 3 steps back from position 1 on a board of 10 squares: in Python (1 - 3) % 10 gives 8, as you would hope. In Java, (1 - 3) % 10 gives -2, which will crash an array lookup. Use Math.floorMod in Java, or add the modulus before taking the remainder.
Where modular arithmetic leads
- Olympiads. Remainders are behind a large share of number theory problems at every level, from school contests to national olympiads. Our guide to the pigeonhole principle uses remainders as its boxes in several problems.
- Primes and encryption. RSA encryption is modular arithmetic with very large prime numbers.
- Programming. Hashing, random number generators, circular buffers and anything that wraps around use mod constantly.
- Everyday life. Calendars, clocks, shift rotas and check digits all run on it.
Modular arithmetic is what happens when you decide to care only about the remainder, and it turns out the remainder is often all you need.
How we teach it
Number theory in our olympiad and maths classes starts from patterns students discover themselves, like the cycle of last digits here, before any notation, following the principle on our how we teach page of deriving a rule before seeing it written down. See IOQM, RMO and INMO preparation and our live maths classes, one to one or in small groups of 5 to 10.
Frequently asked questions
It is arithmetic where numbers wrap around after reaching a certain value, called the modulus, like hours on a clock. a mod n means the remainder when a is divided by n, so 17 mod 5 is 2.
Two numbers are congruent modulo n if they leave the same remainder when divided by n. For example, 17 and 2 are congruent modulo 5, written 17 ≡ 2 (mod 5).
Find the cycle of last digits by multiplying repeatedly, then reduce the exponent by the cycle length. Powers of 7 end in 7, 9, 3, 1 in a cycle of 4, and 2026 leaves remainder 2 when divided by 4, so 7 to the power 2026 ends in 9.
Because 10 leaves a remainder of 1 when divided by 9, so every power of 10 does too. That means a number leaves the same remainder as the sum of its digits when divided by 9.
Python's % always returns a result with the same sign as the divisor, so -7 % 3 is 2. Java, C and C++ round division towards zero, so -7 % 3 is -1. Java's Math.floorMod matches Python's behaviour.
In clocks and calendars, check digits on book codes, bank accounts and ID numbers, hashing and random numbers in computing, and in encryption systems such as RSA.
It is often taught informally through remainders and divisibility, and formally in olympiad preparation, some advanced school courses, and early university mathematics and computer science.