Writing a function that determines if a number is perfect

In summary, the function perfect does not actually tell you whether number is a perfect-number or not. All it does is add all the divisors of number and put it into sum. The part of the code that actually determines whether number is a perfect-number or not is inside the function main. You can do this more concisely, because the expression 'sum == number' itself has a Boolean value, so you can return it directly: bool perfect(int number) { return (sum == number); }
  • #1
Valour549
57
4
First of all there are plenty of answers on Google for this commonly searched problem, but none of them gives me the solution I am looking for.

What I am looking for is how to write a function which determines whether a parameter number is a perfect-number. Take the code below for example, notice how the function perfect doesn't actually tell you whether number is a perfect-number or not. All it does is add all the divisors of number and put it into sum. The part of the code that actually determines whether number is a perfect-number or not is inside the function main.

In other words, I am wanting to know how to put the actual determination (starting with... if(re==n)...) inside the function perfect, which I'm strugging with since my knowledge of function is that they end with return {expression} (if they do indeed return a value), or simply return; (if they don't return anything at all).
Code:
#include<iostream>
using namespace std;
int perfect(int number)
{
  int sum=0;
  for(int i=1;i<number;i++)
  {
    if(number%i==0)
    {
      sum=sum+i;
    }
  }
  return sum;
}
void main()
{
  int n;
  cout<<"Enter a number: ";
  cin>>n;
  int re= perfect(n);
  if(re==n)
    cout<<"\n\nYes!\n  It Is A perfect number.\n\n";
  else
    cout<<"\n\nNo! \n  It Is Not A Perfect Number.\n\n";
}
 
Technology news on Phys.org
  • #2
Valour549 said:
First of all there are plenty of answers on Google for this commonly searched problem, but none of them gives me the solution I am looking for.

What I am looking for is how to write a function which determines whether a parameter number is a perfect-number. Take the code below for example, notice how the function perfect doesn't actually tell you whether number is a perfect-number or not. All it does is add all the divisors of number and put it into sum. The part of the code that actually determines whether number is a perfect-number or not is inside the function main.

In other words, I am wanting to know how to put the actual determination (starting with... if(re==n)...) inside the function perfect, which I'm strugging with since my knowledge of function is that they end with return {expression} (if they do indeed return a value), or simply return; (if they don't return anything at all).
Code:
#include<iostream>
using namespace std;
int perfect(int number)
{
  int sum=0;
  for(int i=1;i<number;i++)
  {
    if(number%i==0)
    {
      sum=sum+i;
    }
  }
  return sum;
}
void main()
{
  int n;
  cout<<"Enter a number: ";
  cin>>n;
  int re= perfect(n);
  if(re==n)
    cout<<"\n\nYes!\n  It Is A perfect number.\n\n";
  else
    cout<<"\n\nNo! \n  It Is Not A Perfect Number.\n\n";
}
Why not add the test number==sum to your function "perfect", and return 0 if the number is not perfect, and 1 if the number is perfect?
 
Last edited:
  • Like
Likes Valour549
  • #3
A function that returns a value does not need to have a single 'return' statement as the last statement. Whenever the flow of control encounters a 'return' statement, control returns to the calling function and the specified value is passed back to the calling function as the value of the called function. So you can have something like this:

C:
    if (condition)
        return 1;
    else
        return 0;

Then in the calling function, you can have a statement like this:

C:
if(perfect(n) == 1)
    // do something
  else
    // do something else

Because your function has now effectively become a Boolean function (returns the result of a true/false) decision, I would prefer to redefine the function so it returns a value of type 'bool' (that is, either 'true' or 'false') instead of an int.

C:
bool perfect(int number)
{
  // other stuff omitted for brevity
  if (sum == number)
    return true;
  else
    return false;
}

You can do this more concisely, because the expression 'sum == number' itself has a Boolean value, so you can return it directly:

Code:
bool perfect(int number)
{
  // other stuff omitted for brevity
  return (sum == number);
}

