Finding Perfect Number in Java: A Complete Guide
Updated on Jul 15, 2025 | 16 min read | 6.64K+ views
Share:
For working professionals
For fresh graduates
More
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.
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.
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:
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.
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:
This version runs faster than the basic loop. It keeps the logic clear while reducing the number of tests.
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:
This breaks the task into small, focused parts. It also makes testing and updating the program easier.
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:
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.
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:
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:
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
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.
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.
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:
Subscribe to upGrad's Newsletter
Join thousands of learners who receive useful tips
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:
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:
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:
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:
Also Read: Java Developer Salary in India (2025): Freshers, Experienced, Top Cities, Companies & Growth
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
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
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
Top Resources