sum of Maclaurin series c++ - c++

I am struggling to make this equation equals to each other because of a bad understanding of mathematics.
The problem is that the equation does not equal to each other
here is my code for better understand
#include <iostream>
#include <ccomplex>
using std::cout;
int main() {
int n = 8;
double sum = 0.0;
unsigned long long fact =1;
for (int i = 1; i <= n; i++)
{
fact *= 2*i*(2*i-1);
sum += 1.0 / fact;
}
std::cout << "first equation " << sum << std::endl;
double e = M_E;
double st = 1.0/2.0*(e + (1.0/e));
std::cout <<"second equation " << st << std::endl;
return 0;
}
the output
first equation 0.543081
second equation 1.54308
The result it nearly It must be at least equal before the comma,

You don't account for n = 0, which yields 0! and thus 1. Therefore, you need to add 1 to sum.

Related

Overflow in C++

So..
Here is the code:
#include <iostream>
#include <limits>
#include <math.h>
using namespace std;
int main()
{
unsigned long long i,y,n,x=45;
unsigned long long factorial = 1;
for(n = 0; n <= 5; n++)
{
y = (pow(-1,n)*pow(x,2*n)) / factorial;
cout << "COS IS " << y << endl;
}
for(int i = 1; i <=n; i++)
{
factorial *= 2*i;
}
}
I get an overflow but I really don't know why. I use unsigned long long just to make sure that I on't get but.. I still get it. Even limited to small numbers. I tried to implement this:
https://en.wikibooks.org/wiki/Trigonometry/Power_Series_for_Cosine_and_Sine
But I really can't do it because of the overflow. Do you have any ideea on what can I do ? I am newbie in programming so, take it easy on me :D
There are many issues.
you use integer types when you should use floating point types
you use unsigned types for signed calculations
you don't use radians but degrees (45° ≈ 0.78539 radians)
you don't calculate the factorial in the loop, it is always 1, you only calculate it at the end of the loop but then it's too late, and your calculation of the factorial is wrong anyway.
the algorithm is wrong, it just doesn't do what Maclaurin's therorem says, you need to sum up the terms, but you just print the terms.
You probably want this:
#include <iostream>
#include <cmath>
using namespace std;
long factorial(int n)
{
long result = 1;
for (int i = 1; i <= n; i++)
result *= i;
return result;
}
int main()
{
double x = 0.785398163397448309616; //PI/4 expectd result COS(PI/4) = 0.7071067
double mycosinus = 0;
for (int n = 0; n <= 5; n++)
{
mycosinus += (pow(-1, n) * pow(x, 2 * n)) / factorial(2*n);
cout << "COS IS " << mycosinus << endl;
}
}
This is your wrong algorithm for calculating the factorial of 5:
int main()
{
int n = 5;
int factorial = 1;
for (int i = 1; i <= n; i++)
{
factorial *= 2 * i;
}
cout << "factorial 5 = " << factorial << endl;
}
The calculated value is 3840 instead of 120. I let you find out what's wrong yourself.
For performing this sort of maths you need to use a floating point like float or double not integral types like long, int or long long, given that sin and cos can both return negative numbers you shouldn't be using unsigned either.

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 ;)

Use a single while loop to calculate various means

