Calculating PI in java with loops
 CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com

# Thread: Calculating PI in java with loops

1. Junior Member
Join Date
Sep 2008
Posts
2

## Calculating PI in java with loops

Hello all,
I'm a first year Java student and
I need some help on a practice problem.

Code:
```Project 4-5: THe German mathematician Gottfried Leibniz developed the
following method to approximate the value of PI:
PI/4 = 1 - 1/3 + 1/5 - 1/7 + ...
Write a program that allows the user to specify the number of iterations used in this approximation and displays the resulting value.```
We need to solve this with either
"for" or "while" loops

Here is what i've got so far:
Code:
```import java.util.Scanner;

public class Proj45

{
public static void main(String[]args)
{
double input = 1;
double output = 1;

System.out.print("Enter the number of iterations:");

for(int x=1 ; x <= input ; x=x+2)
output = ((output) - ((1.0)/(x+2)));

System.out.println(output);
}
}```
I don't know how to wrap my head around this.
If any one can help me it would be greatly appreciated.
THanks!

2. Elite Member
Join Date
Jun 1999
Location
Eastern Florida
Posts
3,741

## Re: Calculating PI in java with loops

Rewrite the equation as:
y/x + y/(x+2) + y/(x+4) + y/(x+6) ...
And alternate the value of y from +1 to -1

3. _uj
Banned
Join Date
Nov 2003
Posts
1,405

## Re: Calculating PI in java with loops

Originally Posted by webyugioh
Hello all,
for(int x=1 ; x <= input ; x=x+2)
output = ((output) - ((1.0)/(x+2)));
Say you're in iteration i (the iterations are counted from 0 up to input-1). The contribution to the output in that iteration is 1/(2*i+1). In an iteration the contribution is either positive or negative depending on whether i is even or odd. You get this,

Code:
```int input = ........;
double output = 0.0;
boolean positive = true;
for (int i=0; i<input; i++) {
double contribution = 1.0/(2.0*((double)i) + 1.0);
if (positive)
output += contribution
else
output -= contribution;
positive = !positive;
}
System.out.println("Pi is ", output*4.0);```
As an alternative you can decide whether the contribution is positive or negative by checking whether i is even or odd repectively. This approach would then utilize the fact that (i%2==0) evaluates to true when i is even and to false when i is odd.

Note that in the contribution calculation care has been taken to use double throughout. This is to avoid implicit conversion surprises. Double literals have been used (1.0 instead of 1 etcetera) and the int i has been explicitly cast to double.
Last edited by _uj; September 28th, 2008 at 03:36 AM.

4. Junior Member
Join Date
Sep 2008
Posts
2

## Re: Calculating PI in java with loops

Originally Posted by _uj
Say you're in iteration i (the iterations are counted from 0 up to input-1). The contribution to the output in that iteration is 1/(2*i+1). In an iteration the contribution is either positive or negative depending on whether i is even or odd. You get this,

Code:
```int input = ........;
double output = 0.0;
boolean positive = true;
for (int i=0; i<input; i++) {
double contribution = 1.0/(2.0*((double)i) + 1.0);
if (positive)
output += contribution
else
output -= contribution;
positive = !positive;
}
System.out.println("Pi is ", output*4.0);```
As an alternative you can decide whether the contribution is positive or negative by checking whether i is even or odd repectively. This approach would then utilize the fact that (i%2==0) evaluates to true when i is even and to false when i is odd.

Note that in the contribution calculation care has been taken to use double throughout. This is to avoid implicit conversion surprises. Double literals have been used (1.0 instead of 1 etcetera) and the int i has been explicitly cast to double.
I thank you very much, it works perfectly.
If you don't mind, can you explain some things to me.
I am only a few weeks into programming so I do not understand everything you have there.

Here is the program that works perfectly:
Code:
```import java.util.Scanner;

public class cheat

{
public static void main(String[]args)
{

int input;

System.out.print("Enter the number of iterations:");
input = Reader.nextInt(); // set input as the input

double output = 0.0;
boolean positive = true; // don't know this

for (int i=0; i<input; i++) {
double sum = 1.0/(2.0*((double)i) + 1.0); //how no idea how this works
if (positive)
output += sum; //same as output = output + sum
else
output -= sum; // same as output = output = output - sum
positive = !positive; // Don't know this
}
System.out.println("Pi/4 is " + output);
}
}```
what is "boolean positive = true" do?
what does that ((double)i) do?
how does if (positive) work?
what does positive = !positive do?

