C++ Perfect Number. Need some help revising - c++

I need some help revising this. It keeps only displaying 0s as the temp. Thank you.
// A program to determine whether the input number is a perfect number
// A perfect number is defined by the sum of all its positive divisors excluding itself
// 28: 1+2+3+7+14 = 28.
int perfect, limit, divisor;
cout << "Please enter a positive integer in order to define whether it is a perfect integer or not: " ;
cin >> perfect;
cout << endl;
int temp = 0;
int prevtemp = 0;
limit = 1;
divisor = 1;
while (limit < perfect)
{
if ((perfect % divisor) == 0)
{
divisor = prevtemp;
temp = prevtemp + temp;
}
limit++;
divisor++;
}
if (perfect == temp)
cout << "Your number is a perfect number!" << endl;
else
cout << "Your number is not a perfect number" << endl;
return 0;

You are never setting prevtemp to anything other than 0, so adding it to temp does nothing.
I believe you meant to say
if ((perfect % divisor) == 0)
temp += divisor; // not "divisor = prevtemp;"
The line "temp = prevtemp + temp" should also be removed with this solution; there is no longer any need for the prevtemp variable.
Also, there is no need to keep separate limit and divisor variables, since they are always the same. Just remove limit and change the loop condition to use divisor.
Also, as Mark Byers pointed out, the loop would be simpler to understand if you refactored it into a for loop rather than a while.

It seems like you are making it too complicated. Here's how you could do it:
int total = 0;
for (int i = 1; i < perfect; ++i)
{
if (perfect % i == 0)
total += i;
}
if (perfect == total)
cout << "Your number is a perfect number!" << endl;
else
cout << "Your number is not a perfect number" << endl;
Note that the running total is kept in a variable called total (you called this variable temp) and it is only increased when the number is an exact divisor.

I'm not sure, but I'd guess that in the code:
if ((perfect % divisor) == 0)
divisor = prevtemp;
you intended this to be prevtemp=divisor instead. That fixes an obvious problem, but still leaves quite a bit that doesn't look like it's doing that you probably intended. For example, I can't quite figure out what limit is intended to accomplish -- you initialize it and increment it, but as far as I can see, you never use its value (well, I guess you use it, but its value is always the same as divisor's so I'm not sure why you think you need both, or how limit makes any sense as its name).
Edit: It would make sense to have a limit. In particular, factors always come in pairs: one that's less than or equal to the square root of the number, and one that matches the first that's always greater than or equal to the square root of the number. As such, you don't need to scan all the way up to the number itself looking for factors -- you can set the square root of the number as the limit, and scan only up to that point. For each factor you find up to that point, the matching factor will be perfect/divisor. Since you've already gotten one working example, I guess I might as well just hope this isn't homework, and post an example as well:
bool is_perfect(int number) {
int limit = sqrt((double)number);
int sum = 1;
for (int i=2; i<=limit; i++)
if (number % i == 0)
sum += i + number/i;
return sum == number;
}

You are never assigning anything to prevtemp after initializing it to 0, so there is nothing to add to temp on the line that reads temp = prevtemp + temp.

#include<iostream>
#include<iomanip>
using namespace std;
int main(){
int n,i=1,sum=0;
cout<<"Enter a number: ";
cin >> n;
while(i<n){
if(n%i==0)
sum=sum+i;
i++;
}
if(sum==n)
cout << i << " is a perfect number";
else
cout << i << " is not a perfect number";
system("pause");
return 0;
}

Related

A simple recursion problem to simulate the spread of a computer virus

