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. =)

3
Contributors
5
Replies
8
Views
6 Years
Discussion Span
Last Post by paperstars

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 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 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 by firstPerson: n/a

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

Edited by paperstars: n/a

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.