first commit
This commit is contained in:
136
frac.py
Normal file
136
frac.py
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
#stores a rational number to perfect precision as a ratio of longs
|
||||||
|
#combines with ints to produce a frac ( except __rpow__() ) and with floats to produce a float
|
||||||
|
#comparisons with floats might not work perfectly for very similar numbers, I need to test out the float casting a bit
|
||||||
|
#it's possible that order w/r/t floats that differ near the limit of precision may not work properly, and even break ordering
|
||||||
|
#one solution would be casting floats to fracs instead of vice-versa
|
||||||
|
|
||||||
|
import numbers
|
||||||
|
|
||||||
|
class frac:
|
||||||
|
|
||||||
|
def __init__(self, num, den):
|
||||||
|
self.num = long(num)
|
||||||
|
self.den = long(den)
|
||||||
|
self.reduce()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return 'frac(%d, %d)' % (self.num, self.den)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '%d/%d' % (self.num, self.den)
|
||||||
|
|
||||||
|
def __int__(self):
|
||||||
|
return int(self.num / self.den)
|
||||||
|
|
||||||
|
def __long__(self):
|
||||||
|
return self.num / self.den
|
||||||
|
|
||||||
|
def __float__(self):
|
||||||
|
return float(self.num) / self.den
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return bool(self.num)
|
||||||
|
|
||||||
|
def __add__(self, other):
|
||||||
|
if isinstance(other, frac):
|
||||||
|
newnum = self.num * other.den + other.num * self.den
|
||||||
|
newden = self.den * other.den
|
||||||
|
return frac(newnum, newden)
|
||||||
|
elif isinstance(other, (int, long)):
|
||||||
|
return frac(self.num + other * self.den, self.den)
|
||||||
|
elif isinstance(other, float):
|
||||||
|
return other + float(self)
|
||||||
|
else:
|
||||||
|
return NotImplemented
|
||||||
|
|
||||||
|
def __radd__(self, other):
|
||||||
|
return self + other
|
||||||
|
|
||||||
|
def __sub__(self, other):
|
||||||
|
if isinstance(other, frac):
|
||||||
|
newnum = self.num * other.den - other.num * self.den
|
||||||
|
newden = self.den * other.den
|
||||||
|
return frac(newnum, newden)
|
||||||
|
elif isinstance(other, (int, long)):
|
||||||
|
return frac(self.num - other * self.den, self.den)
|
||||||
|
elif isinstance(other, float):
|
||||||
|
return float(self) - other
|
||||||
|
else:
|
||||||
|
return NotImplemented
|
||||||
|
|
||||||
|
def __rsub__(self, other):
|
||||||
|
return -1 * (self - other)
|
||||||
|
|
||||||
|
def __mul__(self, other):
|
||||||
|
if isinstance(other, frac):
|
||||||
|
return frac(self.num * other.num, self.den * other.den)
|
||||||
|
elif isinstance(other, (int, long)):
|
||||||
|
return frac(self.num * other, self.den)
|
||||||
|
elif isisntance(other, float):
|
||||||
|
return float(self) * other
|
||||||
|
else:
|
||||||
|
return NotImplemented
|
||||||
|
|
||||||
|
def __rmul__(self, other):
|
||||||
|
return self * other
|
||||||
|
|
||||||
|
def __truediv__(self, other):
|
||||||
|
if isinstance(other, frac):
|
||||||
|
return frac(self.num * other.num, self.den * other.den)
|
||||||
|
elif isintance(other, (int, long)):
|
||||||
|
return frac(self.num * other, self.den)
|
||||||
|
elif isinstance(other, float):
|
||||||
|
return float(self) * other
|
||||||
|
else:
|
||||||
|
return NotImplemented
|
||||||
|
|
||||||
|
def __rtruediv__(self, other):
|
||||||
|
if isinstance(other, frac):
|
||||||
|
return frac(other.num * self.den, self.num * other.den)
|
||||||
|
elif isinstance(other, (int, long)):
|
||||||
|
return frac(self.den * other, self.num)
|
||||||
|
elif isinstance(other, float):
|
||||||
|
return other / float(self)
|
||||||
|
else:
|
||||||
|
return NotImplemented
|
||||||
|
|
||||||
|
def __pow__(self, other):
|
||||||
|
if isinstance(other, frac):
|
||||||
|
return float(self) ** float(other)
|
||||||
|
elif isinstance(other, (int, long)):
|
||||||
|
return frac(self.num ** other, self.den ** other)
|
||||||
|
elif isinstance(other, float):
|
||||||
|
return float(self) ** other
|
||||||
|
else:
|
||||||
|
return NotImplemented
|
||||||
|
|
||||||
|
def __rpow__(self, other):
|
||||||
|
if isinstance(other, frac):
|
||||||
|
return float(other) ** float(self)
|
||||||
|
elif isinstance(other, (int, long)):
|
||||||
|
return other ** float(self)
|
||||||
|
elif isinstance(other, float):
|
||||||
|
return other ** float(self)
|
||||||
|
else:
|
||||||
|
return NotImplemented
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
if isinstance(other, frac):
|
||||||
|
return self.num * other.den < other.num * self.den
|
||||||
|
else:
|
||||||
|
return float(self) < other
|
||||||
|
|
||||||
|
def __le__(self, other):
|
||||||
|
if isinstance(other, frac):
|
||||||
|
return self.num * other.den <= other.num * self.den
|
||||||
|
else:
|
||||||
|
return float(self) <= other
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if isinstance(other, frac):
|
||||||
|
return self.num * other.den == other.num * self.den
|
||||||
|
else:
|
||||||
|
return float(self) == other
|
||||||
|
|
||||||
|
def reduce(self):
|
||||||
|
pass
|
||||||
Reference in New Issue
Block a user