The problem I try to solve is:
A kind of computer virus will infect 100 computers at day 0.
Each of the 70% of the infected computer will infect one more computer.
There are 2 computer scientists fix the problem. Each of them can fix 1 Computer at day 1.
Each of the subsequent days, because of their increased experience, they can fix double so many computers as the previous day.
So, how many computers are still infected n days later ?
And how would the figures be from the day 0 to day 20?
To solve it, I wrote the following code:
#include<iostream>
#include<cmath>
using namespace std;
int computervirus(int n){ //n:Tage
int nr_virus= 100;
int nr_fixed;
int rest = 0;
if(n == 0) return 100;
if(n <= 20){
nr_virus += computervirus(n-1)*0.7;
nr_fixed = pow(2,n);
rest = nr_virus - nr_fixed;
}
return rest;
}
int main(){
cout << endl;
for(int i=0; i <= 20; i++){
cout << "at the "<< i << " .day are still "<< computervirus(i) << " infected Computers\n" <<endl;
}
return 0;
}
The output for the number(infected computers) are just not right, because the infecting speed is definitly faster als the repair at least first 9 days.
I'm not sure where the prrblem is. Can you help?
Your recursion for day n try to use 70% of the result of day n+1. This causes an infinite recursion. You must use 70% of day-1 and it will work. Now it's not 70% of the previous day, but it's 70% more so not * 0,7 but * 1,7.
And you need to take into account that there can't be a negative number of computer infected.
Finally, you overestimate the repairs: on day 1 it's 2, on day 2 it's 4, but as the 2 of day 1 were already counted in your recursion for day-1, so you deduce them twice. So you should only count the aditional computers fixed the day n. So pow(2, n-1).
The corrected code would look like:
int computervirus(int n){ //n:Tage
int nr_virus= 100;
int nr_fixed = 0;
int rest = 0;
if(n>0){
nr_virus = computervirus(n-1)*1.7; // n-1 not n+1
if (n==1)
nr_fixed = 2;
else nr_fixed = pow(2,n-1);
}
rest = nr_virus - nr_fixed;
if (rest<0)
rest = 0;
return rest;
}
Online demo
You forgot to use braces around the body of your for loop
int main(){
for(int i=0; i <= 20; i++)
{
cout << endl;
cout << "at the "<< i << " .day are still "<< computervirus(i) << " infected Computers\n" <<endl;
}
return 0;
}
Put a left brace { before the first statement in your loop, and a right brace } after the last.
Because the braces were missing only the first statement cout << endl; was inside the loop.

c++ sqrt() calculation assistance

So I'm studying c++ from the book ((C++ without fear)). and there's a code I didn't understand. I need to know how the code works. my problem is in the loop, I understand how it works, but I didn't understand how would it work with adding 1 to i. (EVEN WITH COMMENTS).
#include <iostream>
#include <cmath>
using namespace std;
int main() {
int n = 0; // Number to test for prime-ness
int i = 2; // Loop counter
bool is_prime = true; // Boolean flag...
// Assume true for now.
// Get a number from the keyboard.
cout << "Enter a number and press ENTER: ";
cin >> n;
// Test for prime by checking for divisibility
// by all whole numbers from 2 to sqrt(n).
while (i <= sqrt(n)) {
if (n % i == 0) { // If i divides n,
is_prime = false; // n is not prime.
}
++i; // Add 1 to i.
}
// Print results
if (is_prime) {
cout << "Number is prime." << endl;
}
else
{
cout << "Number is not prime." << endl;
}
return 0;
}
Adding 1 to i is simply to move on to test the next number the next time round the loop to test if it divides n. ++i is simply the prefix increment operator being invoked. Postfix i++; could be used here for the same effect, as could i = i + 1;, but since there exist some cases where prefix increment is faster than the alternatives (not the case here) it's usually a good habit to use prefix increment always unless you have a specific reason not to do so.

Simple while loop not terminating (beginner)

Here's what I want my program to do. Prompt the user to input 10 integers. Then my program adds up the even integers, adds up the odd integers, then displays both sums. Simple beginner's exercise. To do this, I'm using a while loop with a control variable. Here is the entirety of my code:
#include <iostream>
using namespace std;
int main()
{
int evenSum = 0;
int oddSum = 0;
int num;
int control = 0;
cout << "Enter 10 integers: " << endl;
cin >> num;
while (control <= 10)
{
if (num%2 == 0)
{
evenSum = evenSum + num;
}
else
{
oddSum = oddSum + num;
}
control++;
cin >> num;
}
cout << "The sum of the even integers is " << evenSum << endl;
cout << "The sum of the odd integers is " << oddSum << endl;
return 0;
}
To test this code, I'm using as input the first 10 positive integers, 1-10. However, I'm having a couple headaches. First, control never passes from the while loop, i.e. the program never gets to the point where it displays the evenSum and outSum variable values. I'm having a hell of a time figuring out why the while loop never terminates. As I've written it, the while condition will become false as soon as control = 11, and the control variable is incremented at the end of the while body, so it should not keep going. Yet it does.
My second headache (probably related) is that the sum of the even numbers in my input should be 30, and the sum of the odd numbers should be 25. However, while my program gets the oddSum correct, it only sums the evens up to 20, so it is not counting the last number (10) for some reason.
I have walked through this program carefully several times on paper. Also, I've had it display the variable values as it goes, so I can track what it is doing with each while loop. Eventually, it just stops displaying output, but without ever actually terminating. And it sums the evens and odds correctly, just without adding that last number.
It seems to me there is at least one off-by-one error here, possible 2 that are compounding each other. But I have tried adjusting my various values and it's nothing doing. My other thought is that I'm suspicious of the way I have set up my input stream. I.e. I'm unsure of what value will be assigned to num in the final iteration of the while loop.
Can anyone shed some light on either of these problems?
Read at the top of your loop (after checking the count)
// cin >> num;
while (control <= 10)
{
cin >> num;
if (num%2 == 0)
{
evenSum = evenSum + num;
}
else
{
oddSum = oddSum + num;
}
control++;
// cin >> num;
}
Try to trace the code execution. Manually. That is the best way to learn how computers think.
You’ll realize, that the loop condition is broken. You start counting from 0, continue up to 10 including, stop at 11. 0..10, that’s 11 numbers!
Furthermore, you are reading input once at the beginning and then once at the end of each iteration. That makes 12 reads.
When trying to read more input than supplied, the program blocks and waits for more input. A program in infinite loop is active, it consumes all your CPU resources. In this case the program is blocked and uses close to no resources.
ask to enter numbers inside the loop,its easy to understand when to input particular number
int control = 1;
while (control <= 10)
{
cout << "Enter integer at position:"+Control << endl;
cin >> num;
if (num%2 == 0)
{
evenSum = evenSum + num;
}
else
{
oddSum = oddSum + num;
}
control++;
}
I could not see an error. Only the issue that you have to put 11 numbers instead of 10. Have you tried to type 11 numbers?
hey i am also a beginner but i tried to answer your question. you could also use compound assignment i.e. += instead of repeating evenSum and oddSum twice.
#include <iostream>
using namespace std;
int main()
{
int evenSum = 0;
int oddSum = 0;
int num;
int control = 0;
cout << "Enter 10 integers: " << "\n";
while (control <= 9 )
{
cin >> num;
if (num % 2 == 0)
{
evenSum += num;
}
else
{
oddSum += num;
}
control++;
}
cout << "The sum of the even integers is: " << evenSum << "\nThe sum of the odd integers is: " << oddSum << "\n";
return 0;
}

