series computing using loops

Pages: 12
Hey guys
can someone please explain me how I can do this C++ program. I dont need a code I just want someone to explain me how is the working for this question and how to do it.I am at basic level of programming.
The ques is :-
Consider the following series:
y=x-x^3/3!+x^5/5!-x^7/7!+x^9/9!

Write a program that prompts the user to enter x (any integer value) and n (an odd positive integer
from 1 to 9) then the program computes and prints y using the series and the computation should use
all terms in the series up through the term involving x^n.For example, if the n is 5 then the program will only compute y=x-x^3/3!+x^5/5!.
Hint: The first term x can be represented as x^1/1!.

p.s I have no background of programming so step by step explanations are a blessing for me.


Thank you
Use cout to prompt the user for x and n
Use cin to input x and n

Call a function that takes these parameters x and n and returns the sum of the series as a double.

Let's suppose the function is called mySine. Its declaration might look like
double mySine( double x, int n );

In that function:
> Set term equal to x
> Set sum equal to term

You can then do a series of loops.
First loop, multiply term by (-x*x)/(2*3) and add to sum.
Second loop, multiply term by (-x*x)/(4*5) and add to sum.
Third loop, multiply term by (-x*x)/(6*7) and add to sum.
etc.
Spot a pattern?

You will have to do these loops until the last factor in the denominator equals n - think how you will control that looping. Loops are covered in
http://www.cplusplus.com/doc/tutorial/control/
and a simple for loop or while loop would be fine here.

When you've finished looping, return sum as the return value of the function.

hey
Thank you for the reply but the problem is that I haven't use functions in my classes yet and just loops and if else statements so what can i use instead of functions can I use cmath instead but if i use cmath how do i put up the equation.
Also "!" the not operator if i add it it gives me a build error.
and i have two more doubts in the loop how many times should it run and

First loop, multiply term by (-x*x)/(2*3) and add to sum.//why do we use (2*3)
Second loop, multiply term by (-x*x)/(4*5) and add to sum.
Third loop, multiply term by (-x*x)/(6*7) and add to sum.

is it like i multiply the odd num with its previous even num
eg : (-x/x)/(8*9) add to sum??
If you don't want to use functions then you can do the summation in main().

There is no factorial operator ! in c++, nor was there any in my post: please read it carefully.

If you look carefully at the individual terms then you will see that each can be formed from the previous one by the factors that I wrote out. This avoids unnecessary computation and prevents overflow when factorials become large.

I think you should understand the maths before you start coding.
y = x^1/1! - x^3/3! + x^5/5! - x^7/7! + x^9/9!

There is no need for functions. Just one loop. Each iteration of the loop should add one term.

"What is in a term?" is not a programming language question. It is a math question.
Lets take two consecutive terms. Instead of numbers, we'll use 'a' and 'b':
x^a/a! x^b/b!
What is a! It is a product of a serie: 1*2*3*4*5*6*..*a

We do know that b = a+2.
Therefore, b! = a! * (a+1) * (a+2), is it not?

Math says: x^(h+k) = x^h * x^k
Therefore, x^b = x^(a+2) = x^a * x^2 = x^a * x * x

Last, the sign of each term is opposite of the previous term.

Lets rewrite the x^b/b!:
x^b/b! = -1 * (x^a * x * x) / ( a! * (a+1) * (a+2))
       = x^a/a!  *  (-1) * (x * x) / ((a+1) * (a+2))

Do you see how we can compute the next term x^b/b! from the previous term x^a/a!, if we know the value of a?

The first term x^1/1! is simply x and its a==1.
Therefore, the next term should be x * (-1) * (x * x) / ((1+1) * (1+2))
which simplifies to -(x*x*x)/(2*3) = -x^3/6 = -x^3/3!

Math is fun.
Yes, @Keskiverto's statement is more accurate: one loop, multiple iterations or passes of that loop.

The key thing is that you don't calculate each new term from scratch, you just multiply the previous one by whatever is necessary



In pseudocode:

> request values for x and n (x should be double, n should be an int)
> input those values

> declare and initialise term as x
> declare and initialise sum as term

> loop ( counter a initialised to 1; loop whilst a < n; increment a by 2 )
      > multiply term by -x*x/( (a +1 ) * ( a + 2 ) )          // multiplies old value of term to get new one
      > add term to sum
> end of loop

> output your sum



If you post some effort at code we can look at it.

There are alternative, equivalent ways of looping, writing the update factors etc. Those are up to you.

