Wrong logic in approximating e^1 :( [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I've written code using class object to calculate the value of e^1 by approximation using the summation of series given below, but seems like i can't get the logic to work properly.I tried running it to 5 terms for approximation but my answer was 1.2 only where it should be around 2.7038...
e^1 is given by the series 1 + 1/1! + 1/2! + 1/3! ...
#include <iostream>
#include <stdlib.h>
using namespace std;
class factorial
{
public:
double loopfactorial ( double y)
{
double value;
for (int a=0; a<=y; a++)
{
value=1;
value = value*a;
}
return value;
}
};
int main()
{
factorial calcu;
int x;
double sum;
cout<<"Enter the number of terms to approximate exponent:"<<endl;
cin>>x;
for (int y=1; y<=x-1; y++)
{
int n = calcu.loopfactorial(y);
sum=1.0;
sum = sum + 1/n;
}
cout<<"The value of e is "<<sum<<endl;
return 0;
}

For reference and the benefit of future readers, here's the "correct" code:
#include <iostream>
#include <cstdlib>
int main()
{
unsigned int terms;
if (!(std::cout << "Number of terms: " && std::cin >> terms))
{
std::cout << "Error, I did not understand you.\n";
return EXIT_FAILURE;
}
double e = terms > 0 ? 1.0 : 0.0, term = 1.0;
for (unsigned int n = 1; n < terms; ++n)
{
term /= n;
e += term; // this is "e += 1/n!"
}
std::cout << "e is approximately " << e << "\n";
}
(The code can be trivially extended to compute ex for any x.)

You should move the variable initializations out of the loops - you're resetting them over and over.
Side note: it's rather pointless to put loopfactorial in a class.

I found three problems with your code, both are similar to each other
1. in loopfactorial(), value=1 should be defined before the loop body
2. in main(), sum=1.0 should be defined before the loop body
3. in loopfactorial(), loop variable a should have been initialized with either 1 or 2 instead of 0.

Try moving your initial values outside the loop:
#include <iostream>
#include <stdlib.h>
using namespace std;
class factorial
{
public:
double loopfactorial ( double y)
{
double value;
// MOVED INITIAL VALUE HERE
value=1;
for (int a=1; a<=y; a++)
{
value = value*a;
}
return value;
}
};
int main()
{
factorial calcu;
int x;
double sum;
cout<<"Enter the number of terms to approximate exponent:"<<endl;
cin>>x;
// MOVED INITIAL VALUE HERE
sum=1.0;
for (int y=1; y<=x-1; y++)
{
int n = calcu.loopfactorial(y);
sum = sum + 1/n;
}
cout<<"The value of e is "<<sum<<endl;
return 0;
}

Related

C++ function to approximate sine using taylor series expansion

Hi I am trying to calculate the results of the Taylor series expansion for sine to the specified number of terms.
I am running into some problems
Your task is to implement makeSineToOrder(k)
This is templated by the type of values used in the calculation.
It must yield a function that takes a value of the specified type and
returns the sine of that value (in the specified type again)
double factorial(double long order){
#include <iostream>
#include <iomanip>
#include <cmath>
double fact = 1;
for(int i = 1; i <= num; i++){
fact *= i;
}
return fact;
}
void makeSineToOrder(long double order,long double precision = 15){
double value = 0;
for(int n = 0; n < precision; n++){
value += pow(-1.0, n) * pow(num, 2*n+1) / factorial(2*n + 1);
}
return value;
int main()
{
using namespace std;
long double pi = 3.14159265358979323846264338327950288419716939937510L;
for(int order = 1;order < 20; order++) {
auto sine = makeSineToOrder<long double>(order);
cout << "order(" << order << ") -> sine(pi) = " << setprecision(15) << sine(pi) << endl;
}
return 0;
}
I tried debugging
here is a version that at least compiles and gives some output
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
double factorial(double long num) {
double fact = 1;
for (int i = 1; i <= num; i++) {
fact *= i;
}
return fact;
}
double makeSineToOrder(double num, double precision = 15) {
double value = 0;
for (int n = 0; n < precision; n++) {
value += pow(-1.0, n) * pow(num, 2 * n + 1) / factorial(2 * n + 1);
}
return value;
}
int main(){
long double pi = 3.14159265358979323846264338327950288419716939937510L;
for (int order = 1; order < 20; order++) {
auto sine = makeSineToOrder(order);
cout << "order(" << order << ") -> sine(pi) = " << setprecision(15) << sine << endl;
}
return 0;
}
not sure what that odd sine(pi) was supposed to be doing
Apart the obvious syntax errors (the includes should be before your factorial header) in your code:
I see no templates in your code which your assignment clearly states to use
so I would expect template like:
<class T> T mysin(T x,int n=15){ ... }
using pow for generic datatype is not safe
because inbuild pow will use float or double instead of your generic type so you might expect rounding/casting problems or even unresolved function in case of incompatible type.
To remedy that you can rewrite the code to not use pow as its just consequent multiplication in loop so why computing pow again and again?
using factorial function is waste
you can compute it similar to pow in the same loop no need to compute the already computed multiplications again and again. Also not using template for your factorial makes the same problems as using pow
so putting all together using this formula:
along with templates and exchanging pow,factorial functions with consequent iteration I got this:
template <class T> T mysin(T x,int n=15)
{
int i;
T y=0; // result
T x2=x*x; // x^2
T xi=x; // x^i
T ii=1; // i!
if (n>0) for(i=1;;)
{
y+=xi/ii; xi*=x2; i++; ii*=i; i++; ii*=i; n--; if (!n) break;
y-=xi/ii; xi*=x2; i++; ii*=i; i++; ii*=i; n--; if (!n) break;
}
return y;
}
so factorial ii is multiplied by i+1 and i+2 every iteration and power xi is multiplied by x^2 every iteration ... the sign change is hard coded so for loop does 2 iterations per one run (that is the reason for the break;)
As you can see this does not use anything funny so you do not need any includes for this not even math ...
You might want to add x=fmod(x,6.283185307179586476925286766559) at the start of mysin in order to use more than just first period however in that case you have to ensure fmod implementation uses T or compatible type to it ... Also the 2*pi constant should be in target precision or higher
beware too big n will overflow both int and generic type T (so you might want to limit n based on used type somehow or just use it wisely).
Also note on 32bit floats you can not get better than 5 decimal places no matter what n is with this kind of computation.
Btw. there are faster and more accurate methods of computing goniometrics like Chebyshev and CORDIC

Testing program for convergence?

So, I'm pretty inexperienced with calculus, and in C++, so please bear with me if I'm misunderstanding this completely. I'm supposed to be testing this Taylor series program for convergence, which I'm told is when the output value does no change. However, the way mine is written out, it seems impossible as I'm iterating through for loops while implementing it. After around 12 it's no longer accurate to the library sin(); but I'm not sure if that's the same thing because it doesn't seem to be. Advice on what I'm looking for would be grand, I really appreciate it. Apologies again if this question is stupid!
Here is my code:
#include <iostream>
#include<cmath>
using namespace std;
double getFactorial (double num)
{
long double factorial = 1.0;
for (int i = 1; i <= num; ++i)
{
factorial *= i; //iterates from 1 to num value, multiplying by each number
}
return factorial;
}
double taylorSin(double num){
double value=0;
for(int i=0;i<20;i++){
value+=pow(-1.0,i)*pow(num,2*i+1)/getFactorial(2*i+1);
}
return value;
}
int main ()
{ cout<<getFactorial(6);
for(double i=1;i<=12;i++){
//loops through given amount of values to test function
double series=i; //assign double type variable with value of i
//cout<<"Taylor function result is "<<taylorSin(series)<<endl;
//cout<<"Library sin result is "<<sin(series)<<endl;
}
return 0;
}
Based on your answer, I wrote a taylor summing program:
#include <iostream>
#include <cmath>
#include <limits>
#include <concepts>
template<typename F>
concept my_lambda = requires(F f, unsigned long long int x) {
{ f(x) } -> std::same_as<long double>;
};
template<my_lambda ftn>
long double Taylor_sum(ftn term) noexcept {
using namespace std;
long double value = 0, prev = 0;
unsigned long long int i = 0;
try {
do {
if (i == numeric_limits<unsigned long long>::max() || !isfinite(prev)) return numeric_limits<long double>::quiet_NaN();
prev = value;
value += term(i++);
} while (prev != value);
return value;
}
catch (...) { return numeric_limits<long double>::quiet_NaN(); }
};
int main() {
using namespace std; long double x; cin >> x ;
long double series_sum = Taylor_sum([x](unsigned long long int i) -> long double { return /*Your implementation here*/; });
if (!isfinite(series_sum)) cout << "Series does not converge!" << endl;
else {
cout << "Series converged, its value is : " << series_sum << endl;
cout << "Compared to sin : " << sinl(x) << endl;
}
return 0;
}
Although comparing term before & after summing is not much rigorous way to check convergence, but this approach is usual approach in practice.
Note: When I used this function for large x, it differed from the std::sin() and diverged when x is large enough. This is because the floating-point arithmetic has limited precision (std::sin() is more accurate because it takes the periodic nature of the original sine function)

hostel visit question (priority queue application )

question: Dean of MAIT is going to visit Hostels of MAIT. As you know that he is a very busy person so he decided to visit only the first "K" nearest Hostels. Hostels are situated on a 2D plane. You are given the coordinates of hostels and you have to answer the Rocket distance of Kth nearest hostel from the origin ( Dean's place )
Input Format
The first line of input contains Q Total no. of queries and K There are two types of queries:
first type: 1 x y For query of 1st type, you came to know about the coordinates ( x, y ) of the newly constructed hostel. second type: 2 For query of 2nd type, you have to output the Rocket distance of Kth nearest hostel till now.
//The Dean will always stay at his place ( origin ). It is guaranteed that there will be at least k queries of type 1 before the first query of type 2.
Rocket distance between two points ( x2 , y2 ) and ( x1 , y1 ) is defined as (x2 - x1)2 + (y2 - y1)2
Constraints
1 < = k < = Q < = 10^5 -10^6 < = x , y < = 10^6
Output Format
For each query of type 2 output the Rocket distance of Kth nearest hostel from Origin.//
This is my code:
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
class roomno
{
public:
int x;
int y;
roomno(int x,int y)
{
this->x=x;
this->y=y;
}
void print()
{
cout<<"location"<<"("<<x<<","<<y<<")"<<endl;
}
int distance ()
{
return (x*x+y*y);
}
};
class roomcompare
{
public:
bool operator() (roomno r1,roomno r2)
{
return r1.distance()>r2.distance();
}
};
int main()
{
int x[1000]},y[1000];
int l,k=0;
priority_queue<roomno,vector<roomno>,roomcompare> pq;
int n,i,j;
cin>>n>>l;
//cin>>n;
cin.ignore();
for( i=0;i<n;i++)
{
cin>>x[i];
}
cin.ignore();
for( j=0;j<n;j++)
{
cin>>y[j];
}
cin.ignore();
for(i=0;i<n;i++ )
{
roomno r1(x[i],y[i]);
pq.push(r1);
}
while(!pq.empty()&&k!=l)
{ k++;
roomno r2=pq.top();
r2.print();
pq.pop();
}
return 0;
}
Original link to code: https://codeshare.io/2j1bkA
What's wrong with my code?
Please consider adding what problem you are facing in your post. I've seen your code but I couldn't help with your code as I even saw a syntax error in your code and didn't know if it was the problem.
If I didn't misunderstand your question, std::set will fit better than priority queue as it is not possible to remove the largest item in a priority queue(min heap). The following code should work:
#include <iostream>
#include <set>
using namespace std;
using ll = long long;
multiset<ll> distances;
int main() {
ll n, k;
cin >> n >> k;
for(ll i = 0; i < n; ++i) {
ll query;
cin >> query;
if (query == 1) {
ll x, y;
cin >> x >> y;
distances.insert(x * x + y * y);
if (distances.size() > k) {
distances.erase(--distances.end());
}
} else {
cout << *distances.rbegin() << '\n';
}
}
return 0;
}

C++: about precision of calculating (code is inside)

Can you give me advice about precision of computing Taylor series for an exponent? We have a degree of exponent and a figure of precision calculating as imput data. We should recieve a calculating number with a given precision as output data. I wrote a program, but when I calculate an answer and compare it with embedded function's answer, it has differents. Can you advice me, how I can destroy a difference between answeres? formula of exponent's calculating
#include "stdafx.h"
#include "iostream"
#include <math.h>
#include <Windows.h>
#include <stdlib.h>
using namespace std;
int Factorial(int n);
double Taylor(double x, int q);
int main()
{
double res = 0;
int q = 0;
double number = 0;
cout << "Enter positive number" << "\n";
cin >> number;
cout << "Enter rounding error (precision)" << "\n";
cin >> q;
cout << "\n" << "\n";
res = Taylor(number, q);
cout << "Answer by Taylor : " << res;
cout << "Answer by embedded function: " << exp(number);
Sleep(25000);
return 0;
}
int Factorial(int n) {
int res = 1;
int i = 2;
if (n == 1 || n == 0)
return 1;
else
{
while (i <= n)
{
res *= i;
i++;
}
return res;
}
}
double Taylor(double x, int q) {
double res = 1;
double res1 = 0;
int i =1;
while (i)
{
res += (pow(x, i) / Factorial(i));
if (int(res*pow(10, q)) < (res*pow(10, q)))
{//rounding res below
if ( ( int (res * pow(10,q+1)) - int(res*pow(10, q))) <5 )
res1 = (int(res*pow(10, q))) * pow(10, (-q));
else
res1 = (int(res*pow(10, q))) * pow(10, (-q)) + pow(10,-q);
return res1;
}
i++;
}
}
There are two problems in your code. First, the factorial is very prone to overflow. Actually I dont know when overflow occurs for int factorials, but I remember that eg on usual pocket calculators x! overflows already for x==70. You probably dont need that high factorials, but still it is better to avoid that problem right from the start. If you look at the correction that needs to be added in each step: x^i / i! (maths notation) then you notice that this value is actually much smaller than x^i or i! respectively. Also you can calculate the value easily from the previous one by simply multiplying it by x/i.
Second, I dont understand your calculations for the precision. Maybe it is correct, but to be honest for me it looks too complicated to even try to understand it ;).
Here is how you can get the correct value:
#include <iostream>
#include <cmath>
struct taylor_result {
int iterations;
double value;
taylor_result() : iterations(0),value(0) {}
};
taylor_result taylor(double x,double eps = 1e-8){
taylor_result res;
double accu = 1; // calculate only the correction
// but not its individual terms
while(accu > eps){
res.value += accu;
res.iterations++;
accu *= (x / (res.iterations));
}
return res;
}
int main() {
std::cout << taylor(3.0).value << "\n";
std::cout << exp(3.0) << "\n";
}
Note that I used a struct to return the result, as you should pay attention to the number of iterations needed.
PS: see here for a modified code that lets you use a already calculated result to continue the series for better precision. Imho a nice solution should also provide a way to set a limit for the number of iterations, but this I leave for you to implement ;)

c++ double type and integer type [duplicate]

This question already has answers here:
Why does division result in zero instead of a decimal?
(5 answers)
Closed 7 years ago.
I want to calculate the result of this formula:
1/1! + 1/2! + 1/3! + 1/4! + ... + 1/10!
Here is my code:
#include <iostream>
#include <cstdlib>
using namespace std;
double func(int );
int main(void) {
int a;
double sum=0;
do{
cout << "input a num: " ;
cin >> a;
}while (a<=0);
for (int i=1; i<a+1; i++) {
sum = sum + (double)(1/func(i));
}
cout << sum << endl;
return 0;
}
double func(int num)
{
if(num>0)
return num*func(num-1);
else
return 1;
}
I am curious about why I have to use double type for func to pass back.
If I used int type to pass, like this
int func(int num)
The result of sum will be not correct.
That would work. Infact, you don't need the typecast (double)(1/func(i))
Change the line as follows:
sum = sum + (1.0/func(i));