Need help in basic C++ regarding how to properly loop through part and finding smallest value

Hi I'm needing some help. I'm in a intro to programming class and we are using c++. I am hoping someone can help me with an assignment that was due yesterday (I understand not to expect miracle responses but a girl can always try).
I'm having two problems that I know of. The first is regarding the smallest value.
The big one is in trying to make it loop for requirements of three times but not lose out on my total count. I cannot use arrays or anything I haven't learned yet which is why I've posted this. I've seen similar problems and questions but they have ended up with answers too complex for current progress in class. So here is the problems instructions:
Instructions
1) Write a program to find the average value, the largest value, and the smallest value of a set of numbers supplied as input from the keyboard. The number of values in the data set must be in the range 0 to 20, inclusive. The user will first enter the number of values in the data set(use variable int Number). Give the user 3 attempts at entering Number in the range given. If the value for Number entered is out of this range, write an error message but continue. If the user does not enter a valid value for Number within the 3 attempts print an error message and terminate the program.
2) Format only the output for the Average value to 3 decimal places when printed.
3) The values in the data set entered as input can be any value positive, negative, or zero.
4) Make the program output readable(see the example below). (Note: that you will notprint out the input values that were entered in this program like you normally are required to do. This is because we have not covered the “tool” needed to do so yet in our studies).
Below will be the output from the execution of your program:
(using these values in order for the data set --> 19.0 53.4 704.0 -15.2 0 100.0)
The largest number: 704
The smallest number: -15.2
The average of the 6 numbers entered: 143.533
yourName L4p2XX.cpp
Lab#4 prob 2 XX-XX-12
Here is my poor excuse at the solution:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double Number = 0, minValue, maxValue, average, total = 0;
int ct = 0, numCount;
cout << "How many numbers would you like to enter? ";
cin >> numCount;
for(ct = 1; ct <= numCount; ct += 1)
{
cout << "Enter Value from 0 to 20, inclusive: ";
cin >> Number;
if(Number > 20|| Number < 0)
for(int errorCt = 1; errorCt <= 4; errorCt += 1)
{
if(errorCt == 4)
{
cout << "You have had 3 attempts to enter a valid" <<
"number. \nPlease try this program again when you" <<
"are able to follow directions.";
cout <<"\nLBn\n"<<"L4P2LB.cpp\n"<<"11-05-12\n";
return 0;
}
cout << Number << "is not within range.\n" <<
"Please enter a number from 0 to 20: ";
cin >> Number;
} //end for loop
total += Number;
if(maxValue <= Number)
maxValue = Number;
if(Number <= minValue)
minValue = Number;
} //end for loop
cout << "The smallest number entered was " << minValue << endl;
cout << "The largest number you entered was " << maxValue << endl;
average = total/numCount;
cout << setprecision(3) << fixed << showpoint << "You entered " <<
numCount << " numbers. The average of these is " << average;
//Program ID
cout <<"\n" << "L4P2LB.cpp\n" << "11-05-12\n";
system ("pause");
return 0;
} // End main
Thank you in advance to anyone who can steer me in the right direction. Not looking for anyone to do my work I just need help in direction if nothing else or any suggestions as to what to do. Thanks again. Lynda
Also I need somehow to pause after the third time and exit properly. If I put the second pause in it won't work so am I missing something obvious there too!
The first problem I see is that you didn't initialize a couple of variables.
You should either initialize both minValue and maxValue variables with something which will overwritten in every case in the first loop (typically "positive/negative infinity", as provided by <limits>), or just set both to Number in the first iteration, regardless of their current value. So I'd suggest to fix this by replacing
if(maxValue <= Number)
maxValue = Number;
if(Number <= minValue)
minValue = Number;
with
if(maxValue <= Number || ct == 1)
maxValue = Number;
if(Number <= minValue || ct == 1)
minValue = Number;
as ct == 1 will be true in the first iteration.
That said, you check the 0..20 range condition on the wrong variable. You check it on the Number variable, but you should check the numCount variable. But you also didn't respect the requirement that the variable to store the "number of numbers" should be Number, so you did check the correct variable, but used the wrong to read the input into. This should fix this issue (I changed the variable name in the cin >>... line + moved the check outside your main loop):
cout << "How many numbers would you like to enter? ";
cin >> Number;
if(Number > 20|| Number < 0)
{
for(int errorCt = 1; errorCt <= 4; errorCt += 1)
...
if(errorCt == 4)
{
cout << "You have had 3 attempts to enter a valid" <<
"number. \nPlease try this program again when you" <<
"are able to follow directions.";
cout <<"\nLBn\n"<<"L4P2LB.cpp\n"<<"11-05-12\n";
return 0;
}
cout << Number << "is not within range.\n" <<
"Please enter a number from 0 to 20: ";
cin >> Number;
} //end for loop
}
for(ct = 1; ct <= Number; ct += 1)
{
...
}
...

