Update the py3k version of the rational module to expose only methods needed by

py3k (i.e., no __div__) and use py3k functions like math.floor().
This commit is contained in:
Jeffrey Yasskin 2008-01-17 07:36:30 +00:00
parent 35641461db
commit 9893de1b83
3 changed files with 20 additions and 53 deletions

View File

@ -5,7 +5,6 @@
TODO: Fill out more detailed documentation on the operators.""" TODO: Fill out more detailed documentation on the operators."""
from __future__ import division
from abc import ABCMeta, abstractmethod, abstractproperty from abc import ABCMeta, abstractmethod, abstractproperty
__all__ = ["Number", "Exact", "Inexact", __all__ = ["Number", "Exact", "Inexact",
@ -62,8 +61,7 @@ class Complex(Number):
def __complex__(self): def __complex__(self):
"""Return a builtin complex instance. Called for complex(self).""" """Return a builtin complex instance. Called for complex(self)."""
# Will be __bool__ in 3.0. def __bool__(self):
def __nonzero__(self):
"""True if self != 0. Called for bool(self).""" """True if self != 0. Called for bool(self)."""
return self != 0 return self != 0
@ -121,30 +119,14 @@ class Complex(Number):
"""other * self""" """other * self"""
raise NotImplementedError raise NotImplementedError
@abstractmethod
def __div__(self, other):
"""self / other without __future__ division
May promote to float.
"""
raise NotImplementedError
@abstractmethod
def __rdiv__(self, other):
"""other / self without __future__ division"""
raise NotImplementedError
@abstractmethod @abstractmethod
def __truediv__(self, other): def __truediv__(self, other):
"""self / other with __future__ division. """self / other: Should promote to float when necessary."""
Should promote to float when necessary.
"""
raise NotImplementedError raise NotImplementedError
@abstractmethod @abstractmethod
def __rtruediv__(self, other): def __rtruediv__(self, other):
"""other / self with __future__ division""" """other / self"""
raise NotImplementedError raise NotImplementedError
@abstractmethod @abstractmethod

View File

@ -3,7 +3,6 @@
"""Rational, infinite-precision, real numbers.""" """Rational, infinite-precision, real numbers."""
from __future__ import division
import math import math
import numbers import numbers
import operator import operator
@ -203,28 +202,14 @@ class Rational(RationalAbc):
a.denominator * b.numerator) a.denominator * b.numerator)
__truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv) __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)
__div__, __rdiv__ = _operator_fallbacks(_div, operator.truediv)
@classmethod
def _floordiv(cls, a, b):
div = a / b
if isinstance(div, RationalAbc):
# trunc(math.floor(div)) doesn't work if the rational is
# more precise than a float because the intermediate
# rounding may cross an integer boundary.
return div.numerator // div.denominator
else:
return math.floor(div)
def __floordiv__(a, b): def __floordiv__(a, b):
"""a // b""" """a // b"""
# Will be math.floor(a / b) in 3.0. return math.floor(a / b)
return a._floordiv(a, b)
def __rfloordiv__(b, a): def __rfloordiv__(b, a):
"""a // b""" """a // b"""
# Will be math.floor(a / b) in 3.0. return math.floor(a / b)
return b._floordiv(a, b)
@classmethod @classmethod
def _mod(cls, a, b): def _mod(cls, a, b):
@ -324,11 +309,11 @@ class Rational(RationalAbc):
shift = 10**abs(ndigits) shift = 10**abs(ndigits)
# See _operator_fallbacks.forward to check that the results of # See _operator_fallbacks.forward to check that the results of
# these operations will always be Rational and therefore have # these operations will always be Rational and therefore have
# __round__(). # round().
if ndigits > 0: if ndigits > 0:
return Rational((self * shift).__round__(), shift) return Rational(round(self * shift), shift)
else: else:
return Rational((self / shift).__round__() * shift) return Rational(round(self / shift) * shift)
def __hash__(self): def __hash__(self):
"""hash(self) """hash(self)

View File

@ -74,14 +74,14 @@ class RationalTest(unittest.TestCase):
def testConversions(self): def testConversions(self):
self.assertTypedEquals(-1, trunc(R(-11, 10))) self.assertTypedEquals(-1, trunc(R(-11, 10)))
self.assertTypedEquals(-2, R(-11, 10).__floor__()) self.assertTypedEquals(-2, math.floor(R(-11, 10)))
self.assertTypedEquals(-1, R(-11, 10).__ceil__()) self.assertTypedEquals(-1, math.ceil(R(-11, 10)))
self.assertTypedEquals(-1, R(-10, 10).__ceil__()) self.assertTypedEquals(-1, math.ceil(R(-10, 10)))
self.assertTypedEquals(0, R(-1, 10).__round__()) self.assertTypedEquals(0, round(R(-1, 10)))
self.assertTypedEquals(0, R(-5, 10).__round__()) self.assertTypedEquals(0, round(R(-5, 10)))
self.assertTypedEquals(-2, R(-15, 10).__round__()) self.assertTypedEquals(-2, round(R(-15, 10)))
self.assertTypedEquals(-1, R(-7, 10).__round__()) self.assertTypedEquals(-1, round(R(-7, 10)))
self.assertEquals(False, bool(R(0, 1))) self.assertEquals(False, bool(R(0, 1)))
self.assertEquals(True, bool(R(3, 2))) self.assertEquals(True, bool(R(3, 2)))
@ -96,11 +96,11 @@ class RationalTest(unittest.TestCase):
self.assertTypedEquals(0.1+0j, complex(R(1,10))) self.assertTypedEquals(0.1+0j, complex(R(1,10)))
def testRound(self): def testRound(self):
self.assertTypedEquals(R(-200), R(-150).__round__(-2)) self.assertTypedEquals(R(-200), round(R(-150), -2))
self.assertTypedEquals(R(-200), R(-250).__round__(-2)) self.assertTypedEquals(R(-200), round(R(-250), -2))
self.assertTypedEquals(R(30), R(26).__round__(-1)) self.assertTypedEquals(R(30), round(R(26), -1))
self.assertTypedEquals(R(-2, 10), R(-15, 100).__round__(1)) self.assertTypedEquals(R(-2, 10), round(R(-15, 100), 1))
self.assertTypedEquals(R(-2, 10), R(-25, 100).__round__(1)) self.assertTypedEquals(R(-2, 10), round(R(-25, 100), 1))
def testArithmetic(self): def testArithmetic(self):