This commit is contained in:
commit
fe4e5d3aba
1 changed files with 81 additions and 0 deletions
81
padic.py
Normal file
81
padic.py
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
from fractions import Fraction
|
||||||
|
from sys import maxint
|
||||||
|
|
||||||
|
class PAdic:
|
||||||
|
p = 2
|
||||||
|
def __init__(self):
|
||||||
|
self.val = '' # current known value
|
||||||
|
self.prec = 0 # current known precision
|
||||||
|
self.order = 0 # order/valuation of number
|
||||||
|
pass # initialize object as subclass perhaps
|
||||||
|
|
||||||
|
def get(self, prec):
|
||||||
|
'Return value of number with given precision.'
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
# return value with precision up to 32 bits
|
||||||
|
def __int__(self):
|
||||||
|
return int(self.get(32), p)
|
||||||
|
def __str__(self):
|
||||||
|
return self.get(32)
|
||||||
|
def __repr__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# arithmetic operations
|
||||||
|
def __add__(self, other):
|
||||||
|
return PAdicAdd(self, other)
|
||||||
|
def __radd__(self, other):
|
||||||
|
return PAdicAdd(other, self)
|
||||||
|
def __sub__(self, other):
|
||||||
|
return PAdicAdd(self, PAdicInv(other))
|
||||||
|
def __rsub__(self, other):
|
||||||
|
return PAdicAdd(other, PAdicInv(self))
|
||||||
|
def __smul__(self, other):
|
||||||
|
return PAdicMul(self, other)
|
||||||
|
def __rsub__(self, other):
|
||||||
|
return PAdicMul(other, self)
|
||||||
|
|
||||||
|
# p-adic norm
|
||||||
|
def __abs__(self):
|
||||||
|
if self.order == maxint:
|
||||||
|
return 0
|
||||||
|
norm = Fraction(1)
|
||||||
|
if self.order > 0:
|
||||||
|
norm.numerator = p ** self.order
|
||||||
|
if self.order < 0:
|
||||||
|
norm.denominator = p ** self.order
|
||||||
|
return norm
|
||||||
|
|
||||||
|
class PAdicConst(PAdic):
|
||||||
|
def __init__(self, value):
|
||||||
|
PAdic.__init__(self)
|
||||||
|
value = Fraction(value)
|
||||||
|
|
||||||
|
# calculate valuation
|
||||||
|
if value == 0:
|
||||||
|
self.value = value
|
||||||
|
self.val = '0'
|
||||||
|
return
|
||||||
|
|
||||||
|
self.norm = Fraction(1)
|
||||||
|
self.order = 0
|
||||||
|
while not value.numerator % p:
|
||||||
|
self.norm /= p
|
||||||
|
self.order += 1
|
||||||
|
value.numerator /= p
|
||||||
|
while not value.denominator % p:
|
||||||
|
self.norm *= p
|
||||||
|
valuation -= 1
|
||||||
|
value.denominator /= p
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
def get(self, prec):
|
||||||
|
'Return value of constant with given precision.'
|
||||||
|
if self.value == 0:
|
||||||
|
return self.val
|
||||||
|
|
||||||
|
while self.prec < prec:
|
||||||
|
# update val based on value
|
||||||
|
|
||||||
|
self.prec += 1
|
||||||
|
return self.val # TODO add decimal point or trailing zeros
|
Loading…
Reference in a new issue