File: base.py, class: Base | ||
---|---|---|
base.py | Rest of base.py | Calculate Gregory's series |
# base.py: convert to and from any base # convert: # Input: int or double or mpmath, # the base, and no of decimals # Output: a str representing the num # restore: # Input: str rep a fp num and base b # Output: the num as an internal int # or double or mpmath ds = ['0','1','2','3','4','5','6','7','8', '9','a','b','c','d','e','f','g','h','i', 'j','k','l','m','n','o','p','q','r','s', 't','u','v','w','x','y','z', 'A','B','C','D','E','F','G','H','I','J', 'K','L','M','N','O','P','Q','R','S','T', 'U','V','W','X','Y','Z'] dr = {'0':0, '1':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, 'a':10, 'b':11, 'c':12, 'd':13, 'e':14, 'f':15, 'g':16, 'h':17, 'i':18, 'j':19, 'k':20, 'l':21, 'm':22, 'n':23, 'o':24, 'p':25, 'q':26, 'r':27, 's':28, 't':29, 'u':30, 'v':31, 'w':32, 'x':33, 'y':34, 'z':35, 'A':36, 'B':37, 'C':38, 'D':39, 'E':40, 'F':41, 'G':42, 'H':43, 'I':44, 'J':45, 'K':46, 'L':47, 'M':48, 'N':49, 'O':50, 'P':51, 'Q':52, 'R':53, 'S':54, 'T':55, 'U':56, 'V':57, 'W':58, 'X':59, 'Y':60, 'Z':61,} def dbase(y, b): # int part >= 1 s = "" while y > 0: s = ds[y%b] + s y = y // b return s | class Base: # number base convert def __init__(self): pass def convert(self,x,b=10,lim=8): if not(1 < b < 63): return "?" s = dbase(int(x),b) if s == "": # int part s = '0' if x - int(x) == 0: return s s += '.' x -= int(x) d = 0 for k in range(0,lim): x = (x - d)*b d = int(x) s += ds[d] return s def restore(self, st, b): i = 0; res = 0 while True: if i == len(st): return res c = st[i] if c == '.': break res = res*b + dr[c] i = i + 1 # here i --> '.' in st i = i + 1 bs = b while i < len(st): res = (res + float(dr[st[i]])/bs) bs = bs * b i = i + 1 return res |
# mp.py: sum Gregory's series, from __future__ import print_function from mpmath import * from base import * mp.dps = 60 # digits of numbers print("Prec:", mp.dps) currB = 8 # base for answer print("Base: ", currB) currN = 8**5 # total terms in series sum = mpf(0) sign = 1 for k in range(0,currN): term = 1/(mpf(2)*k + 1) sum = sum + sign*term sign = -sign print(k) base = Base() print(base.convert(sum*4, currB, int(mp.dps))) print(base.convert(mp.pi, currB, int(mp.dps))) |
The class Base above is especially interesting to me because
it works unchanged on doubles or on the extended floats of mpmath.
When the function convert is invoked, the type of the first
parameter, whether double or mpmath, determines the type of
all the other float variables in the function, because when the
actual parameter is combined with other variables, that forces
these to take on the same type. The same is true for the function
restore, where its second actual parameter (the base b) is
made into an mpmath float.
The restore function in Base is not needed for the study
below of Gregory's Series in other number bases.
It is included for completeness.
The "float" at the end of the base.py file is there so
that the code will execute properly in Python 2, since in Python 2,
a single slash applied to 2 integers gives truncated integer division.
Here is a short test of Base using ordinary doubles.
|
Using other number bases: Bases 8 (and other binary ones), 12, and 20 |
Base 8, binary, same as bases 2, 4, 16, etc. 3.1103755242102643021514230630505600670163211220111602105147630720020273724616611633104505120207461615002335737124315474647220615460126051557445742415647741 8(8^1) 3.0105732144000672224301057321440006722243010 64(8^2) 3.1003757241642737746355363136740316011712232 512(8^3) 3.107375524410264042152373055526641342172463230726020207105570 4095(8^4) 3.110275524210464302147023063145560061474321734555035621774573 32768(8^5) 3.11036552421026450215142303705056007651632111446716021664242305754315242227167757 262144(8^6) 3.11037452421026430235142306305032006701632207201116020317276307206330377246043527561050032203746505755523713272 2097152(8^7) 3.11037542421026430215162306305056006441632112201125521051476306446002737246247372731045036743217616153004361273 16777216(8^8) 3.1103755142102643021514232630505600670162751220111602105244630720020273651376611633104566374607461614657747167124315772747406015457024126562741746715427734 Exact:pi: 3.1103755242102643021514230630505600670163211220111602105147630720020273724616611633104505120207461615002335737124315474647220615460126051557445742415647741 Base 12 20736(12^4) 3.184709493b91b664573a2511bb160a81a0519a200ab94a46ba043a31796a5928a6 248832(12^5) 3.1847b9493b918667573a6211b7451551a06680290a7774b402742509409a453703 2985984(12^6) 3.184808493b918664576a6211bb151514a05729290b7139a49274177017a762b398 Exact: pi 3.184809493b918664573a6211bb151551a05729290a7809a4927421406947728691 Base 20 8000(20^3) 3.2gbeg9gbi49d21hccb3eh9dg030da9he4i3ccf9b5h7405b00jfig7f 160000(20^4) 3.2gcdg9gbhj9d71hihb3ea5cb0362dc7bfb8bj11211j5ih96dgf5172 3200000(20^5) 3.2gcef9gbhj9d21i3hb3egacajh11eb2bfb9g98987debbgh6fcfagahjh7c77c22idag0b8f91ef39d2 Exact: pi 3.2gceg9gbhj9d21hihb3egacb0361eb2bfb8h83987debh5180cfag88d2c627c3fiacdi7ddid6ec0d0 1 1 1 1 1 1 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 |
Below are three examples of number bases without 2 as a factor.
Notice that in each case there is only one section of extra
digits of pi, except for randomly occurring ones.
That section exists because in Euler's formula, the first term
after the sum only has an N in the denominator.
All other terms have a non-zero power of 4 in the
denominator.
|