Skip to main content

Modulo Operator in Python: Understanding Key Concepts

Learn how to use the modulo operator (%) in Python to solve real-world problems, from checking even/odd numbers to cryptography, or cyclic data structures.
Mar 12, 2025  · 9 min read

The modulo operator (%) in Python is a fundamental arithmetic operator used to determine the remainder of a division operation. While simple in concept, it plays a crucial role in various programming applications. From checking whether a number is even or odd to cycling through sequences and determining leap years, mastering the modulo operator can enhance your problem-solving skills in Python.

Understanding the modulo operator is essential because it frequently appears in:

  • Identifying even and odd numbers
  • Looping through elements cyclically
  • Implementing mathematical computations in modular arithmetic
  • Practical real-world applications like date calculations, cryptography, and gaming logic.

In this blog, I will provide a comprehensive guide to using the modulo operator in Python, covering syntax, behavior with different number types, use cases, and practical examples. If you're new to Python, consider taking our Introduction to Python course. 

What is the Modulo Operator in Python?

The modulo operator (%) computes the remainder of the division between two numbers. Given two numbers a (dividend) and b (divisor), the modulo operation returns the remainder when a is divided by b.

Mathematical background

Modulo has its roots in modular arithmetic, a system of arithmetic for integers where numbers "wrap around" after reaching a certain value (modulus). It is widely used in cryptography, hashing, and cyclic computations.

Think of a 12-hour clock: after 12, instead of continuing to 13, we wrap back to 1. This is essentially modular arithmetic with a modulus of 12:

  • 13 % 12 = 1, meaning 13 o’clock corresponds to 1 o’clock in a 12-hour format.

Python Modulo Syntax and Basic Usage

In Python, the modulo operator follows a straightforward syntax:

remainder = dividend % divisor

Let's look at some basic examples:

# Basic modulo operations
print(7 % 3)     
print(15 % 4)   
print(20 % 5)  
1 
3 
0 

When we divide 7 by 3, we get 2 with a remainder of 1. The modulo operator gives us that remainder. Similarly, 15 divided by 4 gives 3 with a remainder of 3, and 20 divided by 5 gives exactly 4 with no remainder.

Working with Integers

Now that we understand the basics of the modulo operator, let's explore how it behaves with integers.

Modulo with positive integers

Working with positive integers is the most straightforward use case for the modulo operator:

# Examples with positive integers
print(10 % 3)      
print(25 % 7)     
print(100 % 10)  
1 
4 
0 

In these examples, we can calculate the results by finding how many times the divisor goes into the dividend and then determining what's left over:

  • 10 ÷ 3 = 3 remainder 1, so 10 % 3 = 1
  • 25 ÷ 7 = 3 remainder 4, so 25 % 7 = 4
  • 100 ÷ 10 = 10 remainder 0, so 100 % 10 = 0

Modulo with negative integers

The behavior of the modulo operator becomes more interesting when working with negative numbers. Python follows a specific rule: the result of  a % b always has the same sign as  b (the divisor).

# Examples with negative integers
print(-10 % 3)    
print(10 % -3)    
print(-10 % -3) 
2 
-2 
-1 

These results might seem counterintuitive at first, but they follow a consistent rule:

  1. For -10 % 3: Instead of getting -1 (which might be expected if thinking of -10 ÷ 3 = -3 remainder -1), Python returns 2. This is because Python seeks a value between 0 and 3 (exclusive) that, when added to a multiple of 3, gives -10. The answer is 2, because -12 + 2 = -10.
  2. For 10 % -3: The result has the same sign as the divisor (-3), so we get -2. This is because 10 = (-3) × (-4) + (-2).
  3. For -10 % -3: The result is -1, because -10 = (-3) × 3 + (-1).

Understanding how Python handles negative numbers in modulo operations is crucial when working with cyclic computations, such as:

  • Implementing hashing functions
  • Solving problems involving clock arithmetic
  • Handling negative indexing logic in lists

Using Modulo with Floating-Point Numbers

Python's modulo operator isn't limited to integers; it works with floating-point numbers as well:

# Modulo with floating-point numbers
print(7.5 % 2)     
print(9.7 % 4.2)  
print(5.0 % 0.2)  
1.5
1.299999999999999
0.19999999999999973