I am to calculate the arithmetic mean, the geometric mean, and the harmonic mean for five numbers using a single while loop.
Here is what I have so far:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
float a;
float g;
float h;
sum1 = 0;
sum2 = 0;
sum3 = 0;
n = 5;
int k;
int main()
{
printf("Please Enter Five Integers:\n");
while (k = 0 && k < n && ++k);
{
scanf("%lf", &k);
sum1 = sum1 + k;
sum2 = sum2 * k;
sum3 = sum3 + (1.0 / k);
}
a = sum1 / n;
g = pow(sum2, 1 / n);
h = n / sum3;
printf("Arithmetic mean: %.3f\n", a);
printf("Geometric mean: %.3f\n", g);
printf("Harmonic mean: %.3f\n", h);
return 0;
Your C program has several issues.
You don't declare all the variables you are using, for example, and there's no need for them to be global.
Your initial value for sum2 (0) is wrong, it will never update because you repetedly multiply k times 0.
Then in pow(..., 1 / n) the 1/n is an integer division, so you are elevating to 0.
Your loop and its condition must be modified. Try this, I used double, instead of integers and float, but it depends on your assignment:
#include <stdio.h>
#include <math.h>
#define MAX 80
int main()
{
double a, g, h, k;
double sum = 0, prod = 1, sum_inv = 0;
const int n = 5;
int i = 0;
printf("Please, enter five numbers:\n");
char buffer[MAX];
while ( i < n ) {
fgets(buffer, MAX, stdin);
if ( sscanf(buffer, "%lf", &k) != 1 ) {
printf("Wrong format, floating point number expected\n");
continue;
}
if ( k == 0.0 ) {
printf("You should enter non zero numbers\n");
continue;
}
++i;
sum += k;
prod *= k;
sum_inv += (1.0 / k);
}
a = sum / n;
g = pow(prod, 1.0 / n);
h = n / sum_inv;
printf("Arithmetic mean: %.3f\n", a);
printf("Geometric mean: %.3f\n", g);
printf("Harmonic mean: %.3f\n", h);
return 0;
}
Apologies if this is brutal, but simply saying there are multiple issues and proceeding to correct them without explaining why they are issues or what was done to correct them doesn't make for a very good answer. It makes for homework cut-and-paste.
#define _CRT_SECURE_NO_WARNINGS
This is actually a bad idea. Those security warnings often tell you you're taking unnecessary risks. They are annoying, but often they are right.
#include <stdio.h>
#include <math.h>
These should be <cstdio> and <cmath>. Better still, don't use cstdio. Use the C++ equivalents.
float a;
float g;
float h;
sum1 = 0;
sum2 = 0;
sum3 = 0;
n = 5;
The preceding 4 variables do not have data types. All variables must have a type.
Further initializing sum2 to zero when it will be used to gather a product is a bad idea. 0 will result.
int k;
None of these variables need to be global and all of the variable names are non-descriptive. In a program this size, that's not horrible, but in a large program with dozens or thousands of variables, being able to read from the variable name what it does and what it contains is worth it's weight in gold.
int main()
{
printf("Please Enter Five Integers:\n");
while (k = 0 && k < n && ++k);
The ; is a bad mistake here. ; ends the instruction. It separates the loop from it's body, so you get a while the loops but does nothing else.
But let's look at the loop conditions shall we?
k = 0
this is the same as
k = 0
if (k)
Which is always false since k is 0. This exits the loop right here.
k < n
Which it always is because of k = 0. k is 0. A moot point because this never gets tested.
++k
is always true because at this point k will always be 1.
This screams read the textbook more closely because you missed quite a bit.
{
scanf("%lf", &k);
This line reads a floating point number into an integer. Not a good idea. The results will be bizarre at best.
In addition, the return code from scanf is untested so you have no way to tell whether or not scanf successfully read a value.
And this question is tagged C++. Why use C?
sum1 = sum1 + k;
sum2 = sum2 * k;
sum3 = sum3 + (1.0 / k);
That all looks good to me, other than being really bad, non-descriptive names.
}
a = sum1 / n;
Syntactically and logically sound.
g = pow(sum2, 1 / n);
1 / n will be performed entirely in integer arithmetic and certainly result in a fraction. Integers can't do fractions, so this will result in 0. Any number to the power of 0 is one.
h = n / sum3;
Looks good.
printf("Arithmetic mean: %.3f\n", a);
printf("Geometric mean: %.3f\n", g);
printf("Harmonic mean: %.3f\n", h);
Again, using C in C++. printf has it's uses, even in C++, and frankly this is one of those cases where I might use it (but with caution because there is a performance hit) because the C++ equivalent std::cout << "Arithmetic mean: " << std::fixed << std::setprecision(3) << a << '\n'; is brutally verbose.
return 0;
}
Revising this for C++
#include <cmath>
#include <iostream>
#include <iomanip>
#include <limits>
int main()
{
// discarded a, g, and h. Renamed the rest for easier reading
float sum = 0;
float product = 1;
float invSum = 0;
constexpr int MAX = 5;
int input;
std::cout <<"Please Enter Five Integers:" << std::endl;
int count = 0;
while (count < MAX)
{
if (std::cin >> input)
{ // read a good, or at least not horrible, number
// this will not handle the problem of "123abc" as input. "123" will be
// accepted and "abc" will be seen as a second token and rejected.
// proper handling of this is a question unto itself and has been asked
// hundreds of times.
sum += input;
product *= input;
invSum += (1.0 / input);
count++;
}
else
{ // clean up and ask for new input
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout <<"Bogus integer. Input again: " << std::endl;
}
}
std::cout << "Arithmetic mean: " << std::fixed << std::setprecision(3) << sum / MAX << '\n';
std::cout << "Geometric mean: " << std::fixed << std::setprecision(3) << pow(product, (1.0 / MAX)) << '\n';
std::cout << "Harmonic mean: " << std::fixed << std::setprecision(3) << MAX / invSum << '\n';
return 0;
}

finding pi - using Machin's formula. Different iterations are giving same result

I've written a few programs to find pi, this one being the most advanced. I used Machin's formula, pi/4 = 4(arc-tan(1/5)) - (arc-tan(1/239)).
The problem is that however many iterations I do, I get the same result, and I can't seem to understand why.
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
double arctan_series(int x, double y) // x is the # of iterations while y is the number
{
double pi = y;
double temp_Pi;
for (int i = 1, j = 3; i < x; i++, j += 2)
{
temp_Pi = pow(y, j) / j; //the actual value of the iteration
if (i % 2 != 0) // for every odd iteration that subtracts
{
pi -= temp_Pi;
}
else // for every even iteration that adds
{
pi += temp_Pi;
}
}
pi = pi * 4;
return pi;
}
double calculations(int x) // x is the # of iterations
{
double value_1, value_2, answer;
value_1 = arctan_series(x, 0.2);
value_2 = arctan_series(x, 1.0 / 239.0);
answer = (4 * value_1) - (value_2);
return answer;
}
int main()
{
double pi;
int iteration_num;
cout << "Enter the number of iterations: ";
cin >> iteration_num;
pi = calculations(iteration_num);
cout << "Pi has the value of: " << setprecision(100) << fixed << pi << endl;
return 0;
}
I have not been able to reproduce your issue, but here is a bit cleaned up code with a few C++11 idioms and better variable names.
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
// double arctan_series(int x, double y) // x is the # of iterations while y is the number
// then why not name the parameters accoringly? In math we usually use x for the parameter.
// prefer C++11 and the auto notation wherever possible
auto arctan_series(int iterations, double x) -> double
{
// note, that we don't need any temporaries here.
// note, that this loop will never run, when iterations = 1
// is that really what was intended?
for (int i = 1, j = 3; i < iterations; i++, j += 2)
{
// declare variables as late as possible and always initialize them
auto t = pow(x, j) / j;
// in such simple cases I prefer ?: over if-else. Your milage may vary
x += (i % 2 != 0) ? -t : t;
}
return x * 4;
}
// double calculations(int x) // x is the # of iterations
// then why not name the parameter accordingly
// BTW rename the function to what it is supposed to do
auto approximate_pi(int iterations) -> double
{
// we don't need all of these temporaries. Just write one expression.
return 4 * arctan_series(iterations, 0.2) - arctan_series(iterations, 1.0 / 239.0);
}
auto main(int, char**) -> int
{
cout << "Enter the number of iterations: ";
// in C++ you should declare variables as late as possible
// and always initialize them.
int iteration_num = 0;
cin >> iteration_num;
cout << "Pi has the value of: "
<< setprecision(100) << fixed
<< approximate_pi(iteration_num) << endl;
return 0;
}
When you remove my explanatory comments, you'll see, that the resulting code is a lot more concise, easier to read, and therefore easier to maintain.
I tried a bit:
Enter the number of iterations: 3
Pi has the value of: 3.1416210293250346197169164952356368303298950195312500000000000000000000000000000000000000000000000000
Enter the number of iterations: 2
Pi has the value of: 3.1405970293260603298790556436870247125625610351562500000000000000000000000000000000000000000000000000
Enter the number of iterations: 7
Pi has the value of: 3.1415926536235549981768144789384678006172180175781250000000000000000000000000000000000000000000000000
Enter the number of iterations: 42
Pi has the value of: 3.1415926535897940041763831686694175004959106445312500000000000000000000000000000000000000000000000000
As you see, I obviously get different results for different numbers of iterations.
That method converges very quickly. You'll get more accuracy if you start with the smallest numbers first. Since 5^23 > 2^53 (the number of bits in the mantissa of a double), probably the maximum number of iterations is 12 (13 won't make any difference). You'll get more accuracy starting with the smaller numbers. The changed lines have comments:
double arctan_series(int x, double y)
{
double pi = y;
double temp_Pi;
for (int i = 1, j = x*2-1; i < x; i++, j -= 2) // changed this line
{
temp_Pi = pow(y, j) / j;
if ((j & 2) != 0) // changed this line
{
pi -= temp_Pi;
}
else
{
pi += temp_Pi;
}
}
pi = pi * 4;
return pi;
}
For doubles, there is no point in setting precision > 18.
If you want an alternative formula that takes more iterations to converge, use pi/4 = arc-tan(1/2) + arc-tan(1/3), which will take about 24 iterations.
This is another way if some of you are interested. The loop calculates the integral of the function : sqrt(1-x²)
Which represents a semicircle of radius 1. Then we multiply by two the area. Finally we got the surface of the circle which is PI.
#include <iomanip>
#include <cmath>
#define f(x) sqrt(1-pow(x,2))
double integral(int a, int b, int p)
{
double d=pow(10, -p), s=0;
for (double x=a ; x+d<=b ; x+=d)
{
s+=f(x)+f(x+d);
}
s*=d/2.0;
return s;
}
int main()
{
cout << "PI=" << setprecision (9) << 2.0*integral(-1,1,6) << endl;
}

