converted from a post in the freebasic forum
example output
pi in base 10 = 3.1415926535897932384626433832795028841971693993751
pi in base 16 = 3.243F6A8885A308D313198A2E03707344A4093822299F31D01
pi in base 2 = 11.0010010000111111011010101000100010000101101001000
Declare Function find_pi$(Byval n As Integer, Byval nbase As Integer)
PRINT "waiting"
PRINT find_pi$(50, 10)
PRINT find_pi$(50, 16)
PRINT find_pi$(50, 2)
FUNCTION convert$ (n AS _INTEGER64, nbase AS INTEGER)
IF nbase < 2 OR nbase > 16 THEN
convert$ = "base must be between 2 and 16"
EXIT FUNCTION
END IF
DIM sn AS STRING
DIM r AS _INTEGER64
DIM h(15) AS STRING * 1
h(0) = "0": h(1) = "1": h(2) = "2": h(3) = "3": h(4) = "4": h(5) = "5": h(6) = "6": h(7) = "7": h(8) = "8"
h(9) = "9": h(10) = "A": h(11) = "B": h(12) = "C": h(13) = "D": h(14) = "E": h(15) = "F"
IF n = 0 THEN
convert$ = "0"
EXIT FUNCTION
ELSEIF n < 0 THEN
convert$ = "positive number only"
EXIT FUNCTION
END IF
sn = ""
WHILE n >= nbase
r = n MOD nbase
n = n \ nbase
sn = h(r) + sn
WEND
sn = h(n) + sn
convert$ = sn
END FUNCTION
SUB array_mul (a() AS _INTEGER64, f AS INTEGER, n AS INTEGER, nbase AS INTEGER)
DIM c AS _INTEGER64, p AS _INTEGER64, h AS _INTEGER64
c = 0
FOR p = n TO 0 STEP -1
h = a(p) * f + c
c = h \ nbase
a(p) = h MOD nbase
NEXT p
END SUB
SUB array_div (a() AS _INTEGER64, f AS INTEGER, n AS INTEGER, nbase AS INTEGER)
DIM b AS _INTEGER64, p AS _INTEGER64, h AS _INTEGER64
b = 0
FOR p = 0 TO n
h = a(p) + b * nbase
a(p) = h \ f
b = h MOD f
NEXT p
END SUB
SUB array_add (a() AS _INTEGER64, b() AS _INTEGER64, n AS INTEGER, nbase AS INTEGER)
DIM c AS _INTEGER64, p AS _INTEGER64, h AS _INTEGER64
c = 0
FOR p = n TO 0 STEP -1
h = a(p) + b(p) + c
c = h \ nbase
a(p) = h MOD nbase
NEXT p
END SUB
SUB array_sub (a() AS _INTEGER64, b() AS _INTEGER64, n AS INTEGER, nbase AS INTEGER)
DIM c AS _INTEGER64, p AS _INTEGER64, h AS _INTEGER64
c = 0
FOR p = n TO 0 STEP -1
h = a(p) - b(p) + nbase
c = h \ nbase
a(p) = h MOD nbase
IF (c = 0) THEN a(p - 1) = a(p - 1) - 1
NEXT p
END SUB
FUNCTION is_zero% (a() AS _INTEGER64, n AS INTEGER)
DIM p AS INTEGER
FOR p = 0 TO n
IF a(p) <> 0 THEN
is_zero% = 0
EXIT FUNCTION
END IF
NEXT p
is_zero% = 1
END FUNCTION
SUB arctan (t() AS _INTEGER64, s() AS _INTEGER64, div AS INTEGER, n AS INTEGER, nbase AS INTEGER)
DIM w AS _INTEGER64, i AS INTEGER
s(0) = 1
i = 1
w = div
array_div s(), w, n, nbase
array_add t(), s(), n, nbase
DO
array_mul s(), i, n, nbase
w = div * div
array_div s(), w, n, nbase
i = i + 2
w = i
array_div s(), w, n, nbase
array_sub t(), s(), n, nbase
array_mul s(), i, n, nbase
w = div * div
array_div s(), w, n, nbase
i = i + 2
w = i
array_div s(), w, n, nbase
array_add t(), s(), n, nbase
LOOP UNTIL is_zero%(s(), n) = 1
END SUB
FUNCTION find_pi$ (n AS INTEGER, nbase AS INTEGER)
IF nbase < 2 OR nbase > 16 THEN
find_pi$ = "base must be between 2 and 16"
EXIT FUNCTION
END IF
IF n < 2 THEN n = 2
'DIM tm AS DOUBLE: tm = TIMER
DIM digit AS STRING, uit AS STRING
uit = "pi in base " + STR$(nbase) + " = " + convert(3, nbase) + "."
DIM s(n + 2) AS _INTEGER64
DIM t(n + 2) AS _INTEGER64
DIM i AS INTEGER, f AS INTEGER
f = 2
arctan t(), s(), f, n, nbase
f = 3
arctan t(), s(), f, n, nbase
array_mul t(), 4, n, nbase
'tm = TIMER - tm
FOR i = 1 TO n - 1
digit = convert(t(i), nbase)
uit = uit + digit
NEXT i
'PRINT "elapsed time = "; tm; " seconds"
find_pi$ = uit
END FUNCTION