Last edited on
first of all thank you guys so much for taking time to explain everything its really is a blessing at the moment

second i dont have a background in maths or in computer languages but my university thought its a good idea to keep these courses so i am struck with programming

and yes i will post my code to show if i am working correctly or not since i had exams i couldnt work on the coding.
hey guys
This is my code for the above program it isnt close to the solution doesnt gives me error but not giving the correct answer aswell

include <iostream>
using namespace std;
int main ()
{
int x, n, ans=1, value=1, counter, y=2;
double sum;

cout<<"Enter the value of x : ";
cin>>x;
cout<<"Enter the value of n : ";
cin>>n;

for (counter=1; counter<n; counter++)
{
ans = x;
value = y;
sum+=(double)(ans)/y;

}

cout<<"the sum is " <<sum<<endl;
return 0;
}
Last edited on
Q: What is the value of 'sum' before the loop?
A: Unknown; the variable was not initialized with known value.

Q: How much is unknown+0.5 ?
A: Unknown.

=> Initialize the 'sum'. Probably with 0.0.


Q: How many times does the loop repeat?
A: n-1 times.

The y does not change within loop. It is 2 every time.
The x does not change within loop and 'ans' is always equal to x.

Therefore, the current loop does same as:
sum += (n-1) * x / 2.0;

Look again at lastchance's pseudocode.
Hello @sairaashraf17,
I'm struggling to relate your code to the series sum in your assignment, but here goes.

You input x and n OK, but I would think it reasonable that x should be a double, not an int.

You add to sum ... but you are adding to something you never initialised. It needs to have a value set before your loop.

I can't identify any variable that I would call the term in the sum - I'm not sure what your variable value is doing.

Both @Keskiverto and I tried to show you how to get one term from the previous one:
       multiply term by -x*x/( (a +1 ) * ( a + 2 ) )

where a is a counting variable.

It is also suggested that you increment a by 2 each loop, whereas you are just incrementing your counter by 1 and the term doesn't seem to depend on it.

Make sure that you can understand the maths in the problem, and then see if you can change your code to reflect it.
a quick warning as you are new to it:
^ is NOT power in c++.
pow(base, exponent) is power in c++.

your code will look like

sum+= pow(x, loopvariable)/factorial[loopvariable];

where factorial is just a constant array. (And you may be able to avoid explicit factorials here, which is also fine).

unsigned long long factorial[] = {1,1,2,6,24,120,... fill in what you need... };

you can handle the alternating signs various ways...
pow(-1, something) //sign flips .. 0 is 1, 1 is -1, 2 is 1, 3 is -1, ... etc
or
char sign = -1;
...
loop //this is probably preferred since your loopvariable may be 1,3,5,7,... making the pow method not so useful

sign *= -1;

to name a couple of ways.

Last edited on
Guys I wrote the code all over again still not getting the correct output

[code][#include <iostream>
using namespace std;
int main()
{
double x, sum=0.0, term;
int n, i;

cout<<"Enter the value of x";
cin>>x;
cout<<"Enter the value of n";
cin>>n;

if(n % 2 != 0 && n % 2 > 0) //work for odd numbers only
{
for ( i=1; i<n; i++)
sum=term;
term*-x*x/ (( i+1 ) * ( i + 2 ) ) ;
sum += (n-1) * x / 2.0;

i++;

}

cout<<"Sum = "<< sum <<endl;
cout<<"Term = "<< term <<endl;

return 0;
}
]
It's getting closer.

Have another look at the pseudocode. You need
1
2
term = x;
sum = term;

before looping starts. In particular, move the sum=term; statement out of the loop.

Your change to term is nearly right. You can start this
term *= ...
instead.

Then your sum increment can be
sum += term;
and not what you have at present.

Your incrementing of i is a little dangerous. You have i++ both inside the loop and as part of the for() statement. Better just to do the single increment i+=2 within the for() statement.

You only need to output sum at the end, not the last term.

You only need one of those tests for n being odd - they will give you the same result.
Last edited on
did the changes still not required output

[#include <iostream>
using namespace std;
int main()
{
double x, sum=0.0, term;
int n, i;

cout<<"Enter the value of x";
cin>>x;
cout<<"Enter the value of n";
cin>>n;

sum=term;

if(n % 2 != 0 && n % 2 > 0) //work for odd numbers only

{
for ( i=1; i<n; i+=2)

term*=-x*x/ (( i+1 ) * ( i + 2 ) ) ;
sum += term;



}

cout<<"Term = "<< term <<endl;

return 0;
}
][/code]
@sairaashraf17,
You are almost there, but you didn't make all the changes.

