// Applet that computes pi
// Author Steve Merrin June 1998
// Computes pi to any desired accuracy; user can choose
// from three formulas:
// formula 1: pi = 16arctan(1/5) - 4arctan(1/239)
// formula 2: pi = 8arctan(1/3) + 4arctan(1/7)
// formula 3: pi = 4arctan(1/2) + 4arctan(1/3)
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.math.BigInteger;
public class AppletPi3 extends Applet implements ActionListener, ItemListener
{
final int COLS = 50; // display pi in blocks ROWS by COLS
final int ROWS = 10;
TextField numDigits = new TextField(7);
TextArea output =
new TextArea( "", ROWS + 7, COLS + 2, TextArea.SCROLLBARS_VERTICAL_ONLY);
int choice = 1; // 3 formulas to choose from
String[] formula = { "16arctan(1/5) - 4arctan(1/239)",
"8arctan(1/3) + 4arctan(1/7)",
"4arctan(1/2) + 4arctan(1/3)" };
String initialText =
"Choose the formula to be used to compute pi.\nThe first one is " +
"the fastest:\n" +
"formula 1 is pi = " + formula[0] + "\n" +
"formula 2 is pi = " + formula[1] + "\n" +
"formula 3 is pi = " + formula[2] + "\n\n" +
"Enter the number of places in the box above and press return.";
Button show = new Button( "show formulas" );
// button puts initial prompting text back into the text area
Panel p = new Panel(); // panel at bottom of window
CheckboxGroup g = new CheckboxGroup(); // group 3 radio buttons
Checkbox fmla1 = new Checkbox( "formula 1", g, true );
Checkbox fmla2 = new Checkbox( "formula 2", g, false );
Checkbox fmla3 = new Checkbox( "formula 3", g, false );
Panel p1 = new Panel(); // panel for top of Window
public void init()
{
setLayout(new BorderLayout());
setBackground(Color.lightGray);
numDigits.addActionListener(this);
p1.setLayout( new FlowLayout() );
p1.add( new Label("Author: Steve Merrin") );
p1.add( new Label("Compute pi") );
p1.add( new Label("Enter number of decimal places:", Label.RIGHT) );
p1.add(numDigits);
add(p1, "North");
add(output, "Center");
output.setText( initialText );
p.setLayout( new FlowLayout() );
p.add( new Label( "Choose formula:", Label.CENTER ) );
p.add(fmla1); p.add(fmla2); p.add(fmla3); // three radio buttons
// Below, button show used to restore initial text in text area
p.add(show);
add(p, "South"); // add panel of 3 radio buttons plus show button
show.addActionListener(this);
fmla1.addItemListener(this);
fmla2.addItemListener(this);
fmla3.addItemListener(this);
}
public void itemStateChanged( ItemEvent e ) // handle radio buttons
{
if( e.getItem().equals("formula 1") ) {choice = 1; return;}
if( e.getItem().equals("formula 2") ) {choice = 2; return;}
if( e.getItem().equals("formula 3") ) {choice = 3; return;}
}
public void actionPerformed(ActionEvent e)
{
// event could be clicking the "show" button or else pressing Enter
// with the cursor in the text field
if( e.getActionCommand().equals("show formulas") )
{
// "show" button was clicked
output.setText( initialText );
return;
}
// Below, action to take when user presses Enter, with cursor in textfield
int N = Integer.parseInt( numDigits.getText() );
output.setText("Using formula " + choice + "\nComputation of pi to " + N +
" places now in progress ...");
long time1 = System.currentTimeMillis(); // time how long it takes
String piString = PiN3.piDigits(N, choice).toString();
// piString is 31415...
long time2 = System.currentTimeMillis();
output.setText( "3.\n" );
int digitsRemaining = N;
int next = 1; // index into piString, initialized to point to 2nd char
while( digitsRemaining > 0 ) // loop that extracts substrings from
{ // piString
if( digitsRemaining >= COLS )
{
output.append( piString.substring(next, next + COLS) + "\n" );
next += COLS;
digitsRemaining -= COLS;
}
else
{
output.append( piString.substring(next,
next + digitsRemaining) + "\n" );
digitsRemaining = 0;
}
if( (N - digitsRemaining) % (COLS * ROWS) == 0 )
output.append( "(number of digits displayed so far: " +
(N - digitsRemaining) + ")\n" );
} // while
long deltaSeconds = (time2 - time1)/1000; // elapsed time in seconds
output.append( "pi computation time: " + deltaSeconds/60 + " min "
+ deltaSeconds % 60 + " sec\n" );
output.append( "total number of digits displayed: " + N + "\n" );
output.append( "formula " + choice + " used: " + formula[choice - 1] );
} // actionPerformed
} // AppletPi3
// author: Steve Merrin June 98
// Computes pi to any desired accuracy; user can choose
// from three formulas (formula 1 is the fastest):
// formula 1: pi = 16arctan(1/5) - 4arctan(1/239)
// formula 2: pi = 8arctan(1/3) + 4arctan(1/7)
// formula 3: pi = 4arctan(1/2) + 4arctan(1/3)
class PiN3
{
// Finds integer part of 10^N times arctan(1/k)
public static BigInteger invtan( int k, int N )
{
int i;
int a = k*k;
int M = 0;
while( (Math.log(2*M + 3) + (M + 1)*Math.log(a)) <= N*Math.log(10) )
M++;
// M is the degree of the Taylor polynomial needed to achieve N
// digit accuracy of arctan(1/k).
BigInteger tenToN = new BigInteger("1");
// The following loop computes 10^N
for( i = 0; i < N; i++ )
tenToN = tenToN.multiply(BigInteger.valueOf(10));
int c = 2*M + 1;
BigInteger s = tenToN.divide(BigInteger.valueOf(c)); // s = (10^N)/c
for( i = 0; i < M; i++ )
{
c = c - 2;
s = (tenToN.divide(BigInteger.valueOf(c))).
subtract(s.divide(BigInteger.valueOf(a))); // s = (10^N)/c - s/a
}
return s.divide(BigInteger.valueOf(k));
// return s/k, which is integer part of 10^N times arctan(1/k)
}
// computes pi with N digits following the decimal point
// choice == 1 use formula 1
// choice == 2 use formula 2
// choice == 3 use formula 3
public static BigInteger piDigits(int N, int choice)
{
N += 8;
// To be safe, compute 8 extra digits, to be dropped at end
// The 8 is arbitrary
BigInteger pi = new BigInteger("1"); // compiler requires init
if( choice == 1 )
pi = (invtan(5,N).multiply(BigInteger.valueOf(16))).subtract
(invtan(239,N).multiply(BigInteger.valueOf(4)));
if( choice == 2 )
pi = (invtan(3,N).multiply(BigInteger.valueOf(8))).add
(invtan(7,N).multiply(BigInteger.valueOf(4)));
if( choice == 3 )
pi = (invtan(2,N).multiply(BigInteger.valueOf(4))).add
(invtan(3,N).multiply(BigInteger.valueOf(4)));
return pi.divide(BigInteger.valueOf(100000000)); // drop last 8 digits
} // piDigits
} // class PiN3