I thank you very much for your help, but it seems that you are way above my head.

EDIT: I found out another way to do it from another form:
Code:
```import java.util.Scanner; // import scanner util

public class Proj45v2 // name the project

{
public static void main(String[]args)
{
Scanner Reader = new Scanner(System.in); // set up the scanner variable

int input; // this is initialized and given value by the user

System.out.print("Enter the number of iterations:");
input = Reader.nextInt(); //sets user input

double sum = 0; //sets up the sum variable

for (int i = 1; i <= input; i++) {
//i starts as the int 1 ; as long as less than or equal the input ; i = i+1 after each loop
double numToAdd = (1.0 / ((i * 2) - 1));
// put ((i * 2) - 1)) on botom so that
// *2 to makes it even and -1 to make it odd

if (i%2 > 0) // if the remander of i/2 is >0 then add the
// preivous number to the new one
else // if the remander of i/2 is not >0 then subtract the
// previous number to the new one

System.out.println("PI/4 is equal to " + sum);
}
}
}```
Last edited by webyugioh; September 28th, 2008 at 02:56 PM.

5. _uj
Banned
Join Date
Nov 2003
Posts
1,405

## Re: Calculating PI in java with loops

Originally Posted by webyugioh
I thank you very much for your help, but it seems that you are way above my head.
It's very basic Java usage.

what is "boolean positive = true" do?
how does if (positive) work?
what does positive = !positive do?
Check out the boolean primitive.

what does that ((double)i) do?
It converts an int into a double. It's called a cast.

6. Elite Member
Join Date
Jun 1999
Location
Eastern Florida
Posts
3,741

## Re: Calculating PI in java with loops

Here's another, slightly shorter way to do it:
Code:
```public class ComputePI {
public static void main(String[] args) {
double pi = 0;
double y = 1;

int lps = 90000000*2;
int cnt = 0;

for(int x=1; x < lps; x+=2) {
//         System.out.println("x=" + x + ", y=" + y + "  y/x=" + (y/x) + ", pi=" + pi);
pi = pi + (y/x);
y = -y;    // alternate the sign each time
cnt++;
}
System.out.println("PI=" + 4*pi + " after " + cnt); //PI=3.141592642478473 after 90000000
}
}```

7. Member +
Join Date
Feb 2008
Posts
966

## Re: Calculating PI in java with loops

There is a MUCH better way to alternate signs for Taylor series. All you simply need to do is raise -1 to the Ith power:

Math.pow(-1,i)

double sum = 1.0;
for(int i = 1; i < input; ++i)
sum += Math.pow(-1,i)*1.0/(2.0*((double)i) + 1.0);

And use that in the actual equation. Inside of the loop should be one line of code.

8. Elite Member
Join Date
Jun 1999
Location
Eastern Florida
Posts
3,741

## Re: Calculating PI in java with loops

What do you think the cost of Math.pow() is vs y = -y?
I'd code an extra line of code for the expense.

9. _uj
Banned
Join Date
Nov 2003
Posts
1,405

## Re: Calculating PI in java with loops

Originally Posted by Norm
What do you think the cost of Math.pow() is vs y = -y?
I'd code an extra line of code for the expense.
I agree. Using Math.pow like that is something only a newbie would do.

If speed is important I have a suggestion to your solution,

Code:
```double pi=0;
for(int x=1; x < lps; x+=4) pi += 1.0/(double)x;
for(int x=3; x < lps; x+=4) pi -= 1.0/(double)x;```
You first add up all positive contributions in one loop, then you subtract all negative contributions in another. The total number of iterations is the same as before but there's no need anymore to keep track of an alternating sign while looping.
Last edited by _uj; September 30th, 2008 at 10:58 AM.

10. Member +
Join Date
Feb 2008
Posts
966

## Re: Calculating PI in java with loops

Originally Posted by _uj
I agree. Using Math.pow like that is something only a newbie would do.
_uj, you're an ***, no wonder you and dlorde are always butting heads. Lets look at YOUR "noob" solution:

Code:
```int input = ........;
double output = 0.0;
boolean positive = true;
for (int i=0; i<input; i++) {
double contribution = 1.0/(2.0*((double)i) + 1.0);
if (positive)
output += contribution
else
output -= contribution;
positive = !positive;
}```
Oh yes, having if else statements in a foor loop checking a boolean value is MUCH more elegant right?