Problems with cout ( C++)

I am having the hardest time figuring out what is wrong here:
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
double fact(double);
double sinTaylor(double);
double cosTaylor(double);
int main()
{
double number, sineOfnumber, cosineOfnumber;
cout << "Enter a number, then I will calculate the sine and cosine of this number" << endl;
cin >> number;
sineOfnumber = sinTaylor(number);
cosineOfnumber = cosTaylor(number);
cout << fixed << endl;
cout << cosineOfnumber << endl;
cout << sineOfnumber << endl;
return 0;
}
double fact(double n)
{
double product = 1;
while(n > 1)
product *= n--;
return product;
}
double sinTaylor(double x)
{
double currentIteration, sumSine;
for(double n = 0; n < 5; n++)
{
currentIteration = pow(-1, n)*pow(x, 2*n+1) / fact(2*n+1);
sumSine += currentIteration;
}
return sumSine;
}
double cosTaylor(double y)
{
double currentIteration, sumCosine;
for(double n = 0; n < 5; n++)
{
double currentIteration = pow(-1, n)*pow(y, 2*n) / fact(2*n);
sumCosine += currentIteration;
}
return sumCosine;
}
Ok, so here's my code. I'm pretty content with it. Except for one thing:
sineOfnumber and cosOfnumber, after the calling of sinTaylor and cosTaylor, will add each other in the following cout line that will print each other.
In other words, if number is equal to lets say, .7853, 1.14 will be printed in the line that is intended to print cosineOfnumber, and sineOfnumber will print the result normally.
Can anyone help me identify why this is? Thank you so much!
Are you ever initializing the variables sumSine and sumCosine in your functions? They're not guaranteed to start at zero, so when you call += inside your loop you could be adding computed values to garbage.
Try initializing those two variables to zero and see what happens, as other than that the code seems okay.
The series for the sine is (sorry for the LaTeX):
sin(x) = \sum_{n \ge 0} \frac{x^{2 n + 1}}{(2 n + 1)!}
If you look, given term t_{2 n + 1} you can compute term t_{2 n + 3} as
t_{2 n + 3} = t_{2 n + 1} * \frac{x^2}{(2 n + 2)(2 n + 3)}
So, given a term you can compute the next one easily. If you look at the series for the cosine, it is similar. The resulting program is more efficient (no recomputing factorials) and might be more precise. When adding up floating point numbers, it is more precise to add them from smallest to largest, but I doubt that will make a difference here.