Hi,

I'm new to C++, I'm trying to write a program to compute the sine series for taylor expansion. I've written two codes, but both do not work after a certain point.

(The sine series is: sin x = x - (x^3/3!) + (x^5/5)...etc.)

With the code below, when x=1.5, n=3, I do not get the expected value of .9375, instead I get .375. I think the problem is in the if/else statement.

double sineSeries(double x, int n){
	double xPower = 0.0;
	double factorial = 1.0;
	double sineComputed = 0.0;
	bool sign = true;

	for (int i=1; i<=n; i+=2){
		xPower = pow(x,i);
		factorial *= i;

		if (sign) {
			sineComputed += xPower/factorial;
		}
		else {
			sineComputed -= xPower/factorial;
		}
		sign = !sign;
	}

	return sineComputed;
}

I also tried starting with i=3. Here, I have a problem when x=1.5, n=5; I get 1.25391 instead of 1.00078. Again, I think the problem is in the if/else statement, but I'm not sure where.

double sineSeries(double x, int n){
	double xPower = 0.0;
	double factorial = 3.0;
	double sineComputed = x;
	bool sign = true;

	for (int i=3; i<=n; i+=2){
		xPower = pow(x,i);
		factorial *= (i-1);

		if (sign) {
			sineComputed -= xPower/factorial;
		}
		else {
			sineComputed += xPower/factorial;
		}
		sign = !sign;
	}

	return sineComputed;
}

I prefer the first version of the code actually, so I'd like more advice on how to fix that one up. I could probably fix the second one by myself. =)
Thanks in advance.

Your factorial is wrong. Since you are updating by 2, you are missing terms in your factorial.

Separate the factorial into its own function. Or do this:

double sineSeries(double x, int n){
	double xPower = 0.0;
	double factorial = 1.0;
	double sineComputed = 0.0;
	bool sign = true;

	for (int i=1; i<=n; i+=2,factorial *= (i-1) * i){
		xPower = pow(x,i);

		if (sign) {
			sineComputed += xPower/factorial;
		}
		else {
			sineComputed -= xPower/factorial;
		}
		sign = !sign;
	}

	return sineComputed;
}

Edited 5 Years Ago by firstPerson: n/a

Hi firstPerson,
This still doesn't work, when I try n=3, I get an answer of 120, instead of 3!. I'm a little confused, because it's i-1, and factorial=1, wouldn't that always give me a value of 0?

EDIT: Nevermind, when I try the whole function it works. But why when I try to only return the factorial, I get the above answers? Also I've tried figuring out why (i-1)*i works (and doesn't make the entire factorial=0), but I'm still not sure why either. Any insight would be very much appreciated. =)

Edited 5 Years Ago by paperstars: n/a

factorial *= (i-1) * i would make the entire factorial zero (or very close to zero) when i == 1.
One way out of this is to start with i == 3.

In each term of the expansion, the numerator can be computed by multiplying the previous term by x*x.
That is, x^9 == x^7 * x*x. This could be more efficient than calling std::pow() every time.

If you want to avoid the if statement, use an int variable to hold the sign: +1 if positive and -1 if negative.

You might also want to check that x does not exceed 2 * PI (the sweep of the angle across a full circle).

// ...
    double xPower = x ;
    double factorial = 1 ;
    double sineComputed = x ;
    int sign = 1 ;

    for( int i=3; i<=n; i+=2 )
    {
        sign = -sign ;
        xPower *=  x*x ;
        factorial *= i * (i-1);
        sineComputed += xPower/factorial * sign ;
    }
// ...

factorial *= (i-1) * i would make the entire factorial zero (or very close to zero) when i == 1.
One way out of this is to start with i == 3.

No because i gets incremented before factorial is computed as a result of the comma operator which declares a sequence point. Thus that for loop is correct.

@OP: also change the type of factorial from double to unsigned int or something similar.

Edited 5 Years Ago by firstPerson: n/a

Thank you, vijayan121 and firstPerson. I understand how the code works now.

Edited 5 Years Ago by paperstars: n/a

This article has been dead for over six months. Start a new discussion instead.