You want a solution that is not expensive? Sorry I didn't know that speed was such an issue here...

Code:
```double sum = 1.0;
for(int i = 1; i < input; ++i)
sum += Math.pow(-1,i%2)*1.0/(2.0*((double)i) + 1.0);```
There, its not expensive anymore since it is either doing -1 no times (to the 0th power) or only once. WAY more elegant than yours and just as effective. Go ahead noob, benchmark it

11. Elite Member
Join Date
Jun 1999
Location
Eastern Florida
Posts
3,741

## Re: Calculating PI in java with loops

I was curious so I added the Math.pow() to the loop. It took 10 times as long. Elegant is nice in art galleries and fashion shows. Efficient wins for me every time in programs.
Code:
```public class ComputePI {
public static void main(String[] args) {
double pi = 0;
double y = 1;

final int lps = 90000000*2;    // this as double increases time to 1,123,755,952 ???
int cnt = 0;

long start = System.nanoTime();
for(int x=1; x < lps; x+=2) {
//         System.out.println("x=" + x + ", y=" + y + "  y/x=" + (y/x) + ", pi=" + pi);
pi = pi + (y/x);
y = -y;
//         Math.pow(-1,x);     //dur=11,930,493,680  <<< MUCH LONGER!!! 10X

cnt++;
} // end for(x)
System.out.println("PI=" + 4*pi + " after " + cnt //PI=3.141592642478473 after 90000000
+ " dur=" + (System.nanoTime() - start));
//(double x)dur=1317885653,=1052510305
//(double lps)=1112621297  <<<< LONGER???
//(int x)   dur=1068757621,=1,058,560,794,=1,066,056,440
}
}```

12. _uj
Banned
Join Date
Nov 2003
Posts
1,405

## Re: Calculating PI in java with loops

Originally Posted by ProgramThis
Lets look at YOUR "noob" solution:
My solution in #3 was aimed at a newbie and it came with a thorough explanation. The aim was to be straightforward, not elegant or effective.

If you want a both elegant and effective solution have a look at my suggested modification in #9 of Norm's solution. It should be the fastest solution so far whereas your Math.pow based solution is the slowest. A one-liner doesn't always translate to fast. Even a newbie knows that.

13. Member +
Join Date
Feb 2008
Posts
966

## Re: Calculating PI in java with loops

Norm, try the version that I posted last with i (x in your case) %2, it is much faster. The difference at 1,000,000 iterations is ~70 ms... If you are worried about 70 milliseconds then... well go with another solution. For 99% of anything you are going to need this for a 70 ms slowdown is nothing.

For both you and uj about speed: not everything in programming is about speed. Why do you think people still use things like bubble or merge sorts. Because they are quick and easy to implement if speed is not critical, which in most cases will only be milliseconds slower. Not everything you do has to be the fastest computational wise out there. Some people prefer readability to speed when the difference is a few milliseconds. Even newbies know that uj...

14. Elite Member
Join Date
Jun 1999
Location
Eastern Florida
Posts
3,741

## Re: Calculating PI in java with loops

Ok how about easy to understand code?
Which is easier to understand:
y = -y; // change sign
Math.pow(-1,i%2) // what does this do?

15. _uj
Banned
Join Date
Nov 2003
Posts
1,405

## Re: Calculating PI in java with loops

Originally Posted by ProgramThis
Norm, try the version that I posted last with i (x in your case) %2, it is much faster. The difference at 1,000,000 iterations is ~70 ms... If you are worried about 70 milliseconds then... well go with another solution. For 99% of anything you are going to need this for a 70 ms slowdown is nothing.
Using Math.pow(-1,i%2) will never be an elegant nor an efficient way of establishing whether i is even or odd and evaluate to 1 or -1 accordingly.

And to not make it ridicously slow you had to "adapt" one of the parameters (the i%2), in order to induce Math.pow to use two special cases which can be performed faster than the general case, making the purpose of the call even more obscure.

The significance of 70 ms is in the eye of the beholder. It could be nothing and it could be ages. What's interesting is how much slower it is than the alternative. 10 times? 100 times? 1000 times? When that has been established a user is free to use whichever alternative best fits the bill.
Last edited by _uj; October 1st, 2008 at 01:35 PM.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•