PLEASE COULD YOU PUT CODE TAGS IN THE RIGHT PLACES - HAVE A LOOK AT YOUR POSTS.

(1) term=x; before your sum=term; line.

(2) You don't have curly braces around the two lines of your for() loop. Put { before
term *= ...
and } after
sum += term;

(3) You should be outputting sum, not term, at the end.


Also, you still only need one of those conditions for n to be odd - just choose one of them and delete the other.
Last edited on
At a guess...

In a reply, lastchance overlooked that every other term is subtracted. All the replies afterward seemed to echo that initial error. You aren't getting the required output because you're just adding them.


Multiply by ((i/4)*4-i+2) to add the required sign change by using the fact that int rounds to integer. Or use if statements. Either way.
In a reply, lastchance overlooked that every other term is subtracted.

No. That has been take care of in there.
@zaphraud,
Please have a careful look at that minus sign in the line where term is multiplicatively updated - that is where the alternating signs come in. Please don't confuse the OP: he/she is almost there.

If @sairaashraf makes the three changes that I have suggested then the series will be correct. Check by choosing a moderately small value of x and moderately large value of n and comparing the sum with sin(x).
Last edited on
Giving the program invalid input doesn't give a zero result for term. So I changed the statement to initialize the variables.
changing
double x, sum=0.0, term;
to
double x, sum=0.0, term=0;

...Now it'll ALWAYS give a zero result.

I fixed the for loop as already mentioned and added a line inside it:
cout << "In loop for " << i << " term is " << term << " and sum is " << sum << ". \n";

that reveals a problem:
Enter the value of x 3
Enter the value of n 11
In loop for 3 term is -0 and sum is 0.
In loop for 5 term is 0 and sum is 0.
In loop for 7 term is -0 and sum is 0.
In loop for 9 term is 0 and sum is 0.
In loop for 11 term is -0 and sum is 0.
Term = -0


Oh and yeah it's getting the sign after all. I see that negative zero is being expressed every other time... :-D

If initializing variables that were left uninitialized changes the output, but its still not the output you want, maybe zero was the wrong number to pick :-D

So I'll have to set them up to produce the correct initial values inside the program..


Enter the value of x 3
Enter the value of n 5
In term 3 term is -4.5 and sum is -1.5.
In term 5 term is 2.025 and sum is 0.525.
Sum = 0.525


Still, looking back at the provided statement:
term*=-x*x/ (( i+1 ) * ( i + 2 ) ) ;
I see a giant headache reading someone elses code created entirely by an desire to avoid coding a function to compute a factorial or include the math library.

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
#include <iostream>

using std::cout;
using std::cin;
int main()
        {
//always initialize with zeros.
//its a good habit, and makes code easier to read.
        double x=0, sum=0, term=0;
        int n=0, i=0;

        cout<<"Enter the value of x ";
        cin>>x;
        cout<<"Enter the value of n ";
        cin>>n;
        if(n % 2 != 0 && n % 2 > 0) //work for odd numbers only
                {
                term = x ; sum = x; //set the first term before the math to be x^1.
                for ( i=1; i<n; i+=2)
                        {
                        term*=-x*x/ (( i+1 ) * ( i + 2 ) ) ;
                        sum += term;
//                      cout << "In term " << i+2 << " term is " << term << " and sum is " << sum << ". \n";
                        }
                }
//      cout<<"Term = "<< term << endl"\n" ;
        cout<<"Sum = "<< sum << "\n" ;

        return 0;
}
...Now it'll ALWAYS give a zero result.

That's why I asked the OP to make the change:
(1) term=x; before your sum=term; line.



Still, looking back at the provided statement:
term*=-x*x/ (( i+1 ) * ( i + 2 ) ) ;
I see a giant headache reading someone else's code created entirely by an desire to avoid coding a function to compute a factorial or include the math library.

That wasn't the desire at all. It was one of efficiency and practicality. Straight multiplies are considerably more efficient than a call to std::pow(), whilst factorials grow incredibly fast, even if treated as doubles rather than ints, or evaluated from a gamma function.

As far as I'm aware it's much more efficient to generate the terms of a power series sequentially in terms of the previous one rather than generating a new one from scratch, as well as mitigating the danger of dividing one overflowing number by another.

Ah well, I'm used to seeing power-series terms defined iteratively. Maybe it's different in computer science.



The OP has done well to get this far: it would be great if he/she reaches the end.
Last edited on
Pages: 12