e power x - C++

Hello,

I want to write the below program. (with three precision)

Question:

https://i.ibb.co/6n317Hp/Screenshot-2021-06-14-121602.jpg

Two examples:
Input:
5
10

Output:
143.689

Input:
3
15

Output:
20.086

My result is: (80% correct and one answer is wrong. I don't have Test 4)

https://i.ibb.co/KrvZ0tT/Screenshot-2021-06-14-121933.jpg

What is your guess?

Thanks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<iostream>
#include<math.h>
#include<iomanip>
using namespace std;

unsigned long long int fact(int n)
{
	if (n == 0 || n == 1)
		return 1;
	return n * fact(n - 1);
}

int main()
{
	double x;
	double n;
	cin >> x >> n;

	double sum = 0;

	if (n == 0)
	{
		sum = pow(x, 0) / fact(0);
	}
	else
	{
		for (int i = 0; i < n; i++)
		{
			sum += pow(x, i) / fact(i);
		}
	}
	cout << fixed;
	cout << setprecision(3) << sum;

	return 0;
}
Shervan360 wrote:
What is your guess?


Your factorial probably overflowed.

Don't use it - write each new term as a multiple of previous ones. DON'T compute a factorial.
Try

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;


double myExp( double x, int n )
{
   double term = 1, sum = term;
   for ( int p = 1; p < n; p++ )
   {
      term *= x / p;
      sum += term;
   }
   return sum;
}


int main()
{
   int n;
   double x;

   cout << "Input x, n: ";
   cin >> x >> n;
   cout << fixed << setprecision( 3 ) << myExp( x, n ) << '\n';
}


I can't see you getting an answer if x=1000 and n=1000, though.
I did but Test 4 is wrong.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<iostream>
#include<math.h>
#include<iomanip>
using namespace std;


int main()
{
	double x;
	double n;
	cin >> x >> n;
	unsigned long long int f = 1;

	double sum = 0;

	if (n == 0)
	{
		sum = pow(x, 0) / f;
	}
	else
	{
		sum = pow(x, 0) / f;
		for (int i = 1; i < n; i++)
		{
			f *= i;
			sum += pow(x, i) / f;
		}
	}
	cout << fixed;
	cout << setprecision(3) << sum;

	return 0;

}
Last edited on
No, you are still de facto calculating a factorial (in f) and trying to fit it in an integer.

Try
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;


double myExp( double x, int n )
{
   double term = 1, sum = term;
   for ( int p = 1; p < n; p++ )
   {
      term *= x / p;
      sum += term;
   }
   return sum;
}


int main()
{
   int n;
   double x;

   cout << "Input x, n: ";
   cin >> x >> n;
   cout << fixed << setprecision( 3 ) << myExp( x, n ) << '\n';
}

In additon to what lastchance said - also don't use pow. Calculate each new term from the proceeding one.
From my time in school, updated it just enough to make it compile. Warning, it is terrible, awful code, from before the STL and dos was not quite dead yet and worse I was a total beginner...

its may not be useful but it computes E to 30 decimal places. If you wanted to add a routine to multiply it up for powers... go for it. Maybe something in it will inspire you, or make you want to run the other way and never look back...
anyway, it still works, for better or worse.

and yes, apparently, way back then, "unsigned long double" was something that worked.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

#include<cmath>
#include<iostream>
#include<cstdio>
using namespace std;

unsigned char sums[35][35]; //save the 1/facts here.

void oneovrfact(uint64_t den, char dx, unsigned char shift)
{
	//create BIG 1/fact by long division and shifting
	
	uint64_t num = 1; 
	uint64_t carry;
	int lc;	
	
	if(den) //divide by 0??? then 0 out for add later.
		for(lc = 0; lc < 35; lc ++)
		{
			
			if(shift)
			{ //we can make bigger n! by divide by 10 and
				//shift.  it will start to approximate as soon as
				//fact%10^c != 0...
				
				shift --;
				sums[lc][dx] = 0;
				
			}
			else
			{
				
				sums[lc][dx] = (unsigned char)((num/den)%10);
				carry = num%den;
				
				num = carry * 10;
				
				if(num < 0) //fix num too big, another shifter
				{
					num = carry; //restore good value
					den /= 10;  //sigh, more approx here 
					
				}
				
			}
		}
		else			
			for(lc = 0; lc < 35; lc ++)
			{
				sums[lc][dx] = 0;
				//zero out den == 0 case
			}		
			
}

void addtofirst(int dx)
{ //add the saved numbers up into the first number.
	//simple carry adder from first grade...
	int lc; 
	int carry;
	int tmp;
	for(lc = 34; lc > -1; lc--) //start on right ends
	{
		carry = 0;
		
		tmp = sums[lc][2] + sums[lc][dx];
		if(tmp > 9)
		{
			tmp -= 10;
			carry++;
		}
		
	       sums[lc][2] = tmp;
		   if(lc) //else memory foo!
			   sums[lc-1][2] += carry;
		   
		   
		   
	}	
}


int main()
{
    uint64_t fact = 2;
	//unsigned long double fact = .5;
	 double e{2.0};
    int lc,lc2;
		
    unsigned char s;
	
	s = 0;
	
	for(lc = 2; lc < 35; lc++,fact*= lc)		
	{
		e+= (double) (1.0/fact);
		
		
		if(lc > 15) //facts getting bigger, start approx.
		{
			fact /= 10;
			s ++;
		}
		oneovrfact(fact, lc, s);
		
    }
	
	
   	for(lc = 3; lc < 35; lc++) //add them up
		addtofirst(lc);
	
	
	
	cout << "2."; //fudge the 2. back in
	for(lc = 2; lc < 3; lc++) //print e
	{		
		for(lc2= 1; lc2<31; lc2++) //digits beyond this are not right. 
		{
			cout << (int)(sums[lc2][lc]%10);
		}
		cout << endl;
    }
}



/*  
	output:
	2.0+
	0.718281828459045235360287471352 8031
	                               
	  actual e:
	  ... 471352 6624977572		
		  
			
*/
Last edited on
Problem solved. Thank you @lastchance @seeplus @jonnin
Topic archived. No new replies allowed.