(I don't think the parentheses are necessary, but I use them anyway because I think it looks nicer. Other people probably have different opinions.)

Now in your main() you can simply say this:

C:
if(perfect(n))
    // do something
  else
    // do something else

Actually, I think you can do this also with the version of the function that returns an int, because 0 is automatically converted to 'false' and non-zero is automatically converted to 'true' in a Boolean context. You might get a compiler warning about it. I'm not expert on the niceties of the C++ standard here.

By the way, why are you using 'void main()'?

https://isocpp.org/wiki/faq/newbie#main-returns-int
 
  • Like
Likes pbuk and Valour549
  • #4
I played around with it, do you something like this? I think this is error-free lol though it'd be nice if you could concur.
Code:
#include <iostream>
using namespace std;

int isPerfect(int);

int main()
{
    int n, result;
   
    cout<<"Enter a number: ";
    cin>>n;
    result=isPerfect(n);
   
    if(result==1)
        cout<<n<<" is a perfect number!"<<endl;
    else
        cout<<n<<" is not a perfect number."<<endl;
   
    return 0;   
}

int isPerfect(int number)
{
    int sum=0, result=0;
    for(int counter=1; counter<number; counter++)
    {
        if(number%counter==0)
            sum+=counter;       
    }
   
    if(number==sum && number!=0) // prevent zero from being a perfect number
        result=1;
       
    return result;
}

PS: The code in my first post wasn't my own. I just copied it from another site to make a point.
 
  • #5
Now my next question: Is it possible to somehow move the "if... else" portion of the function main into the function isPerfect ?

Say something like this
Code:
...
int isPerfect(int number)
{
   int sum=0, result=0;
   for(int counter=1; counter<number; counter++)
   {
       if(number%counter==0)
            sum+=counter;  
   }

   if(number==sum && number!=0)// prevent zero from being a perfect number
        return cout<<number<<" is a perfect number!"<<endl;
  else
        return cout<<number<<"is not a perfect number."<<endl;
}

and then I'll change the function main part to
Code:
int main()
{
    int n, result;
   
    cout<<"Enter a number: ";
    cin>>n;
    result=isPerfect(n);
    cout<<result;
   
    return 0;   
}
 
  • #6
Valour549 said:
Now my next question: Is it possible to somehow move the "if... else" portion of the function main into the function isPerfect ?

Say something like this
Code:
...
int isPerfect(int number)
{
   int sum=0, result=0;
   for(int counter=1; counter<number; counter++)
   {
       if(number%counter==0)
            sum+=counter;
   }

   if(number==sum && number!=0)// prevent zero from being a perfect number
        return cout<<number<<" is a perfect number!"<<endl;
  else
        return cout<<number<<"is not a perfect number."<<endl;
}

and then I'll change the function main part to
Code:
int main()
{
    int n, result;

    cout<<"Enter a number: ";
    cin>>n;
    result=isPerfect(n);
    cout<<result;

    return 0;
}
You could do something like this, but I'm not sure it's good practice.
The function isPerfect determines whether a number is perfect or not.
How a program uses this information is another thing: better keep the two tasks separated.

Of course this is not crucial is a very small program such as this one. But in principle I would keep the tasks separated.
 
  • Like
Likes jtbell and Valour549
  • #7
I tried it and turns out I can't. I think the compiler is saying that I can't put cout after return

if(number==sum && number!=0)// prevent zero from being a perfect number
return cout<<number<<" is a perfect number!"<<endl;
else
return cout<<number<<"is not a perfect number."<<endl;
 
  • #8
Valour549 said:
Now my next question: Is it possible to somehow move the "if... else" portion of the function main into the function isPerfect ?

In order for your new main() to work the way you want it to work, the function has to return a string. But this gets messy, because you have to encode the number into the string. The way to do this in C++ is to use a data type called 'ostringstream'. (Warning: I have not tested this, and it's been a while since I've used stringstreams.)

Code:
#include <string>
#include <sstream>

string isPerfect(int number)
{
   int sum=0, result=0;
   for(int counter=1; counter<number; counter++)
   {
       if(number%counter==0)
            sum+=counter;
   }

   ostringstream mystringstream;  // write to mystringstream just like you would to cout

   if(number==sum && number!=0)// prevent zero from being a perfect number
        mystringstream <<number<<" is a perfect number!"<<endl;
  else
        mystringstream <<number<<"is not a perfect number."<<endl;
return mystringstream.str();  // extract the string from the stringstream and return it
}
Code:
int main()
{
    int n;
    string result;
 
    cout<<"Enter a number: ";
    cin>>n;
    result=isPerfect(n);
    cout<<result;
 
    return 0; 
}
 
  • Like
Likes Valour549
  • #9
Valour549 said:
I tried it and turns out I can't. I think the compiler is saying that I can't put cout after return

That's because you've defined your function to return an 'int,' whereas 'cout' is an object of type 'ostream'.
 
  • Like
Likes Valour549
  • #10
Ah alright, I think I'll have to settle for what I've got so far for now xD

Thank you so much for all your help; much appreciated.
 
  • #11
You "liked" jtbell's post but then did something different! Your code would be clearer (which means more likely to be right first time, easier to debug and easier to maintain) something like this:
Valour549 said:
I played around with it, do you something like this? I think this is error-free lol though it'd be nice if you could concur.
Code:
int main()
...
    // do not declare result, you don't need it
...
    if (isPerfect(n))
...
/** (Heading comment omitted for brevity and because there is no one correct way) */
bool isPerfect(int candidate)
{
    int sum_of_factors = 0;

    // prevent zero from being a perfect number
    if (candidate == 0)
    {
        return false;
    }

    // iterate over potential factors, adding to sum if counter is a factor
    for (int trial_factor = 1; trial_factor < candidate; trial_factor++)
    {
        if (candidate % trial_factor == 0)
        {
            sum_of_factors += trial_factor;
        }
    }

    // return result of test for a perfect number
    return (candidate == sum_of_factors);
}
Separation of concerns is an important concept in programming (particularly OOP, but it also applies to procedural programming). You should never mix code that performs calculations in the same function as code associated with input or output.

Edit: better variable names
 
Last edited:

FAQ: Writing a function that determines if a number is perfect

1. What is a "perfect" number in mathematics?

A perfect number is a positive integer that is equal to the sum of its proper divisors (positive divisors excluding the number itself). In other words, it is a number that is half the sum of all its positive divisors.

2. How do you write a function to determine if a number is perfect?

To write a function that determines if a number is perfect, you first need to find all the divisors of the number. Then, you need to sum these divisors and check if the sum is equal to the number itself. If it is, then the number is perfect. Otherwise, it is not.

3. Can a number be both perfect and prime?

No, a number cannot be both perfect and prime. A prime number only has two divisors (1 and itself), so it cannot satisfy the condition of being the sum of all its divisors.

4. Is there a limit to how large a perfect number can be?

Yes, there is a limit to how large a perfect number can be. As of 2021, the largest known perfect number is 2^82,589,933 - 1, which has over 24 million digits.

5. What is the significance of perfect numbers in mathematics?

Perfect numbers have been studied since ancient times and have been a topic of fascination for mathematicians. They have connections to many other mathematical concepts, such as prime numbers and number theory. They also have practical applications in fields such as cryptography and computer science.

Similar threads

Back
Top