With floating-point numbers, the modulo operation follows the same principle: it returns the remainder after division. However, due to the way floating-point numbers are stored in computers (IEEE 754 format), small rounding errors can occur.

For example, instead of 1.3, Python returns 1.299999999999999, and instead of 0.2, it returns 0.19999999999999973. These small inaccuracies are common in floating-point arithmetic and should be considered when performing precise calculations.

Python also provides the math.fmod() function from the math module as an alternative for floating-point modulo operations, which may handle certain edge cases differently:

import math

print(math.fmod(7.5, 2))    
print(math.fmod(-7.5, 2))  

# Compare with Python's modulo operator 
print(-7.5 % 2) 
1.5
-1.5
0.5

The main difference between % and math.fmod() is in how they handle negative numbers. While % ensures the result has the same sign as the divisor and returns a value in the range [0, divisor), math.fmod() ensures the result has the same sign as the dividend. This distinction is important in applications where the sign of the remainder matters.

So when should you use % versus math.fmod()?

  • Use % when you need consistent sign behavior (e.g., cycling through a range).
  • Use math.fmod() when the sign of the dividend must be preserved, such as in physics simulations or mathematical functions.

Handling Negative Numbers in Python Modulo

As we've seen in earlier examples, Python's implementation of the modulo operator with negative numbers might not align with initial intuition. Let's explore this behavior more systematically:

# Understanding the pattern with negative numbers
for i in range(-10, 11):
    result = i % 3
    print(f"{i} % 3 = {result}")
-10 % 3 = 2
-9 % 3 = 0
-8 % 3 = 1
-7 % 3 = 2
-6 % 3 = 0
-5 % 3 = 1
-4 % 3 = 2
-3 % 3 = 0
-2 % 3 = 1
-1 % 3 = 2
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
3 % 3 = 0
4 % 3 = 1
5 % 3 = 2
6 % 3 = 0
7 % 3 = 1
8 % 3 = 2
9 % 3 = 0
10 % 3 = 1

Notice the pattern: the results cycle through 0 → 1 → 2 repeatedly, regardless of whether the dividend is positive or negative. This consistent behavior makes the modulo operator particularly useful in cyclic computations, such as:

  • Rotating through indices in circular arrays or buffers
  • Mapping values in periodic functions (e.g., time-based calculations)

The mathematical formula that Python follows for modulo is:

Import math 

a % b = a - (b * math.floor(a / b))

This ensures that the result is always between 0 and b (exclusive) when b is positive, or between b and 0 (exclusive) when b is negative.

Summary of Python's Modulo Operator

The modulo operator (%) in Python calculates the remainder of a division operation. It follows a consistent mathematical formula:

a % b = a - (b * math.floor(a / b))

Key Rules of Python’s Modulo Behavior:

  1. For Positive Divisors (b > 0)
    • The result is always in the range [0, b) (inclusive of 0, exclusive of b).
  2. For Negative Divisors (b < 0)
    • The result is always in the range (b, 0] (exclusive of b, inclusive of 0).
    • The remainder adopts the same sign as b (the divisor).
  3. Works with Both Integers and Floats
    • For floating-point numbers, % follows the same formula but may introduce small rounding errors due to floating-point precision.
  4. Difference Between % and math.fmod()
    • % ensures the remainder has the same sign as the divisor.
    • math.fmod(a, b) ensures the remainder has the same sign as the dividend.

Common Use Cases of the Modulo Operator

Let’s look at some of the practical applications of the modulo operator and see some further examples. 

Checking if a number is even or odd

One of the most common applications of the modulo operator is to determine whether a number is even or odd:

def is_even(number):
    return number % 2 == 0

def is_odd(number):
    return number % 2 != 0

# Testing the functions
numbers = [1, 2, -3, 4, -5, 6, 7]
for num in numbers:
    if is_even(num):
        print(f"{num} is even")
    else:
        print(f"{num} is odd")
1 is odd
2 is even
-3 is odd
4 is even
-5 is odd
6 is even
7 is odd

This works because even numbers leave a remainder of 0 when divided by 2, while odd numbers leave a remainder of 1 or -1.

Cycling through a sequence

