1

I'm trying to make a program where the array size is not entered by the user,but the elements are, until 0 is entered.Now I want to check for each element which one is a perfect number,for that I have to do the sum of the divisors.Problem is I can't manage to do the sum of divisors for each element in the array,instead it adds all the divisors of all the elements in the array.

#include <stdio.h>

int main()
{
    int n = 1000, i, j, sum = 0;
    int v[n];

    for (i = 1; i < n; i++)
    {
        scanf("%d", &v[i]);
        if (v[i] == 0)
        {
            break;
        }

        for (j = 1; j < v[i]; j++)
        {
            if (v[i] % j == 0)
            {
                printf("%d", j);
                sum = sum + j;
            }
        }
    }

    printf("\n%d",sum);

    return 0;
}

OUTPUT

  • 1
    Can you elaborate on what you mean by a "Perfect" number? – Adan Vivero Nov 14 '21 at 23:51
  • 5
    Reset `sum` to zero before starting the search for factors of each array element. – Eric Postpischil Nov 14 '21 at 23:51
  • 1
    @AdanVivero: [Perfect number.](https://en.wikipedia.org/wiki/Perfect_number) – Eric Postpischil Nov 14 '21 at 23:51
  • 1
    Does this answer your question? [Perfect Number In C](https://stackoverflow.com/questions/4554351/perfect-number-in-c) – Renat Nov 14 '21 at 23:54
  • @Renat no because it's not using arrays,I can do this without using arrays . – plaguedoctor24 Nov 14 '21 at 23:58
  • A good design here would be to write a function that takes a single integer as an argument, and tests whether it is a perfect number. Then your `sum` will naturally be a local variable of that function, initialized on every call, and you would never have had this bug in the first place. – Nate Eldredge Nov 15 '21 at 00:18
  • More generally, define every variable in the narrowest scope where it is needed. Even with the code as it is, you do not need `sum` anywhere outside the `i` loop, so you could have defined and initialized it in that block, and again avoided this bug. – Nate Eldredge Nov 15 '21 at 00:20
  • I got it thanks @NateEldredge and Eric – plaguedoctor24 Nov 15 '21 at 00:38

1 Answers1

1

Brut force check can be very expensive. It is faster to build the table of perfect numbers using Euclides formula and then simple check if the number is perfect.

static unsigned long long getp(int x)
{
    return (2ULL << (x - 2)) * ((2ULL << (x - 1)) - 1);
}

int isperfect(unsigned long long x)
{
    const int primes[] = {2, 3, 5, 7, 13, 17, 19, 31};
    static unsigned long long array[sizeof(primes) / sizeof(primes[0])];
    int result = 0;

    if(!array[0])
    {
        for(size_t index = 0; index < sizeof(primes) / sizeof(primes[0]); index++)
        {
            array[index] = getp(primes[index]);
        }
    }
    for(size_t index = 0; index < sizeof(primes) / sizeof(primes[0]); index++)
    {
        if(x == array[index])
        {
            result = 1;
            break;
        }
    }
    return result;
}

The array of perfect numbers is build only one time on the first function call.

And some usage (your code a bit modified)

int main(void)
{
    size_t n = 1000, i;
    unsigned long long v[n];

    for (i = 1; i < n; i++)
    {
        scanf("%llu", &v[i]);
        if (v[i] == 0)
        {
            break;
        }
        printf("%llu is %s perfect number\n", v[i], isperfect(v[i]) ? "" : "not");
    }

    return 0;
}

https://godbolt.org/z/exMs345xb

0___________
  • 60,014
  • 4
  • 34
  • 74