# Thread: This is homework but I'm really stuck

1. ## This is homework but I'm really stuck

I'm in a C++.NET class, and last took math 20 years ago.

I have a classmate that has shared with me the following code for a program designed to estimate e using

e = 1 +1/1!+1/2!+ ..

Please see their code, which works, but doesn't do what I want it to, sure I could just copy it, but I'm trying to learn by studying it.

Code:
```int _tmain

float e,
float num,
float num1;

e = 1;
num = 1;
num1 = 1;

while (num < 20 )
{
num1 = num1 * num;
e = e + (1 / ( 1 * num1 ) );
num = num + 1;
}

cout << "e =  " << e;

return 0;```
Now what I want to be able to do is pretty much the same thing, except that I wanted instead of a constant in the while loop, I wanted the constant to be set by the user.

Here was my code which I used against theirs to check the accuracy, but it isn't working right:

Code:
```int _tmain()
{

float ulim; //Upper limit of the computation to be input by user
float result; // The computation will return this value
float counter; // Counter for while loop

result = 1;
counter = 1;

cout << "Please enter the upper limit for this computation  ";
cin >>ulim

while (counter<ulim)

{

ulim = ulim*counter;
result = result +( 1 / ( 1* ulim));
counter = counter + 1;
}

cout << "Best estimate of e based upon input is:  " <<result;

return 0;
}```
Thank you in advance for taking the time to read this.

After working on 4 new programming problems (I've managed to work out 2 of these) over the past 6 days, for a total of about 54 hours and countin (last week I didn't even know what a factorial is, but hours on Google, have changed that), I have tried so many things and it now results in total confusion when I work with any code...I want to learn, I want to put the work and get something from this, but I admit defeat, I don't know what I'm doing wrong and I could really use some help.

I'm not sure if I am coming across correctly, but I hope someone can point out where I'm whrong and why, and assist me with what I need to do, I will learn so much better that way. Right now I am fighting discouragement after 54 hours and I feel stupid...

2. I dont think this loop will end

Code:
```while (counter<ulim) // Endless loop see below

{

ulim = ulim*counter; // Loop doesnt end becos your constantly
increasing the size of ulim. So counter will always be less than ulim.```
If The first code is pretty much the same as your code. Then you should look at variable num1 you probably misplaced it somwhere.

3. Ok lets look at a few things:

e = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + ...

So we look at the denomitor: 0!, 1!, 2!, 3!, 4!, ...
and then we expand them out: 1, 1, 2 * 1, 3 * 2 * 1, 4 * 3 * 2 * 1, ...

So ulim should tell you how many iterations to do. Since the 0! kinda throws off the pattern we'll move that out of the loop so you get something like:
Code:
```int main() // not _tmain()
{
float e = 1; // 1/0! == 1
unsigned fact = 1;  // 0! == 1, unsigned so we can use bigger values
int ulim; // make this an int, not a float

cout << "Please enter the upper limit for this computation  ";
cin >>ulim; // you forgot the ;

for (int count = 1; count < ulim; count++) // start from 1 since we already did one iteration, also makes the body of the loop easier
{
fact = fact * count;  // every iteration causes count to increment so we just multiple the new value of count with the old value of fact to get the factorial
// fact *= count; another way you could have written the above line
e = e + 1.0 / fact;
// e += 1.0 / fact;  another way you could have written the above line
}

cout << "Best guess: "<< e << endl;
}```
Hope that helps

Edit: Also of importance: Remember that factorial gets really big, really fast so if the user inputs say 10000 as the number of iterations then you'll easily exceed the amount an interger can be expected to hold

4. Then use a double for fact.

But note that before factorial overflows 32 bits, you've reached the precision limit of a float anyway.

5. Thank you so much - I really appreciated this assistance - your explanations were great, and I don't know what I would have done if not for your guidance.

Please comment on the code below. I didn't realize that I had an infinte loop until you pointed it out. I had to use While, since for aren't covered in this chapter, only if and while...

Code:
```#include "stdafx.h"
#include <iostream>;
using namespace std;

int _tmain()
{

int ulim; //Upper limit of the computation to be input by user
float e; // The computation will return this value
int count; // Counter for while loop
double fact; // factorial

e = 1;
count = 1;
fact = 1;

cout << "Please input the upper limit between 1- 10 for this factorial:  "; // here the user is prompted for the ulimit
cin >>ulim;

while (ulim >10)
{
cout << "Please enter in a number between 1-10.  This number is too high: "; //error checks for a number too high
cin >>ulim;
}

while (count < ulim) //As long as the count is less than the upper limit this loop will execute

{

fact = fact*count; //as count moves up it simulates the factorial moving up, since it increases to the upper limit
e = e+( 1 / ( 1* fact));  //e is set to 1, so it will build up to the upper limit each cycle thru the loop
count += 1;  //adds one to count at the end of each cycle thru the loop till it equals ulim
}

cout << "Best estimate of e based upon input is:  " <<e;

return 0;
}```

