Jun 14, 2021 at 4:35pm UTC
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 Jun 14, 2021 at 4:35pm UTC
Jun 14, 2021 at 4:39pm UTC
In additon to what lastchance said - also don't use pow. Calculate each new term from the proceeding one.
Jun 14, 2021 at 5:06pm UTC
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 Jun 14, 2021 at 5:15pm UTC
Jun 14, 2021 at 6:40pm UTC
Problem solved. Thank you @lastchance @seeplus @jonnin