commit 12e8cd63852d8b0bf40be1cf51e153778f02bc34 Author: Cameron Neville Date: Sat Sep 16 00:52:00 2017 -0400 first commit diff --git a/frac.py b/frac.py new file mode 100644 index 0000000..90d4754 --- /dev/null +++ b/frac.py @@ -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 \ No newline at end of file