Problem with perfect number in C

I'm having trouble showing if the number is perfect, when I put 6 it says it's not perfect, and I can only use pointer and dynamic allocation. Would anyone know how to help me?

 #include <stdio.h>
 #include <stdlib.h>
 #include <locale.h>

int perfectNumber(int fNumber) {
    int sum = 0;
    for(int i = 1; i < fNumber; ++i) {
        sum += i;
        if(fNumber % sum == 0) {
            return 0; // It's perfect
        } else {
            return -1; // it isn't perfect
        }
    }
}

int perfectVerify(int fSecondNumber) {
    if(fSecondNumber == 1) {
        return 1;
    }
    if(perfectNumber(fSecondNumber) == 0) {
        return 1;
    } else {
        return 0;
    }
}

int main()  {
    setlocale(LC_ALL, "Portuguese");

    int *number;
    number = malloc(sizeof(int));

    printf("Digite um número inteiro: ");
    scanf("%d", number);

    if(perfectNumber(*number) == 1) {
        printf("%d Um número perfeito\n", *number);
    } else {
        printf("%d Não é um número perfeito", *number);
    }

    return 0;
}
Author: Vagner Wentz, 2019-03-25

2 answers

According to Wikipedia, a perfect number is a natural number for which the sum of all its own natural divisors (excluding itself) is equal to the number itself.

For example, the number 28 is perfect because:

28 = 1 + 2 + 4 + 7 + 14

Therefore, follows a function (tested and commented) capable of calculating whether or not an integer is perfect, see only:

int eh_perfeito( int numero )
{
    int resto = 0;
    int soma = 0;
    int i = 0;

    /* Para todos os numeros entre 1 e o numero em questao menos 1... */
    for( i = 1; i <= (numero - 1); i++ )
    {
        /* Verifica se eh um divisor natural */
        resto = numero % i;

        /* Se for um divisor natural, inclui na soma */
        if(resto == 0)
            soma += i;
    }

    /* Verifica se a soma eh igual ao numero */
    if( soma == numero )
        return 1; /* Eh perfeito */

    /* Nao eh perfeito*/
    return 0;
}

Now, let's test the function by passing a number inteiro that has been dynamically allocated, see only:

#include <stdio.h>
#include <stdlib.h>

int eh_perfeito( int numero )
{
    int resto = 0;
    int soma = 0;
    int i = 0;

    for( i = 1; i <= (numero - 1); i++ )
    {
        resto = numero % i;

        if(resto == 0)
            soma += i;
    }

    if( soma == numero )
        return 1;

    return 0;
}

int main( void )
{
    /* Aloca memoria para acomodar o numero */
    int * pnumero = (int*) malloc( sizeof(int) );

    /* Le o numero do console */
    printf( "Digite um numero inteiro: ");
    scanf( "%d", pnumero );

    /* Verifica se eh um numero perfeito */
    if( eh_perfeito(*pnumero) )
        printf("Numero Perfeito!\n");
    else
        printf("Numero NAO Perfeito!\n");

    /* libera memoria alocada */
    free(pnumero);

    return 0;
}

Testing:

Digite um numero inteiro: 6
Numero Perfeito!

Digite um numero inteiro: 100
Numero NAO Perfeito!

Digite um numero inteiro: 101 
Numero NAO Perfeito!

Digite um numero inteiro: 99
Numero NAO Perfeito!

Digite um numero inteiro: 28
Numero Perfeito!

Digite um numero inteiro: 496
Numero Perfeito!
 1
Author: Lacobus, 2019-03-25 23:35:44

Let's see...

You seem to understand well what a perfect number is. Therefore, I will not dwell on this area.

What I see as problem:

  • using only pointers and dynamic memory;
  • correct execution of the required algorithm;

There is no way to assume to what extent you need to use only pointers. I will assume that erred only in the act of defining the function arguments - which should be pointers. Thus, the sum and i are free to be used without the need for dynamic allocation because they are temporary locations and number turns pointer inside the functions.

Em perfectNumber(int fNumber), the error is in incrementing sum always . You should only increment if the division of remainder (%) results in zero.

The function perfectNumber(int fSecondNumber) is unnecessary . Only the logic contained in perfectNumber(...) is enough.

Algorithm

I built a algorithm based on on yours. I changed the name from perfectNumber to isPerfect to get more elegant and logical in a statement if/else. I also fixed the problems I pointed out and adapted the code to the style I usually use because I find it clearer and lean .

Function isPerfect(...):

int isPerfect(int *number) {

    size_t i;   /* Boa prática para laços: usar size_t */
    int    sum;

    sum = 0;

    for( i = 1; i < (size_t) *number; ++i ) if( *number % i == 0 ) sum += i;

    if( sum == *number && *number > 0 ) return 1; /* É perfeito */
    else                                return 0; /* Não é perfeito */

}

Function main(...):

int main( void )  {

    int *number;


    setlocale(LC_ALL, "Portuguese");


    number = (int *) malloc(sizeof(int));

    printf("\nDigite um número natural: ");
    scanf("%d", number);


    if( isPerfect( number ) ) printf("%d é perfeito\n\n", *number);
    else                      printf("%d não é perfeito\n\n", *number);


    return 0;

}

After executing the code, we have the following input / output :

1 não é perfeito
...
5 não é perfeito
6 é perfeito
7 não é perfeito
...
27 não é perfeito
28 é perfeito

A version with argument input to the program can be seen here .

 1
Author: José, 2019-03-26 01:29:51