6. why are you multipling by 1 here?
Code:
`( 1* fact)`
Code:
```cout << "Please input the upper limit between 1- 10 for this factorial:  "; // here the user is prompted for the ulimit
cin >>ulim;

while (ulim >10)
{
cout << "Please enter in a number between 1-10.  This number is too high: "; //error checks for a number too high
cin >>ulim;
}```
A do {} while() loop would probably be more useful here. Also what happens if the user enters -1?

Code:
`int _tmain()`
And your purpose of using _tmain() is what?

As a general comment, you need to work on your indentation style.

7. Originally Posted by Rashakil Fol
Then use a double for fact.

But note that before factorial overflows 32 bits, you've reached the precision limit of a float anyway.
Using a double would be a worse solution. By the time a 32 bit integer (esp an unsigned) nears the max value you are adding a negligible amount to e. The better option is to be aware of it and put preventative measures in place.

8. Take this code for what it is, a modification of improved error checking of your input. Note that if a user enters a decimal number, it's treated as an int and the decimals are dropped.

Code:
```#include <iostream>
using namespace std;

int main()
{

int ulim = 1; //Upper limit of the computation to be input by user
float e = 1; // The computation will return this value
int count = 1; // Counter for while loop
double fact = 1; // factorial
int uservalue = 2; //2 used to indicate first time
string outline;

while (uservalue != 1)
{
if (uservalue == 0)
{
cout << ulim << " is not in range.  Please enter in a number between 1-10:";
}
else
{
cout << "Please enter in a number between 1-10: ";
}

cin >> ulim;
if ((ulim <= 0)  || (ulim > 10))
{uservalue = 0;}
else
{uservalue = 1;}
}

while (count < ulim) //As long as the count is less than the upper limit this loop will execute

{

fact = fact*count; //as count moves up it simulates the factorial moving up, since it increases to the upper limit
e = e+( 1 / ( 1* fact));  //e is set to 1, so it will build up to the upper limit each cycle thru the loop
count += 1;  //adds one to count at the end of each cycle thru the loop till it equals ulim
}

cout << "Best estimate of e based upon input is:  " <<e<<endl;

return 0;
}```

9. Originally Posted by Thantos
Using a double would be a worse solution. By the time a 32 bit integer (esp an unsigned) nears the max value you are adding a negligible amount to e. The better option is to be aware of it and put preventative measures in place.
Do you read only the first sentence of people's replies?

10. Do you believe in rhetorical questions?

11. Using a double when computing factorial is not bad. Factorials can be stored with no error up to larger values in a double than in a 32-bit integer, and what would overflow a 32-bit integer causes no problems with a double. The number will just get converted to a double anyway when you divide it under 1.0.

It's true that if the user inputs 10000, a lot of unnecessary computation is performed, but the whole fun of this program is being able to input whatever you want and see how the accuracy changes and whether it stops growing. (For extra fun, rewrite the program to reverse the order of addition and see how the answers change! :-))

12. Originally Posted by Rashakil Fol
Do you read only the first sentence of people's replies?
Actually I read your entire response, your point? Also the double will run out of precision at a lower value then a 32 bit unsigned int would overflow on.

13. Originally Posted by Thantos
Actually I read your entire response, your point? Also the double will run out of precision at a lower value then a 32 bit unsigned int would overflow on.
This is incorrect. Because the mantissa of a double is 52 bits long, any integer that can be exactly represented in a 53 bit unsigned integer representation can be exactly represented by a double. And so can its negative. Doubles can represent anything that 54 bit signed integers can represent.

Here's some C code (C in a C++ forum because I don't feel like dealing with setprecision and such) that shows this.

Code:
```#include <stdlib.h>
#include <stdio.h>

void showbits(void * p, size_t len) {

unsigned char ch;
int i;

while (len --) {
ch = *((unsigned char *) p)++;
for (i = 0; i < 8; ++i) {
putchar('0' + (ch & 1));
ch >>= 1;
}
}
return;
}

void drawline(double x) {
printf("%17.0f ", x);
/*  showbits(&x, sizeof(double));*/
putchar('\n');
return;
}

int main(void) {

double x = 1.0;
int i;
for (i = 0; i < 53; ++i) {
x *= 2.0;
drawline(x);
drawline(x + 1.0);
drawline(x + 2.0);
drawline(x + 3.0);
putchar('\n');
}

return 0;
}```
If you want to see what the bits of the double look like, uncomment the call to the showbits subroutine. You might want a terminal wider than 80 characters for this, or modify the code to insert a newline character before the showbits call. Count the bits of the mantissa (or count the bits of the exponent and sign bit and subtract from 64) and you'll get 52. You'll see the very last group of numbers meet the limit of the double's precision. You'll be able to recognize the mantissa because the exponent keeps incrementing.

14. To clear up some wordings:

This is not C++.NET, aka Managed C++. This is normal C++ developed with Visual Studio.NET.

_tmain is a Microsoft specific macro for UNICODE compilation and standard for Visual Studio.NET projects. It doesn't really make sense here, though.

Popular pages Recent additions