A deficient number is a positive integer whose proper divisors (all its divisors except the number itself) add up to less than the number. For example, 21 is deficient because 1 + 3 + 7 = 11, and 11 is smaller than 21. Checking a deficient number in Java comes down to adding the divisors and comparing the sum with the number.
We check deficient numbers in number-theory exercises, coding interviews and school programming assignments, mostly together with perfect and abundant numbers. The same divisor-sum code also helps whenever a program needs the divisors of a number.
The following example checks 21 with a stream that adds every divisor up to half of the number.
int n = 21;
int divisorSum = IntStream.rangeClosed(1, n / 2).filter(d -> n % d == 0).sum(); // 11
boolean deficient = divisorSum < n; // true
int deficiency = n - divisorSum; // 10
Notice that the loop stops at n / 2, because no proper divisor can be larger than half of the number. Next we look at the definition in more detail, a faster square-root version that works with long values, the difference from perfect and abundant numbers, and a way to classify thousands of numbers in one pass.
1. What Is a Deficient Number?
The sum of the proper divisors of n is called its aliquot sum, written s(n). A number is deficient when s(n) < n. Some textbooks use the sum of all divisors, sigma(n), which includes n itself, and write the same rule as sigma(n) < 2n. Both forms give the same answer.

The gap between the number and its aliquot sum is the deficiency, n – s(n), which equals 2n – sigma(n). For 21 the deficiency is 21 – 11 = 10. A few properties help when we test our code.
- Every prime number is deficient, because its only proper divisor is 1.
- Every power of a prime, such as 8 or 81, is deficient.
- Every proper divisor of a deficient or perfect number is also deficient.
- The number 1 is deficient, because it has no proper divisors and the sum 0 is less than 1.
The first deficient numbers are 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 21, 22 and 23, as listed in OEIS A005100. The numbers 6, 12, 18 and 20 are missing from that list, because 6 is perfect and the other three are abundant.
2. Checking a Deficient Number in Java
Every check has two parts. The first part adds the proper divisors, and the second part compares the sum with the number. The divisor sum is where the work happens, so the two methods differ only in how they find divisors.
2.1. Testing Every Candidate up to n / 2
The simplest method tries every number from 1 to n / 2 and keeps those that divide n with no remainder. It is correct and short, and it is fast enough for numbers up to a few million.
static boolean isDeficientSimple(int n) {
if (n < 1) {
throw new IllegalArgumentException("Deficient numbers are positive: " + n);
}
int sum = 0;
for (int d = 1; d <= n / 2; d++) {
if (n % d == 0) {
sum += d;
}
}
return sum < n;
}
boolean a = isDeficientSimple(21); // true
boolean b = isDeficientSimple(20); // false
boolean c = isDeficientSimple(1); // true
boolean d = isDeficientSimple(0); // IllegalArgumentException
The method rejects 0 and negative numbers with an IllegalArgumentException instead of returning a wrong false, since deficiency is defined for positive integers and a 0 here points to a bug in the caller.
2.2. Pairing Divisors up to the Square Root
Divisors come in pairs. When i divides n, the quotient n / i divides it too, so for 100 the pairs are (1, 100), (2, 50), (4, 25), (5, 20) and (10, 10). We only need to loop while i * i <= n, add both members of each pair, and add a square root once.
static long properDivisorSum(long n) {
if (n < 1) {
throw new IllegalArgumentException("Expected a positive number: " + n);
}
if (n == 1) {
return 0;
}
long sum = 1; // 1 divides every n > 1
for (long i = 2; i * i <= n; i++) {
if (n % i == 0) {
long pair = n / i;
sum += (pair == i) ? i : i + pair;
}
}
return sum;
}
static boolean isDeficient(long n) {
return properDivisorSum(n) < n;
}
long s21 = properDivisorSum(21); // 11
long s100 = properDivisorSum(100); // 117
boolean big = isDeficient(1_000_000_000_000L); // false
boolean bigPrime = isDeficient(999_999_999_989L); // true
The method uses long for the number and the sum, and it compares the aliquot sum with n instead of comparing sigma(n) with 2 * n. An int version of 2 * n overflows to a negative value for any n above 1,073,741,823, and the comparison gives a wrong result without any exception. The loop condition i * i <= n also avoids calling Math.sqrt() on every pass.
The square-root version needs about 1,000,000 loop passes for the 13-digit number 1,000,000,000,000, while the n / 2 version needs about 500 billion.
| n | Passes with d <= n / 2 | Passes with i * i <= n |
|---|---|---|
| 21 | 10 | 3 |
| 10,000 | 5,000 | 99 |
| 1,000,000,000,000 | 500,000,000,000 | 999,999 |
3. Deficient, Perfect and Abundant Numbers
Every positive integer falls into one of three classes, depending on whether its aliquot sum is smaller than, equal to or larger than the number. Perfect numbers are rare (6, 28, 496, 8128), and the abundant ones start at 12.
| Class | Rule | Example | Divisor sum |
|---|---|---|---|
| Deficient | s(n) < n | 21 | 1 + 3 + 7 = 11 |
| Perfect | s(n) == n | 28 | 1 + 2 + 4 + 7 + 14 = 28 |
| Abundant | s(n) > n | 12 | 1 + 2 + 3 + 4 + 6 = 16 |
An enum and Long.compare() turn the three cases into one method, so the caller gets a single value instead of three separate boolean checks.
enum NumberClass { DEFICIENT, PERFECT, ABUNDANT }
static NumberClass classify(long n) {
int cmp = Long.compare(properDivisorSum(n), n);
return cmp < 0 ? NumberClass.DEFICIENT
: cmp == 0 ? NumberClass.PERFECT
: NumberClass.ABUNDANT;
}
NumberClass k21 = classify(21); // DEFICIENT
NumberClass k28 = classify(28); // PERFECT
NumberClass k12 = classify(12); // ABUNDANT
NumberClass k945 = classify(945); // ABUNDANT
The last line is worth remembering. Most small odd numbers are deficient, but 945 is the smallest odd abundant number, so a test that assumes “odd means deficient” fails at 945.
4. Classifying a Whole Range at Once
Calling properDivisorSum() for every number in a large range repeats the same divisor search many times. A divisor-sum sieve works the other way around. For each d, it adds d to every multiple of d, so one pass over an array fills the aliquot sums of all numbers up to a limit.
static int[] aliquotSums(int limit) {
int[] sums = new int[limit + 1];
for (int d = 1; d <= limit / 2; d++) {
for (int m = 2 * d; m <= limit; m += d) {
sums[m] += d;
}
}
return sums;
}
int[] sums = aliquotSums(20_000);
long deficientCount = IntStream.rangeClosed(1, 20_000).filter(i -> sums[i] < i).count(); // 15043
long perfectCount = IntStream.rangeClosed(1, 20_000).filter(i -> sums[i] == i).count(); // 4
long abundantCount = IntStream.rangeClosed(1, 20_000).filter(i -> sums[i] > i).count(); // 4953
Three out of four numbers up to 20,000 are deficient. The sieve runs in about n log n steps and uses one int per number, so it suits ranges up to a few million. For single large values, the square-root method from section 2 uses no extra memory. The IntStream filters count each class from the shared array.
5. Building a Number Facts Card
Say a math-practice app for school students shows a “number facts” card for any number the student types. The card says whether the number is deficient, perfect or abundant and shows the deficiency or the excess. Students type anything, including spaces, letters and numbers with 15 digits, so the app must not crash on bad input.
static String factsCard(String input) {
long n;
try {
n = Long.parseLong(input.strip());
} catch (NumberFormatException e) {
return "Please type a whole number";
}
if (n < 1) {
return "Please type a number greater than 0";
}
long sum = properDivisorSum(n);
return switch (classify(n)) {
case DEFICIENT -> n + " is deficient by " + (n - sum);
case PERFECT -> n + " is perfect";
case ABUNDANT -> n + " is abundant by " + (sum - n);
};
}
String card1 = factsCard(" 21 "); // "21 is deficient by 10"
String card2 = factsCard("496"); // "496 is perfect"
String card3 = factsCard("12"); // "12 is abundant by 4"
String card4 = factsCard("abc"); // "Please type a whole number"
String card5 = factsCard("-5"); // "Please type a number greater than 0"
The card reuses properDivisorSum() and classify(), and the exhaustive switch over the enum makes the compiler check that every class has a message. Related exercises, such as listing the prime numbers from 2 to N, follow the same pattern of one reusable check plus a range filter, and more of them are collected in the Java examples index.
6. Deficient Number FAQs
Small inputs such as 1, and the link between deficient numbers, primes and odd numbers, lead to most wrong answers in this exercise.
6.1. Is 1 a deficient number?
Yes. The number 1 has no proper divisors, so its aliquot sum is 0, and 0 is less than 1. The method properDivisorSum() returns 0 for 1 through an explicit check, because the loop that starts with sum = 1 would count 1 as its own divisor.
6.2. Are all prime numbers deficient?
Yes. A prime p has only one proper divisor, 1, and 1 is less than every prime. Powers of primes are deficient too, for example 8 = 23 has the sum 1 + 2 + 4 = 7.
6.3. Is every odd number deficient?
No. Every odd number below 945 is deficient, but 945 has the proper divisors 1, 3, 5, 7, 9, 15, 21, 27, 35, 45, 63, 105, 135, 189 and 315, which add up to 975. Odd numbers with one or two distinct prime factors are always deficient.
6.4. What is the deficiency of a number?
The deficiency is how far the aliquot sum falls short of the number, n – s(n). Perfect numbers have a deficiency of 0, and abundant numbers have a negative deficiency, which we report as a positive abundance instead.
6.5. Why do we stop the loop at the square root?
Because every divisor larger than the square root pairs with one smaller than it. When the loop finds i, it also adds n / i, so all divisors are counted once the loop passes the square root. A perfect square, such as 100 = 10 x 10, needs the check pair == i so that 10 is added only once.
7. Conclusion
A deficient number has proper divisors that add up to less than the number itself. A loop up to n / 2 is enough for small inputs, and pairing divisors up to the square root handles a 13-digit number such as 1,000,000,000,000 in about a million steps.
Using long and comparing the aliquot sum with n avoids the 2 * n overflow. When we need a whole range, a divisor-sum sieve classifies every number in one pass, and an enum with a switch keeps deficient, perfect and abundant results in one place.
8. References
- OEIS A005100, Deficient numbers
- OEIS A005231, Odd abundant numbers
- IntStream Javadoc
- Long.compare() Javadoc
Happy Learning !!