Finding Perfect Number in Java: A Complete Guide

By Pavan Vadapalli

Updated on Jul 15, 2025 | 16 min read | 6.64K+ views

Share:

Did you know? The “Perfect Number” problem (LeetCode #507) is marked as Easy, but still comes up a lot in Java interviews. Learning how to handle perfect numbers in Java helps you practice loops, condition checks, and divisor logic, which are all common in coding tests and interviews.

A perfect number in Java is a positive integer that is equal to the sum of its proper divisors, excluding the number itself. The smallest perfect number is 6, which is divisible by 1, 2, and 3, and the sum of these divisors, 1 + 2 + 3, equals 6. In Java, discovering a perfect number involves writing an algorithm that checks if a given number satisfies this condition.

In this blog, you will learn how to identify a perfect number in Java through practical examples. We’ll also walk you through step-by-step instructions to create a Java program that efficiently calculates whether a number is perfect.

Want to sharpen your Java programming and algorithm skills? upGrad’s software development courses can help you build a strong foundation and write cleaner, faster code, from perfect numbers to more advanced problems.

Perfect Number in Java: What is it and How to Find it?

Perfect numbers are special integers whose proper divisors add up exactly to the number itself. For instance, 6 is ideal because its divisors 1, 2, and 3 sum to 6. In Java, you can write a simple algorithm to check if a number meets this rule.

Perfect numbers also connect to Mersenne primes. If 2ⁿ − 1 is prime, then 2ⁿ⁻¹ × (2ⁿ − 1) produces a perfect number. Here are a few examples.

n

2n - 1 

Is 2n - 1 Prime?

Perfect Number Formula

Perfect Number

2 3 Yes 22-1 × 3 = 2 × 3 6
3 7 Yes 23-1 × 7 = 4 × 7 28

 

In 2025, knowing how to solve problems like finding a perfect number in Java can make a real difference in data analytics and software roles. If you want to build stronger coding and analytical skills, take a look at these courses that can help you work on data-focused projects and sharpen your programming basics.

In Java, using Mersenne primes helps generate perfect numbers without checking all divisors. Writing such programs builds skills in loops, conditionals, and mathematical logic. It’s a common topic in number theory, interviews, and coding exercises. Different methods, from simple loops to optimized checks, teach you how to write clear and efficient Java code.

Let's discuss each of them in detail.

1. Basic looping (up to num-1)

This method checks every number from 1 up to one less than the target number. For each value, it tests whether it divides the target number evenly. If it does, it adds it to a running total.

for (int i = 1; i < num; i++) {
    if (num % i == 0) {
        sum += i;
    }
}

Output:

28 is a perfect number.

Code Explanation: 

  • We define num = 28 as our test input.
  • We loop from 1 to num - 1 and check which numbers divide num without a remainder.
  • Every valid divisor is added to sum.
  • After the loop, we compare sum with num.
  • If both are equal, it's a perfect number. Otherwise, it's not.

This is the simplest way to solve the problem. It helps learn how to build loops and work with conditions. The downside is that it does more checks than needed, especially for larger numbers.

2. Looping up to num / 2

No proper divisor of a number can be more than half of that number. So there’s no reason to test values larger than num / 2. This version stops at num / 2, reducing unnecessary work.

for (int i = 1; i <= num / 2; i++) {
    if (num % i == 0) {
        sum += i;
    }
}

Output: 

28 is a perfect number.

Code Explanation: 

  • We test the number 28, which is known to be a perfect number.
  • The loop runs from 1 to num / 2 (i.e., up to 14), skipping unnecessary checks.
  • All divisors of 28 in that range (1, 2, 4, 7, 14) are added to sum.
  • If the final sum matches the original number, we confirm it is perfect.
  • This version saves time and resources while maintaining readability and correctness.

This version runs faster than the basic loop. It keeps the logic clear while reducing the number of tests.

Coverage of AWS, Microsoft Azure and GCP services

Certification8 Months

Job-Linked Program

Bootcamp36 Weeks

Already familiar with writing Java loops up to num / 2 to check divisors? The upGrad’s Executive Diploma in Data Science & AI takes you beyond these basics. Build on your programming foundation, explore advanced data techniques, and apply smarter algorithms to solve bigger problems across industries.

3. Helper function structure

Using a helper function makes the code easier to read and reuse. One function handles finding the sum of the divisors. Another checks if that sum equals the original number.

public static int sumOfDivisors(int num) {
    int sum = 0;
    for (int i = 1; i <= num / 2; i++) {
        if (num % i == 0) sum += i;
    }
    return sum;
}

public static boolean isPerfect(int num) {
    return sumOfDivisors(num) == num;
}

Output:

28 is a perfect number.

Code Explanation:

  • The main() method simply calls isPerfect(num) and prints the result.
  • sumOfDivisors(int num) calculates the sum of all proper divisors up to num / 2.
  • isPerfect(int num) returns true if the sum equals the original number.
  • This structure improves modularity and makes the logic reusable in larger programs or APIs.

This breaks the task into small, focused parts. It also makes testing and updating the program easier.

4. Recursive technique

Recursion can replace loops by calling the same function with smaller values. Here, the function checks each divisor, working down to zero. If the number is divisible by the current divisor, it adds it to the sum.

public static int sumDivisors(int num, int divisor) {
    if (divisor == 0) return 0;
    if (num % divisor == 0) return divisor + sumDivisors(num, divisor - 1);
    return sumDivisors(num, divisor - 1);
}

public static boolean isPerfect(int num) {
    return sumDivisors(num, num / 2) == num;
}

Output:

28 is a perfect number.

Explanation:

  • sumDivisors(num, divisor) recursively adds all divisors from num / 2 down to 1.
  • If the current divisor divides num, it’s included in the sum.
  • When divisor reaches 0, recursion stops by returning 0.
  • isPerfect() checks if the total sum equals the number, confirming it’s perfect.
  • This approach is conceptually elegant but may use more stack memory and is slower on large input

This version shows how to solve problems by breaking them into smaller subproblems. Although clear, it can use more memory and run slower for large numbers due to repeated function calls.

If recursion for perfect numbers sparks your curiosity, the Master’s in Data Science with upGrad takes it further with advanced algorithms and programming work. You’ll apply concepts like recursion to real data challenges. This builds the strong problem-solving skills needed for top tech roles.

5. Square root divisor pairing

This version takes advantage of the fact that divisors come in pairs. If i divides num, then num / i is also a divisor. By only looping up to the square root of the number, you can find both divisors at once.

int sum = 1;
int sqrt = (int) Math.sqrt(num);

for (int i = 2; i <= sqrt; i++) {
    if (num % i == 0) {
        sum += i;
        int pair = num / i;
        if (pair != i) sum += pair;
    }
}
return sum == num;

Explanation of Logic: 

  • Every divisor under sqrt(num) has a paired divisor above sqrt(num).
  • For example, if num = 28i = 2 gives the pair 14, and i = 4 gives 7.
  • This technique ensures you don’t check each number individually up to num / 2.
  • It avoids double-counting when i equals its pair (like sqrt(36) = 6).

Here’s a combined program that lets you test all methods on any number:

public class PerfectNumberChecker {

    // 1. Basic loop method
    public static boolean isPerfectBasic(int num) {
        int sum = 0;
        for (int i = 1; i < num; i++) {
            if (num % i == 0) sum += i;
        }
        return sum == num;
    }

    // 2. Optimized loop up to num/2
    public static boolean isPerfectOptimized(int num) {
        int sum = 0;
        for (int i = 1; i <= num / 2; i++) {
            if (num % i == 0) sum += i;
        }
        return sum == num;
    }

    // 3. Helper function method
    public static int sumOfDivisors(int num) {
        int sum = 0;
        for (int i = 1; i <= num / 2; i++) {
            if (num % i == 0) sum += i;
        }
        return sum;
    }

    public static boolean isPerfectHelper(int num) {
        return sumOfDivisors(num) == num;
    }

    // 4. Recursive method
    public static int sumDivisorsRecursive(int num, int divisor) {
        if (divisor == 0) return 0;
        if (num % divisor == 0) return divisor + sumDivisorsRecursive(num, divisor - 1);
        return sumDivisorsRecursive(num, divisor - 1);
    }

    public static boolean isPerfectRecursive(int num) {
        return sumDivisorsRecursive(num, num / 2) == num;
    }

    // 5. Square root optimization
    public static boolean isPerfectSqrt(int num) {
        if (num <= 1) return false;

        int sum = 1;
        int sqrt = (int) Math.sqrt(num);

        for (int i = 2; i <= sqrt; i++) {
            if (num % i == 0) {
                sum += i;
                int pair = num / i;
                if (pair != i) sum += pair;
            }
        }
        return sum == num;
    }

    public static void main(String[] args) {
        int num = 28;

        System.out.println("Checking number: " + num);
        System.out.println("Basic loop method: " + isPerfectBasic(num));
        System.out.println("Optimized loop method: " + isPerfectOptimized(num));
        System.out.println("Helper function method: " + isPerfectHelper(num));
        System.out.println("Recursive method: " + isPerfectRecursive(num));
        System.out.println("Square root optimization method: " + isPerfectSqrt(num));
    }
}

Sample Output (for num = 28):

Checking number: 28
Basic loop method: true
Optimized loop method: true
Helper function method: true
Recursive method: true
Square root optimization method: true

Explanation: 

  • Each method uses a unique technique to calculate the sum of proper divisors.
  • All methods return true for 28 because it’s a known perfect number.
  • The square root method offers the best balance between clarity and performance.
  • This program is great for comparing techniques and validating different approaches to the same problem.

Now that you know how to spot perfect numbers, why stop there? With a few smart tweaks, you can make your Java program quicker and ready for tougher problems.

Also Read: Careers in Java: How to Make a Successful Career in Java in 2025

How to Improve Perfect Number Programs in Java?

Checking for perfect numbers is a classic exercise for working with loops and conditionals in Java. However, many basic programs become slow or inefficient, especially when processing large numbers or performing repeated checks. 

Below are some ways to make your program more reliable, handle inputs safely, and speed it up so it can handle bigger workloads without wasting time.

1. Basic Java Program

Before making the program faster, it helps to get a simple version working first. The main steps are to check that the input is valid, then run the logic to see if the number is perfect. Here’s how to break it down:

Checking inputs

Always make sure the input is a positive integer before doing any calculations. Perfect numbers are only defined for positive values, so handling cases like zero, negative numbers, or unexpected input early prevents incorrect results or wasted computation. You can add a simple check to print a message and skip further work if the input isn’t valid. This also makes your program easier to debug and safer to use.

Main logic for finding perfect numbers

Once the input is confirmed valid, the next step is to figure out if the number is perfect.

  • Loop through numbers from 1 to num / 2 (since no proper divisor can be more than num / 2.
  • Add up the divisors that divide num exactly.
  • If the sum matches num, then it is a perfect number.

Example program using Scanner

import java.util.Scanner;

public class PerfectNumberFinder {

    public static boolean isPerfectNumber(int num) {
        if (num <= 0) return false;

        int sum = 0;
        for (int i = 1; i <= num / 2; i++) {
            if (num % i == 0) {
                sum += i;
            }
        }
        return sum == num;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("Enter a number to check if it's perfect: ");
        int number = scanner.nextInt();

        if (number <= 0) {
            System.out.println("Please enter a positive integer greater than zero.");
        } else if (isPerfectNumber(number)) {
            System.out.println(number + " is a perfect number.");
        } else {
            System.out.println(number + " is not a perfect number.");
        }

        scanner.close();
    }
}

Example runs

Enter a number to check if it's perfect: 28
28 is a perfect number.

Enter a number to check if it's perfect: -5
Please enter a positive integer greater than zero.

Enter a number to check if it's perfect: 27
27 is not a perfect number.

Code Explanation: 

  • Scanner is used to take user input from the console.
  • The isPerfectNumber() method loops through all divisors and calculates their sum.
  • If the sum equals the original number, it returns true; otherwise, false.
  • Input validation ensures only positive numbers are processed, avoiding unnecessary errors.
  • The program ends by closing the scanner to prevent memory leaks.

Subscribe to upGrad's Newsletter

Join thousands of learners who receive useful tips

Promise we won't spam!

Want to sharpen recursion, algorithms, and perfect number skills? The upGrad’s Executive Diploma in Machine Learning & AI can help you strengthen these foundations while building advanced AI skills that open new doors in your tech career.

2. Making the code faster

A basic perfect number check works fine for small inputs, but it can get slow for bigger numbers or repeated checks. You can cut down the work by using some simple math tricks. Here are a few ways to speed things up.

Divisor pairs and the square root trick

You can avoid a lot of extra checks by using the fact that divisors come in pairs. If i divides num, then num / i is also a divisor. This means you only need to loop up to the square root of num. For each divisor you find, add both i and num / i to the sum. Just make sure not to add the same number twice when i equals num/i. This small change can greatly reduce the number of iterations.

public static boolean isPerfectNumber(int num) {
    if (num <= 1) return false;

    int sum = 1;
    int sqrt = (int) Math.sqrt(num);

    for (int i = 2; i <= sqrt; i++) {
        if (num % i == 0) {
            sum += i;
            int pair = num / i;
            if (pair != i) {
                sum += pair;
            }
        }
    }
    return sum == num;
}

Explanation:

  • We skip 1 manually because it’s a divisor for all integers.
  • For each valid divisor i, its pair num / i is also added to the sum.
  • If both are equal (like i == sqrt(num)), we only add it once.
  • This technique cuts iteration count drastically, especially for large numbers

Stop early if the sum gets too large

You don’t always have to finish the whole loop. If the sum of the divisors becomes bigger than the original number, there’s no way it can be perfect. In that case, you can stop right away and save time.

public static boolean isPerfectNumber(int num) {
    if (num <= 1) return false;

    int sum = 1;
    for (int i = 2; i <= Math.sqrt(num); i++) {
        if (num % i == 0) {
            sum += i;
            if (i != num / i) {
                sum += num / i;
            }
        }
        if (sum > num) return false;
    }
    return sum == num;
}

Explanation:

  • We check if sum > num after each iteration.
  • This saves time when testing large non-perfect numbers.
  • The logic still includes divisor pairing and avoids duplicate additions.
  • It is especially helpful when processing a list of random numbers.

3. Using caching with HashSet

If your program checks the same numbers multiple times, you can speed things up by storing known perfect numbers in a HashSet. Then, before doing any calculations, simply check if the number is already in the set. This avoids repeating the same work and makes repeated checks almost instant.

import java.util.HashSet;

public class PerfectNumberMemoized {
    private static HashSet<Integer> cache = new HashSet<>();

    public static boolean isPerfectNumber(int num) {
        if (num <= 1) return false;
        if (cache.contains(num)) return true;

        int sum = 1;
        for (int i = 2; i <= Math.sqrt(num); i++) {
            if (num % i == 0) {
                sum += i;
                if (i != num / i) {
                    sum += num / i;
                }
            }
        }

        if (sum == num) {
            cache.add(num);
            return true;
        }
        return false;
    }
}

Explanation:

  • HashSet stores numbers that were already verified.
  • We skip the calculation if the number is already in the cache.
  • New perfect numbers are added for future checks.
  • This approach saves time in programs that re-check values often.

Using number theory functions

Some advanced programs use known formulas or prime factorization to compute the sum of divisors. This can be much faster for very large numbers. Libraries like GMP can help with this.

Writing and improving perfect number programs is a good exercise in writing loops, using conditionals, and reducing unnecessary work. It also connects programming with classic mathematical ideas. Trying out different methods shows how a few changes can make a program run much faster.

Suggested Use Cases:

  • Used in cryptographic algorithms, research, or high-performance computing.
  • Not typically required in beginner-level applications.
  • Worth exploring for advanced learners or math-heavy applications.

Also Read: Java Developer Salary in India (2025): Freshers, Experienced, Top Cities, Companies & Growth

How Does upGrad Help Discover the Concept of a Perfect Number in Java?

Finding a perfect number in Java means checking if a number equals the sum of its proper divisors. You can make your program run faster by looping only up to the square root and adding both divisors at once. This reduces unnecessary steps and improves how your code handles bigger inputs.

Working on this problem sharpens your use of loops, conditionals, and efficient logic. If you want more structured practice, upGrad offers courses with hands-on Java projects and feedback to help you grow your programming skills and prepare for roles in software development.

While we’ve highlighted top programs, here are additional courses crafted to sharpen your mastery of the perfect number concept in Java. 

If you're unsure which career path suits you best, upGrad’s personalized career guidance can provide the clarity and direction you need to move forward confidently. Plus, by visiting any upGrad center, you can jumpstart your journey with hands-on training that builds real-world skills to fast-track your professional growth.

Boost your career with our popular Software Engineering courses, offering hands-on training and expert guidance to turn you into a skilled software developer.

Master in-demand Software Development skills like coding, system design, DevOps, and agile methodologies to excel in today’s competitive tech industry.

Stay informed with our widely-read Software Development articles, covering everything from coding techniques to the latest advancements in software engineering.

Reference:
https://leetcodehelp.github.io/507.html

Frequently Asked Questions (FAQs)

1. How can I optimize the perfect number check algorithm in Java for efficiency?

2. How do I modularize perfect number logic using Java functions?

3. Can I use perfect number logic in Java for coding interviews or assessments?

4. How can I implement perfect number detection using Java’s Stream API?

5. How can I integrate perfect number logic into a Java-based GUI application?

6. How do I test perfect number logic in Java with JUnit?

7. Can I apply recursion in Java to check perfect numbers?

8. How can I handle very large inputs when checking perfect numbers in Java?

9. Can I find perfect numbers in a Java list using collections?

10. How should I deal with invalid inputs in perfect number programs?

11. How can I explain the real-world use of perfect number logic in Java?

Pavan Vadapalli

900 articles published

Pavan Vadapalli is the Director of Engineering , bringing over 18 years of experience in software engineering, technology leadership, and startup innovation. Holding a B.Tech and an MBA from the India...

Get Free Consultation

+91

By submitting, I accept the T&C and
Privacy Policy

India’s #1 Tech University

Executive PG Certification in AI-Powered Full Stack Development

77%

seats filled

View Program

Top Resources

Recommended Programs

upGrad

upGrad KnowledgeHut

Professional Certificate Program in UI/UX Design & Design Thinking

#1 Course for UI/UX Designers

Bootcamp

3 Months

upGrad

upGrad

AI-Driven Full-Stack Development

Job-Linked Program

Bootcamp

36 Weeks

IIIT Bangalore logo
new course

Executive PG Certification

9.5 Months