The modulo operator is perfect for creating cyclical behavior, such as rotating through a list of items:

days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]

def get_day(n):
    # Get the day of the week for the nth day, where day 0 is Monday
    return days[n % len(days)]

# Starting from Monday (day 0), what day is it after 10 days?
print(get_day(10))  # Output: "Thursday"

# What day was it 15 days ago from Monday?
print(get_day(-15))  # Output: "Sunday"
Thursday
Sunday

In this example, no matter how large or small (negative) n gets, the function will always return a valid day of the week.

Leap year calculation

While leap year calculations involve multiple conditions, the modulo operator is central to the algorithm:

Leap years follow a specific rule:

  • A year is a leap year if it is divisible by 4.
  • But if it's divisible by 100, it's not a leap year.
  • Unless it’s also divisible by 400, then it is a leap year.
def is_leap_year(year):

    return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)

# Test the function
years = [1900, 2000, 2004, 2020, 2023, 2024]
for year in years:
    if is_leap_year(year):
        print(f"{year} is a leap year")
    else:
        print(f"{year} is not a leap year")
1900 is not a leap year
2000 is a leap year
2004 is a leap year
2020 is a leap year
2023 is not a leap year
2024 is a leap year

This ensures that the Gregorian calendar leap year rules are applied correctly.

Practical Examples of Python Modulo

Here are some ways in which you can use the modulo operator in your own Python projects

Using modulo in loops

The modulo operator is frequently used in loops to perform actions at regular intervals:

# Print a message every 5 iterations
for i in range(1, 11):
    print(f"Processing item {i}", end=": ")
    if i % 5 == 0:
        print("Checkpoint reached!")
    else:
        print("Continuing...")
Processing item 1: Continuing...
Processing item 2: Continuing...
Processing item 3: Continuing...
Processing item 4: Continuing...
Processing item 5: Checkpoint reached!
Processing item 6: Continuing...
Processing item 7: Continuing...
Processing item 8: Continuing...
Processing item 9: Continuing...
Processing item 10: Checkpoint reached!

This pattern is useful for batch processing, progress reporting, or implementing any functionality that needs to occur periodically.

Modulo in real-world applications

Password hashing

In cryptographic applications, modulo arithmetic is fundamental. Here's a simplified example of how modulo might be used in a basic hashing function:

def simple_hash(text, modulus=1000000007):
    """A very simple hash function using modulo."""
    hash_value = 0
    for char in text:
        # Combine the current hash with the character's Unicode code point
        hash_value = (hash_value * 31 + ord(char)) % modulus
    return hash_value

# Test with some strings
print(simple_hash("hello"))  # Output a number between 0 and 1000000006
print(simple_hash("world"))
print(simple_hash("hello world"))
print(simple_hash("こんにちは"))  
99162322
113318802
204910434
807637228

This is a very basic example, as real cryptographic hashing is much more complex. The modulo operation ensures that the hash value stays within a manageable range while still preserving the properties of a good hash function.

Clock time calculation

Modulo is useful for handling time calculations, such as converting large numbers of hours into standard time formats.

def convert_to_12_hour_format(hours):
    return hours % 12 or 12  # Ensure 0 maps to 12

# Example
print(convert_to_12_hour_format(13))  # Output: 1
print(convert_to_12_hour_format(24))  # Output: 12
print(convert_to_12_hour_format(36))  # Output: 12

Here, the modulo operator wraps around hours in a 12-hour format.

Game development: Implementing a multiplayer turn system

In multiplayer turn-based games, we can use modulo to cycle through players.

players = ["Alice", "Bob", "Charlie"]
turns = 10

for turn in range(turns):
      current_player = players[turn % len(players)]
      print(f"Turn {turn + 1}: {current_player}'s move")
Turn 1: Alice's move
Turn 2: Bob's move
Turn 3: Charlie's move
Turn 4: Alice's move
Turn 5: Bob's move
Turn 6: Charlie's move
Turn 7: Alice's move
Turn 8: Bob's move
Turn 9: Charlie's move
Turn 10: Alice's move

Validating digits in barcodes

Many barcode systems use modulo operations to detect errors in scanned numbers.