Is there a way to not include a negative number in an average, when entering a negative number is how you terminate the program?

Sorry about last time for those who saw my previous thread. It was riddled with careless errors and typos. This is my assignment:
"Write a program that will enable the user to enter a series of non-negative numbers via an input statement. At the end of the input process, the program will display: the number of odd numbers and their average; the number of even numbers and their average; the total number of numbers entered. Enable the input process to stop by entering a negative value. Make sure that the user is advised of this ending condition."
And here is my code:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int number, total1=0, total2=0, count1=0, count2=0;
do
{
cout << "Please enter a number. The program will add up the odd and even ones separately, and average them: ";
cin >> number;
if(number % 2 == 0)
{
count1++;
total1+=number;
}
else if (number >= 0)
{
count2++;
total2+=number;
}
}
while (number>=0);
int avg1 = total1/count1;
int avg2 = total2/count2;
cout << "The average of your odd numbers are: " << avg1 << endl;
cout << "The average of your even numbers are " << avg2 << endl;
}
It seems to be working fine, but when I enter a negative number to terminate the program, it includes it with the rest of the averaged numbers. Any advice to get around this? I know it's possible, but the idea escapes me.
Your main loop should be like this:
#include <iostream>
for (int n; std::cout << "Enter a number: " && std::cin >> n && n >= 0; )
{
// process n
}
Or, if you want to emit a diagnostic:
for (int n; ; )
{
std::cout << "Enter a number: ";
if (!(std::cin >> n)) { std::cout << "Goodbye!\n"; break; }
if (n < 0) { std::cout << "Non-positve number!\n"; break; }
// process n
}
After here:
cout << "Please enter a number. The program will add up the odd and even ones seperately, and average them: ";
cin >> number;
Immediately check if the number is negative
if(number < 0) break;
Now you wouldn't need to use your do-while loop in checking if the number is negative. Thus, you can use an infinite loop:
while(true) {
cout << "Please enter a number. The program will add up the odd and even ones seperately, and average them: ";
cin >> number;
if(number < 0) break;
// The rest of the code...
}
ADDITIONAL:
There is something wrong in your code. You aren't showing the user how much the number of even and odd numbers are, and the total number of numbers entered.
ANOTHER ADDITIONAL: You should use more meaningful variable names:
int totalNumEntered = 0, sumEven = 0, sumOdd = 0, numEven = 0, numOdd = 0;
Of course I am not limiting you to these names. You can also use other similar names.
FOR THE INTEGER DIVISION PROBLEM:
You must cast your expression values to the proper type (in this case, it is float). You should also change the averages variables' types to float:
float avg1 = float(total1) / float(count1);
float avg2 = float(total2) / float(count2);
Immediately after cin >> number, check for < 0, and break if so. Try to step through the program line by line to get a feel for the flow of execution. Have fun learning, and good luck!