Problem with perfect number in C

Asked

Viewed 2,087 times

0

I’m having trouble showing if the number is perfect, when I put in 6, it says it’s not perfect, and I can only use pointer and dynamic allocation. Someone would 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;
}
  • 1

    Your algorithm for checking if the number is perfect is wrong. You should only add up if it is a divisor and not add up all the numbers.

  • int sum = 0; and int i = 1; break the rule "I can only use pointer and dynamic allocation".

  • I recommend you, my dear, to take a table test. Try to solve for yourself, instead of looking for a solution on the internet, it is not so complicated. This will help you improve as a programmer...

2 answers

1


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, number 28 is perfect because:

28 = 1 + 2 + 4 + 7 + 14

Therefore, it follows a function (tested and commented) able to calculate whether an integer is perfect or not, 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 was dynamically allocated, look at this:

#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

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 a problem:

  • Pointer only usage and dynamic memory;
  • Correct execution of the required algorithm;

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

In perfectNumber(int fNumber), the error is in incrementing sum at all times. You should just increment if the rest split (%) result in zero.

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

Algorithm

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

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 viewed here.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.