Algorithms
Number Theory
C++
C#
Optimization

I need an optimal algorithm to find the largest divisor of a number N. Preferably in C or C

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you mean the largest proper divisor of N, the problem is much simpler than listing all divisors. The key observation is that the largest proper divisor is N divided by the smallest non-trivial divisor, so you only need to find the smallest factor greater than 1.

The Important Insight

Suppose N is composite and its smallest divisor greater than 1 is d. Then N / d is the largest proper divisor.

Why? Because any proper divisor larger than N / d would imply a complementary divisor smaller than d, which contradicts the assumption that d is the smallest non-trivial divisor.

This gives a very efficient algorithm:

  1. Check integers from 2 up to the square root of N.
  2. Stop at the first value that divides N.
  3. Return N / i.
  4. If no such divisor exists, N is prime and the answer is 1.

That is optimal for straightforward trial division because you never need to scan past the first factor or past the square root.

C++ Implementation

cpp
1#include <cmath>
2#include <cstdint>
3#include <iostream>
4
5std::uint64_t largestProperDivisor(std::uint64_t n) {
6    if (n <= 1) {
7        throw std::invalid_argument("n must be greater than 1");
8    }
9
10    if (n % 2 == 0) {
11        return n / 2;
12    }
13
14    std::uint64_t limit = static_cast<std::uint64_t>(std::sqrt(n));
15    for (std::uint64_t i = 3; i <= limit; i += 2) {
16        if (n % i == 0) {
17            return n / i;
18        }
19    }
20
21    return 1;
22}
23
24int main() {
25    std::cout << largestProperDivisor(100) << '\n';
26    std::cout << largestProperDivisor(29) << '\n';
27}

This code handles even numbers immediately and then checks only odd candidates. That cuts the work almost in half for large odd inputs.

Equivalent C# Version

csharp
1using System;
2
3public static class Divisors
4{
5    public static ulong LargestProperDivisor(ulong n)
6    {
7        if (n <= 1)
8            throw new ArgumentException("n must be greater than 1");
9
10        if (n % 2 == 0)
11            return n / 2;
12
13        ulong limit = (ulong)Math.Sqrt(n);
14        for (ulong i = 3; i <= limit; i += 2)
15        {
16            if (n % i == 0)
17                return n / i;
18        }
19
20        return 1;
21    }
22}

The logic is identical. Once the first factor is found, the answer is immediate.

Complexity Analysis

The worst-case time complexity is O(sqrt(N)), which happens when N is prime or has a large smallest factor. The space complexity is O(1).

For this specific problem, that is far better than enumerating every divisor up to N - 1. If you only need the largest proper divisor, generating all divisors is wasted work.

You can also see why the answer is trivial for even numbers: the smallest non-trivial divisor is always 2, so the largest proper divisor is always N / 2.

Edge Cases

You should define what happens for very small inputs:

  • 'N = 2 returns 1 because 2 is prime'
  • 'N = 3 returns 1'
  • 'N = 4 returns 2'
  • 'N = 1 usually has no proper divisor and should be rejected explicitly'

Also make sure you are solving the right problem. If the question allows N itself as a divisor, then the answer is always N, which is not interesting. Most algorithm discussions mean largest proper divisor.

Common Pitfalls

The biggest mistake is searching for the largest divisor directly by iterating downward from N - 1. That works, but it is unnecessarily slow.

Another issue is forgetting that factors come in pairs. Once you find the smallest factor, the largest proper divisor is already known. There is no need to continue searching.

Developers also sometimes loop to N / 2 instead of the square root. That is much slower for large inputs and still not necessary.

Finally, watch out for floating-point square root edge cases in low-level code. In performance-critical or very large integer scenarios, you may prefer a loop condition like i * i <= n with overflow-safe handling rather than relying on sqrt.

Summary

  • The largest proper divisor of N is N / d, where d is the smallest divisor greater than 1.
  • Search for the first divisor from 2 up to the square root of N.
  • Return 1 when N is prime.
  • The algorithm runs in O(sqrt(N)) time and O(1) space.
  • If someone includes N itself as a divisor, clarify the problem first because that version is trivial.

Course illustration
Course illustration

All Rights Reserved.