How To Check If A Number Is Prime In Python

5 min read

Checking if a number is prime is a fundamental concept in computer science and mathematics, often serving as a gateway to understanding algorithmic complexity and optimization. Even so, in Python, this task can be approached in several ways, ranging from the naive brute-force method to highly optimized probabilistic tests used in cryptography. Mastering these techniques not only sharpens your coding skills but also provides insight into how computational efficiency scales with input size.

Not the most exciting part, but easily the most useful Not complicated — just consistent..

Understanding Prime Numbers and Basic Logic

A prime number is a natural number greater than 1 that has no positive divisors other than 1 and itself. The first few primes are 2, 3, 5, 7, 11, and 13. Conversely, a composite number has at least one divisor other than 1 and itself. The number 1 is neither prime nor composite It's one of those things that adds up. Turns out it matters..

The most intuitive way to check for primality is trial division: attempt to divide the number n by every integer from 2 up to n-1. If none do, n is prime. Day to day, if any division results in a remainder of zero, n is composite. While logically sound, this approach is computationally expensive for large numbers, operating in O(n) time complexity Still holds up..

The Naive Implementation in Python

Let's start with the most basic translation of the definition into code. This version is excellent for learning syntax but unsuitable for production use with large integers.

def is_prime_naive(n):
    if n <= 1:
        return False
    for i in range(2, n):
        if n % i == 0:
            return False
    return True

# Example usage
print(is_prime_naive(29))  # True
print(is_prime_naive(100)) # False

Key observations:

  • The function immediately returns False for numbers less than or equal to 1.
  • The loop range(2, n) checks every single integer.
  • Python’s modulo operator % calculates the remainder.

This works perfectly for small inputs but becomes noticeably slow as n grows into the hundreds of thousands or millions The details matter here..

Optimization 1: Checking Up to the Square Root

The first major algorithmic leap comes from a mathematical property: if a number n has a divisor greater than its square root, it must also have a corresponding divisor smaller than its square root.

As an example, take 36. The square root is 6. Now, divisors are pairs: (2, 18), (3, 12), (4, 9), (6, 6). So naturally, in every pair, one number is ≤ 6 and the other is ≥ 6. So, we only need to check divisors up to int(math.Think about it: sqrt(n)) + 1. This reduces the time complexity from O(n) to O(√n), a massive improvement.

import math

def is_prime_sqrt(n):
    if n <= 1:
        return False
    if n == 2:
        return True
    if n % 2 == 0:
        return False
    
    limit = int(math.sqrt(n)) + 1
    for i in range(3, limit, 2): # Skip even numbers
        if n % i == 0:
            return False
    return True

This is the bit that actually matters in practice.

Improvements in this version:

  1. Early exit for even numbers: Since 2 is the only even prime, we check n % 2 == 0 immediately.
  2. Step size of 2: The loop range(3, limit, 2) iterates only over odd numbers (3, 5, 7...), halving the iterations again.
  3. math.sqrt: Efficiently calculates the boundary.

Optimization 2: The 6k ± 1 Pattern

All primes greater than 3 can be written in the form 6k ± 1 (where k is a positive integer) Took long enough..

  • 6k, 6k+2, 6k+4 are divisible by 2.
  • Integers can be expressed as: 6k, 6k+1, 6k+2, 6k+3, 6k+4, 6k+5. Plus, * 6k+3 is divisible by 3. * This leaves only 6k+1 and 6k+5 (which is 6k-1) as potential prime candidates.

We can take advantage of this to skip checking multiples of 2 and 3 entirely, reducing the candidates to test by roughly 66%.

def is_prime_6k(n):
    if n <= 1:
        return False
    if n <= 3:
        return True # 2 and 3 are prime
    if n % 2 == 0 or n % 3 == 0:
        return False
    
    i = 5
    while i * i <= n:
        if n % i == 0 or n % (i + 2) == 0:
            return False
        i += 6
    return True

How the loop works:

  • i starts at 5 (which is 6*1 - 1).
  • i + 2 is 7 (which is 6*1 + 1).
  • Next iteration i becomes 11 (62 - 1), i+2 is 13 (62 + 1).
  • The condition i * i <= n avoids the overhead of calling math.sqrt repeatedly inside the loop condition, though math.isqrt(n) (available in Python 3.8+) is even faster and precise for integers.

Deterministic Miller-Rabin for Large Integers

For very large numbers (e.g., 100+ digits), trial division—even optimized—is infeasible. The Miller-Rabin primality test is a probabilistic algorithm that can be made deterministic for specific ranges by testing a fixed set of bases (witnesses).

For 64-bit integers (up to 2^64), testing the first 12 prime bases [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37] guarantees a correct result. This runs in O(k log³ n) time, making it exponentially faster than trial division for large inputs Easy to understand, harder to ignore..

def is_prime_miller_rabin(n):
    if n < 2:
        return False
    # Small primes check
    small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
    for p in small_primes:
        if n % p == 0:
            return n == p

    # Write n-1 as d * 2^s
    d = n - 1
    s = 0
    while d % 2 == 0:
        d //= 2
        s += 1

    # Deterministic bases for n < 2^64
    # Source: https://miller-rabin.This leads to appspot. com/
    bases = [2, 325, 9375, 28178, 450775, 9780504, 1795265022]
    # Note: The set above works for 64-bit. 
Up Next

Latest and Greatest

If You're Into This

Cut from the Same Cloth

Thank you for reading about How To Check If A Number Is Prime In Python. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home