Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Caster

macrumors newbie
Original poster
Jul 18, 2007
10
0
Hey everyone, I'm writing a program for my intro to Java class, and I'm having a couple of problems.

One part of the program was to write a method to estimate the value of Pi using the following series: 4 * (1 - 1/3 + 1/5 - 1/7 + 1/9 ... - 1/(2i-1) + 1(2i+1)

Heres the method I wrote:
Code:
	public static double pi()
	{
		double pi = 0.0;
		
		for(int i = 0; i <= 1000000; i++)
		{
		 	pi += 4 * (1.0/(1 + i*2) * ((i % 2 == 0) ? 1 : -1));
		}
	
		return pi;
	}

For Pi it returns: 3.1415936535887745 when my professor wants it to return: 3.141590653589692, for the first 7 digits its right, but after that I'm getting something else.

My next problem is creating a method that approximates the square root of a number by repeating the following formula nextGuess = (lastGuess + (num / lastGuess) / 2. The prompt states that when nextGuess and lastGuess are almost identical, nextGuess is the approximate square root. lastGuess is given, as 1.0 and it states that when the difference between nextGuess and lastGuess is less than a very small number (.00001) you can claim that nextGuess is the approximated square root of num.

Heres the method I wrote:
Code:
	public static double sqrt(double num)
	{
		double nextGuess, lastGuess;
		lastGuess = 1.0;
		nextGuess = 0;
		do{
		nextGuess = (lastGuess + (num / lastGuess)) / 2.0;
		lastGuess = nextGuess;
		}
		while((nextGuess - lastGuess) <= 0.00001);
		return nextGuess;
	}

The problem is the loop doesn't end, it just repeats. He wants us to use the input of 10 and it should return 3.16227660168379, which it does when you print out nextGuess, so I can correctly get the square root, but I can't stop the loop. I've printed out nextGuess - lastGuess to see what it is and it prints out 0.0, which should essential stop the loop (0.0 <= .00001), unless there's a positive number less then 0 that Java knows that I don't know..

Thanks for the help everyone, sorry about the long post.
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
I've printed out nextGuess - lastGuess to see what it is and it prints out 0.0, which should essential stop the loop (0.0 <= .00001), unless there's a positive number less then 0 that Java knows that I don't know..

The loop will continue until the expression evaluates to false. 0.0 is less than .00001, so it evaluates to true.

From a cursory glance, I think you want to check for

Code:
((nextGuess - lastGuess) [color=red][b]>[/b][/color] 0.00001)
 

angelwatt

Moderator emeritus
Aug 16, 2005
7,852
9
USA
For the PI question I messed with the equation a little bit using JavaScript (yes i know it's not Java, but still works fine and it got the same answer you did so is accurate enough for this point). I believe all you need to do is let your for loop run longer. Below are results from running at different amounts. As you can see it gets closer to the desired number as the loop amount increases. I'm guessing you may just need to tack on another zero. JavaScript kept timing out on my though in Firefox so wasn't able to test that far. The last number is what Mac's calculator says PI is.

Code:
	3.1415936535887745 looped 1000000
	3.1415931535894743 looped 2000000
	3.1415929869229293 looped 3000000
	3.141590653589692   - desired
	3.14159265358979 // PI from Mac calc
 

Caster

macrumors newbie
Original poster
Jul 18, 2007
10
0
The loop will continue until the expression evaluates to false. 0.0 is less than .00001, so it evaluates to true.

From a cursory glance, I think you want to check for

Code:
((nextGuess - lastGuess) [color=red][b]>[/b][/color] 0.00001)

I've tried that, the problem is that it returns 5.5 and not the correct square root.
For the PI question I messed with the equation a little bit using JavaScript (yes i know it's not Java, but still works fine and it got the same answer you did so is accurate enough for this point). I believe all you need to do is let your for loop run longer. Below are results from running at different amounts. As you can see it gets closer to the desired number as the loop amount increases. I'm guessing you may just need to tack on another zero. JavaScript kept timing out on my though in Firefox so wasn't able to test that far. The last number is what Mac's calculator says PI is.

The problem is that my professor wants us to use i as 1000000, sorry I forgot to include that..

Thanks for the quick responses!
 

Persifleur

macrumors member
Jun 1, 2005
66
0
London, UK
Regarding your first problem, you get the desired answer with your loop if you change your for statement to only do half as many iterations as you are currently:
Code:
for(int i = 0; i < 500000; i++)
I know that your prof wants you to use a specific value for the upper bound of i, so'll just need to do half as much work on each iteration as you're doing now.

Regarding your second problem, the reason your sqrt function isn't working is because you're setting
Code:
lastGuess = nextGuess
as the last line of your loop. i.e.
Code:
((nextGuess - lastGuess) <= 0.00001)
will always be true and your loop will never finish.

Is that enough to get you going? I don't want to just give the answer out.
 

toddburch

macrumors 6502a
Dec 4, 2006
748
0
Katy, Texas
I think you might have copied down the expected correct answer wrong, or it was given to you wrong.

For my tweaked routine, I get the following values:

Code:
// 3.14159365358 87745  = the value you get 
// 3.14159065358 9692   = your instructor's required value 
// 3.14159165358 97743  = 1000000 loops (your assignment rewritten, what I get) 
// 3.14159264358 9326   = 100000000 loops (more precision)
// 3.14159265258 80504  = 1000000000 loops (even more precision)
// 3.14159265358 97932384626433 = wikipedia at 50 decimal places

I rewrote the algorithm to be simpler. When I used your algorithm, I got the same results as you (as expected).

My forumula is more in line with wikipedia's:

pi = 4/1 - 4/3 + 4/5 - 4/7 + 4/9 - 4/11, etc....

Code:
public class MyPi { 
	public static void main(String args[]) { 
		System.out.println( pi() ) ; 
	}

	public static double pi() {
		double pi   =  0.0 ;
		double sign = -1.0 ; 
		for (int i = 0 ; i < 1000000 ; i++ ) {
			sign *= -1.0d ; 
			pi += sign * (4.0d / (1.0d +  (i * 2.0d ) ) ) ; 
		}
		return pi;
	}
}

Todd

edit: Note my difference, I didn't use <=, but just <
 

toddburch

macrumors 6502a
Dec 4, 2006
748
0
Katy, Texas
LOL. This gives the exact correct answer. See if he'll accept it.

Code:
public class MyPi { 
	public static void main(String args[]) { 
		System.out.println( pi() ) ; 
	}

	public static double pi() {
		double pi   =  0.0 ;
		double sign = -1.0 ; 
		for (int i = 0 ; i < 1000000 ; i++ ) {
			[color=red]if (i >= 500000) continue ; [/color]
			sign *= -1.0d ; 
			pi += sign * (4.0d / (1.0d +  (i * 2.0d ) ) ) ; 
		}
		return pi;
	}
}

Todd
 

toddburch

macrumors 6502a
Dec 4, 2006
748
0
Katy, Texas
OK, I figured out what he wants.
Code:
public class MyPi { 
	public static void main(String args[]) { 
		System.out.println( pi() ) ; 
		System.out.println( Math.PI ) ; 
	}

	public static double pi() {
		double pi   =  0.0 ;
		double sign = -1.0 ; 
		for (int i = 0 ; i < 1000000 ; i++ ) {
			[color=red]if (i % 2 == 00) continue ;[/color]
			sign *= -1.0d ; 
			pi += sign * [color=red](4.0d / i)[/color] ; 
		}
		return pi;
	}
}

Todd
 

toddburch

macrumors 6502a
Dec 4, 2006
748
0
Katy, Texas
which can further be refined as

Code:
public class MyPi { 
	public static void main(String args[]) { 
		System.out.println( pi() ) ; 
		System.out.println( Math.PI ) ; 
	}

	public static double pi() {
		double pi   =  0.0 ;
		double sign = -1.0 ; 
		for (int [color=red]i = 1[/color] ; i < 1000000 ; [color=red]i+=2[/color] ) {
			sign *= -1.0d ; 
			pi += sign * (4.0d / i) ; 
		}
		return pi;
	}
}
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
This works for me for the root thing

Code:
public class Sqrt
{
	public static double sqrt(double num)
	{
		double next, last;
		last = 1;
		next = (last+(num/last))/2;
		while( (next>last &&(next-last)>0.0001) ||
			   (last-next>0.0001))
		{
			last = next;
			next = (last+(num/last))/2;
		}
		return next;
	}
	
	public static void main(String[] args)
	{
		double root = sqrt(10);
		System.out.println(root);
	}
}

I'll leave it up to the reader to work out why I have the strange looking loop conditions :D

OK, this is a bit cleaner!

Code:
 static double abs(double in)
	{
		if (in<0)
		{
			return -in;
		}
		return in;
	}
	
	public static double sqrt(double num)
	{
		double next, last;
		last = 1;
		next = (last+(num/last))/2;
		while( abs(next-last)>0.0001)
		{
			last = next;
			next = (last+(num/last))/2;
		}
		return next;
	}
 

toddburch

macrumors 6502a
Dec 4, 2006
748
0
Katy, Texas
More info on why your PI algorithm didn't get you where you wanted.

Here's your basic formula:
Code:
pi += 4 * (1.0/(1 + i*2) * ((i % 2 == 0) ? 1 : -1));

This works starting with 0 since you always add 1 to the denominator. And, you always get an odd demoninator because you multiply i times 2, which always yields an even number, and then add 1, which always yields an odd number.

For the first 500,000 iterations, you are pretty much right on track.
Code:
i = 0:         4 * (1 / (1 + (0*2)) , or 1  
i = 1:         4 * (1 / (1 + (1*2)) , or 3  
i = 2:         4 * (1 / (1 + (2*2)) , or 5  
i = 3:         4 * (1 / (1 + (3*2)) , or 7   
i = 4:         4 * (1 / (1 + (4*2)) , or 9  
i = 500,000:   4 * (1/  (1 + (500000 * 2)) or 1,000,001

Now, your instructor wanted you to stop at 1,000,000. However, since your formula multiplies i * 2, you actually stopped at 2,000,000.

Taking my last version and stopping at 2,000,000 instead of 1,000,000, I get (close enough for illustration purposes) your wrong answer.

Hope that explains why you were getting the answer you were getting.

Todd
 

Caster

macrumors newbie
Original poster
Jul 18, 2007
10
0
Thanks for all the help, I'll be trying it out after my next class and see what I get.

Once again, thanks for the help and quick responses!

Edit: I fixed the square root loop problem last night shortly after posting this.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.