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;
}
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!
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 .