The Museum of HP Calculators

HP Articles Forum

99 Digits of PI on an HP 32SII

Posted by Katie Wasserman on 19 June 2002, 11:08 p.m.

(See the more recent article on this forum for a simpler algorithm them produces 200 digits of pi on the 32sii.)

Just for fun, I tried to see how many digits of pi I could get a 32SII to calculate in a reasonable amount of time. This program computes 99 of them (only the first 96 of them are correct) in around 11 minutes. It makes heavy use of store and recall register arithmetic to save programming space. It also makes use of 12 digit accuracy, but it could be adapted to most any other HP calculator with enough memory and indirect addressing.

After entering the program and verifying that the checksums are correct, you can run it by just using XEQ P. Wait awhile (11 minutes for me) and the program will end. The result will be in registers A-K, 9 digits in each register (no decimal points).

```
First 99 digits of pi (first 96 are correct) based on the following formula:
Pi = 20 * arctan(1/7) + 8 * arctan(3/79)
And using:
Arctan(x) = (y/x) * (1 + y*(2)/(3) + y^2*(2*4)/(3*5) + y^3*(2*4*6)/(3*5*7) + ...)
where y = x^2 / (1 + x^2)
The initial terms of these expressions are built into the program as 2.8 and 0.30336
Pi = term_1 + term_2
term_1 =  20 * arctan(1/7); so  x=1/7; y=1/50
= 2.8 * (2/3*y + 2/3*4/5*y^2 + ...)
term_2 = 8 * arctan(3/79); so x=3/79 and y=9/6250 = (9/125)/50
= .30336 * (2/3*y + 2/3*4/5*y^2 + ...)
-------------------------------------------
LBL P				start of program
CLRVARS			result will be in registers A-K, L-V is the partial sum
X, Y and I are also used
7
10^x
28
x			low memory way of getting 280,000,000; starting value
STO L
XEQ A			add to result register
2
STO Y			starting loop value
LBL Q			         start of 1st term loop
XEQ X			do main part of loop
X>0?			if X is not zero then the partial sum still needs to be reduced
GTO Q
30,336,000		stating value for 2nd term
STO L			(note: M-V will be zero when 1st loop loop ends)
XEQ A			add to result register
2
STO Y			starting loop value
LBL R				start of 2nd term loop
9
XEQ M			multiply partial sum by 9
125
XEQ D			divide by 125
XEQ X			do main part of loop
X>0?			If X is not zero then partial sum still needs to be reduced
GTO R
STOP			done, result is in A-K
(9 digits/register, leading zero's won't display)
LBL X				subroutine to do one step of 1st or 2nd term
RCL Y			get loop counter
XEQ M			multiply partial sum by it
1
XEQ D			divide by it
50
XEQ D			divide by 50
XEQ A			add partial sum to result
2
STO+ Y			add 2 to loop counter
RCL V			get low order 9 digits of partial sum
RCL+ L			add in low order 9 digits and return it
(this is a heuristic,
if X is zero then we assume partial sum is all zero)
RTN
P=15.0	CK=1038
Q=21.5	CK=810E
R=13.5	CK=AF06
X=21.0	CK=3B57
-------------------------------------------
LBL A				Start of subroutine to add partial sum into result
11
STO i			starting value for loop counter
0			starting value for carry
LBL B				start of loop
11
STO+ i			point to 9 digits of partial sum
R\/			drop the 11 from the stack
RCL+(i)			add the partial sum 9 digits to the carry
11
STO- i			point to 9 digits of the result
R\/			drop the 11 from the stack
9
10^x			low memory way of getting 1,000,000,000
x<>(i)			temporarily exchange 1,000,000,000 and the 9 digits of the result
+			add the partial sum + carry to the result - just these 9 digits
RCL/(i)			divide by 1,000,000,000
FP			the fraction part will only be 9 digits
STOx(i)			this will be a 9-digit integer now stored in result
LASTx			get the result of the divide back
IP			the integer part will be the new carry
DSE i			decrement the loop counter and check for done
GTO B			process next 9 digits
RTN
A=06.0	CK=A9D7
B=30.0	CK=099E
-------------------------------------------
LBL M		  	         start of subroutine to multiply partial sum by top of stack
STO X			save the multiplier in X
22.011			set loop counter
0			starting value for carry
LBL N	   		         start of loop
RCL(i)			get 9 digits of partial sum
RCLx X			multiply it by the argument saved in register X
9
10^x			low memory way of getting 1,000,000,000
STO (i)			temporarily store this in place of the multiplicand
/			divide the product by 1,000,000,000
FP			the fractional part will only be 9 digits
STOx(i)			this will be a 9-digit integer now stored in the partial sum
LASTx			get the result of the divide back
IP			the integer part is the new carry
DSE i			decrement the loop counter and check for done
GTO N			process next 9 digits
RTN
M=15.5	CK=4B87
N=22.5	CK=1F72
-------------------------------------------
LBL D			         start of subroutine to divide partial sum by top of stack
STO X			save the divisor in X
12.022			set loop counter
0			starting value for carry
LBL E				start of loop
STO+(i)			add carry to 9-digit dividend
RCL (i)			get the sum
RCL/ X			divide by the argument save in register X
IP			the integer part will be the quotient
X<>(i)			save it and get the original dividend
RCL (i)			get the quotient on the stack
RCLx X			compute the remainder by multiplying by the divisor
-			and subtracting from the dividend
9
10^x			low memory way of getting 1,000,000,000
x			adjust the remainder to be the new carry
ISG i			increment the loop counter and check for done
GTO E			process next 9 digits
RTN
D=15.5	CK=5117
E=22.5	CK=FCD4
```

Edited: 5 Nov 2008, 10:41 a.m.