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 RCL+ Y add one 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 STO i to start with register V and run to L 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 + add in the carry 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 STO i to start with register L and run to V 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.