def is_valid_isbn13(isbn):
    digits = [int(d) for d in str(isbn)]
    checksum = sum(d * (1 if i % 2 == 0 else 3) for i, d in enumerate(digits))
    return checksum % 10 == 0

# Example ISBN Checksum validation
print(is_valid_isbn13(9780306406157))  # Output: True
print(is_valid_isbn13(9780306406158))  # Output: False
True
False

Conclusion

The modulo operator is a versatile tool in Python's arsenal that extends far beyond simple remainder calculations. From determining odd/even numbers to implementing complex algorithms with cyclical patterns, modulo enables cleaner, more elegant solutions to various programming challenges.

By understanding both the basic functionality and the nuanced behavior with different types of numbers, you can leverage the modulo operator to write more efficient and readable code. The next time you find yourself implementing logic that involves cycles, rotations, or periodic events, remember that the modulo operator might be the perfect solution.

If you’re looking to learn more about how to use Python for your projects, check out our interactive course, Introduction to Data Science in Python

Python Modulo FAQs

How does the modulo operator work with negative numbers in Python?

In Python, when using the modulo operator with negative numbers, the result will have the same sign as the divisor.

Can the modulo operator be used with floating-point numbers?

Yes, the modulo operator works with floating-point numbers, but be aware of potential small rounding errors due to the way floats are represented in computers.

How is the modulo operator used in real-world applications?

The modulo operator is used in various real-world applications, such as hashing functions, clock time calculations, and error detection like ISBN validation.

Why is the modulo operator important in programming?

The modulo operator is crucial for solving problems that involve periodicity, division, and wrapping around, making it a versatile tool for efficient coding and algorithm design.


Benito Martin's photo
Author
Benito Martin
LinkedIn

As the Founder of Martin Data Solutions and a Freelance Data Scientist, ML and AI Engineer, I bring a diverse portfolio in Regression, Classification, NLP, LLM, RAG, Neural Networks, Ensemble Methods, and Computer Vision.

  • Successfully developed several end-to-end ML projects, including data cleaning, analytics, modeling, and deployment on AWS and GCP, delivering impactful and scalable solutions.
  • Built interactive and scalable web applications using Streamlit and Gradio for diverse industry use cases.
  • Taught and mentored students in data science and analytics, fostering their professional growth through personalized learning approaches.
  • Designed course content for retrieval-augmented generation (RAG) applications tailored to enterprise requirements.
  • Authored high-impact AI & ML technical blogs, covering topics like MLOps, vector databases, and LLMs, achieving significant engagement.

In each project I take on, I make sure to apply up-to-date practices in software engineering and DevOps, like CI/CD, code linting, formatting, model monitoring, experiment tracking, and robust error handling. I’m committed to delivering complete solutions, turning data insights into practical strategies that help businesses grow and make the most out of data science, machine learning, and AI.

Topics

Top Python Courses

track

Python Data Fundamentals

28hrs hr
Grow your data skills, discover how to manipulate and visualize data, and apply advanced analytics to make data-driven decisions.
See DetailsRight Arrow
Start Course
See MoreRight Arrow
Related

tutorial

Working with Modules in Python

Modules enable you to split parts of your program in different files for easier maintenance and better performance.

Nishant Kumar

8 min

tutorial

How to Square a Number in Python: Basic Examples and Advanced Methods

Squaring in Python is easy: Use the in-built ** operator or try NumPy, pow(), math.pow(), bitwise operators, and other functions for more versatile solutions.
Allan Ouko's photo

Allan Ouko

11 min

tutorial

Operators in Python

This tutorial covers the different types of operators in Python, operator overloading, precedence and associativity.
Théo Vanderheyden's photo

Théo Vanderheyden

9 min

tutorial

Python Count Tutorial

Learn how to use the counter tool with an interactive example.
DataCamp Team's photo

DataCamp Team

3 min

tutorial

Usage of Asterisks in Python

Many Python users are familiar with using asterisks for multiplication and power operators, but in this tutorial, you'll find out additional ways on how to apply the asterisk.
Hafeezul Kareem Shaik's photo

Hafeezul Kareem Shaik

9 min

code-along

Priceless Probability Puzzles in Python

Use Python to tackle some logic and probability puzzles
Justin Saddlemyer's photo

Justin Saddlemyer

See MoreSee More