Search code examples
carraysloopsperfect-numbers

Perfect numbers, arrays, verification and operation


I'm trying to write a code in C which would allow a maximum input of 10 elements (natural numbers) in an array, identify all perfect numbers in the array, and do the product of all non-perfect numbers.

Euclid proved that 2^{p−1}(2^p−1) is an even perfect number whenever 2^p−1 is prime (Euclid, Prop. IX.36). For example, the first four perfect numbers are generated by the formula 2^{p−1}(2^p−1), with p a prime number, as follows: for p = 2: 2^1(2^2−1) = 6 for p = 3: 2^2(2^3−1) = 28 for p = 5: 2^4(2^5−1) = 496 for p = 7: 2^6(2^7−1) = 8128. (source: wikipedia)

When I compile the program, I get a triplicate or higher repetition of declaration of the perfect number.

e.g.:

... t[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 6}

'6' is a perfect number. '6' is a perfect number. '6' is a perfect number. ...

I also get a weird products.

e.g.:

... t[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 28}

'28' is a perfect number. '28' is a perfect number. '28' is a perfect number. '28' is a perfect number. '28' is a perfect number. '28' is a perfect number. '28' is a perfect number. '28' is a perfect number. '28' is a perfect number. '28' is a perfect number. '28' is a perfect number. '28' is a perfect number. '28' is a perfect number. ... The product of the non-perfect numbers is -1677721600

I'm really new to c, I can't seem to figure out what I'm doing wrong, but I wouldn't an handout either. Some guidance would be much appreciated.

#include <stdio.h>
#define MAX_BOUND 9  /*Array's bound*/

main() {

int i, /*array index*/
    t[i],
    d, /*divider*/ 
    sum, /*result for perfect number validation*/
    product; /*product of all non-perfect number in array*/

i = 0;

printf("Enter your natural numbers. \n");

for (i = 0; i <= MAX_BOUND; i++) {
printf("Number %d : ", i + 1);
scanf( "%d", &t[i]);
}

i = 0;
product = 1;
for (i = 0; i <= MAX_BOUND; i++) {   
    d = 1;
    sum = 0;
    while(d < t[i]) {
        if(t[i]%d == 0)
        sum = sum + d;
        d++;

            if(sum == t[i])
            printf("%d is a perfect number. \n", t[i]);
            else
            product = product * t[i];
    }
}  
printf("The product of the non-perfect numbers is %d \n", product);
getch();
}

Solution

  • In your declaration of the array, you have undefined behaviour because you used the wrong size:

    main() {
    
        int i, 
            t[i],
            d, /*divider*/ 
            sum, 
            product;
    
        i = 0;
    
        printf("Enter your natural numbers. \n");
    
        while (i <= 9) {
            printf("Number %d : ", i + 1);
            scanf( "%d", &t[i]);
            i++;
        }
    

    You probably meant to declare

    t[MAX_BOUND+1];
    

    (MAX_BOUND would be wrong, since you use the element t[MAX_BOUND]).

    At the point where t is declared, i has indeterminate value (not unlikely to be 0).

    With indeterminate array size, the accesses t[i] produce yet more indeterminate values (and again are undefined behaviour if i >= sizeof t / sizeof t[0]).

    The printing part,

            if(sum == t[i])
            printf("%d is a perfect number. \n", t[i]);
            else
            product = product * t[i];
    

    should be moved after the loop used to determine the divisor sum. With that inside the loop, you multiply product with t[i] a total of t[i] - 1 times (or t[i] - 2 if one of the intermediate sums equals t[i]) if t[i] is not perfect, and t[i]/2-1 times if t[i] is perfect. Also, you print t[i]/2 times for perfect numbers, and once for abundant numbers if one of the intermediate sums equals t[i] (I'm ignoring the theoretical possibility of odd perfect numbers, if there are any, they are far too large for int).

    Doing that produces correct output here.