'Find the perfect number between two numbers

I'm new to Java, and in order to practice I found a task on the Internet:

"Find all the perfect numbers between the two numbers you enter."

By the way - a perfect number is a natural number equal to the sum of all its own divisors. So I got to work and ran into such a problem that when I enter two numbers.

For example: 1 100, I get the correct answer in the console: 6,28. But if the first number is, for example, 100 and the second is 500 I get this output to the console: 6,28,496,, while I should get only 496. That is, for some reason, the minimum value does not shorten the search for a perfect number.

Here's where I ended up:

import java.util.Scanner;

public class IsPerfect {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int min = in.nextInt();
        int max = in.nextInt();

        System.out.println(min +" to "+max+" perfect numbers:");
        for (min = 1; min <= max; min++) {
            int sum = 0;
            for (int e = 1; e < min; e++) {
                if ((min % e) == 0) {
                    sum += e;
                }
            }

            if (sum == min) {
                System.out.print(sum+ ",");
            }
        }
    }
}

If anyone has any advice on how to fix this error, I would sincerely appreciate it.



Solution 1:[1]

You are assigning the minimum value to 1, no matter what the user enters. Change your outer for loop to start from the minimum value the user enters:

import java.util.Scanner;

public class IsPerfect {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int min = in.nextInt();
        int max = in.nextInt();

        System.out.println(min +" to "+max+" perfect numbers:");
        for (; min <= max; min++) {
            int sum = 0;
            for (int e = 1; e < min; e++) {
                if ((min % e) == 0) {
                    sum += e;
                }
            }

            if (sum == min) {
                System.out.print(sum+ ",");
            }
        }
    }
}

Solution 2:[2]

I think that was the point.

import java.util.Scanner;

public class IsPerfect {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in); 
        
           int min = in.nextInt();
           
           int max = in.nextInt();
        
           System.out.println(min +" to "+max+" perfect numbers:");
        for (int i = min; i <= max; i++)  
            {  
                int sum = 0;  
                for (int j = 1; j < i; j++)  
                {  
                    if (i % j == 0)  
                        sum = sum + j;  
                }  
                if (sum == i)  
                    System.out.println(i+", ");  
            }

    }

}

Solution 3:[3]

Let me give you a piece of advise: integers in Java are defined as:

  • int 4 bytes: from -2,147,483,648 to 2,147,483,647

As a perfect number is positive, you only need to consider the ones from 0 to 2,147,483,647, and they are not that common:
6, 28, 496, 8128, 33550336 and the next one is already larger than the upper limit. So you just put those numbers in a basic collection (like an array) and you verify against that.

Solution 4:[4]

Once entered, min and max should remain constant to make the code easier to read.

You need two loops, which conventionally use i and j as their loop values.

Change your loops to:

for (int i = min; i <= max; i++) {  
    int sum = 0;  
    for (int j = 1; j <= i/2; j++) {  
        if (i % j == 0) {
            sum += j;  
        }
    }
    if (sum == i) {
        System.out.println(i + ", ");  
    }
}

Note the slight performance gain by only iterating j up to i/2

A further and greater improvement to performance is this for the inner loop, which only iterates up to the square root of i and finds factors 2 at a time (eg for 28, if 2 is a factor then so is 14):

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ThisaruG
Solution 2 KruII
Solution 3 Dominique
Solution 4