summaryrefslogtreecommitdiff
path: root/Lib/fractions.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/fractions.py')
-rw-r--r--Lib/fractions.py50
1 files changed, 33 insertions, 17 deletions
diff --git a/Lib/fractions.py b/Lib/fractions.py
index 79e83ff2c0..5ddc84c1a5 100644
--- a/Lib/fractions.py
+++ b/Lib/fractions.py
@@ -70,7 +70,7 @@ class Fraction(numbers.Rational):
__slots__ = ('_numerator', '_denominator')
# We're immutable, so use __new__ not __init__
- def __new__(cls, numerator=0, denominator=None):
+ def __new__(cls, numerator=0, denominator=None, _normalize=True):
"""Constructs a Rational.
Takes a string like '3/2' or '1.5', another Rational instance, a
@@ -104,7 +104,12 @@ class Fraction(numbers.Rational):
self = super(Fraction, cls).__new__(cls)
if denominator is None:
- if isinstance(numerator, numbers.Rational):
+ if type(numerator) is int:
+ self._numerator = numerator
+ self._denominator = 1
+ return self
+
+ elif isinstance(numerator, numbers.Rational):
self._numerator = numerator.numerator
self._denominator = numerator.denominator
return self
@@ -153,6 +158,9 @@ class Fraction(numbers.Rational):
raise TypeError("argument should be a string "
"or a Rational instance")
+ elif type(numerator) is int is type(denominator):
+ pass # *very* normal case
+
elif (isinstance(numerator, numbers.Rational) and
isinstance(denominator, numbers.Rational)):
numerator, denominator = (
@@ -165,9 +173,12 @@ class Fraction(numbers.Rational):
if denominator == 0:
raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
- g = gcd(numerator, denominator)
- self._numerator = numerator // g
- self._denominator = denominator // g
+ if _normalize:
+ g = gcd(numerator, denominator)
+ numerator //= g
+ denominator //= g
+ self._numerator = numerator
+ self._denominator = denominator
return self
@classmethod
@@ -277,7 +288,8 @@ class Fraction(numbers.Rational):
def __repr__(self):
"""repr(self)"""
- return ('Fraction(%s, %s)' % (self._numerator, self._denominator))
+ return '%s(%s, %s)' % (self.__class__.__name__,
+ self._numerator, self._denominator)
def __str__(self):
"""str(self)"""
@@ -395,17 +407,17 @@ class Fraction(numbers.Rational):
def _add(a, b):
"""a + b"""
- return Fraction(a.numerator * b.denominator +
- b.numerator * a.denominator,
- a.denominator * b.denominator)
+ da, db = a.denominator, b.denominator
+ return Fraction(a.numerator * db + b.numerator * da,
+ da * db)
__add__, __radd__ = _operator_fallbacks(_add, operator.add)
def _sub(a, b):
"""a - b"""
- return Fraction(a.numerator * b.denominator -
- b.numerator * a.denominator,
- a.denominator * b.denominator)
+ da, db = a.denominator, b.denominator
+ return Fraction(a.numerator * db - b.numerator * da,
+ da * db)
__sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)
@@ -453,10 +465,12 @@ class Fraction(numbers.Rational):
power = b.numerator
if power >= 0:
return Fraction(a._numerator ** power,
- a._denominator ** power)
+ a._denominator ** power,
+ _normalize=False)
else:
return Fraction(a._denominator ** -power,
- a._numerator ** -power)
+ a._numerator ** -power,
+ _normalize=False)
else:
# A fractional power will generally produce an
# irrational number.
@@ -480,15 +494,15 @@ class Fraction(numbers.Rational):
def __pos__(a):
"""+a: Coerces a subclass instance to Fraction"""
- return Fraction(a._numerator, a._denominator)
+ return Fraction(a._numerator, a._denominator, _normalize=False)
def __neg__(a):
"""-a"""
- return Fraction(-a._numerator, a._denominator)
+ return Fraction(-a._numerator, a._denominator, _normalize=False)
def __abs__(a):
"""abs(a)"""
- return Fraction(abs(a._numerator), a._denominator)
+ return Fraction(abs(a._numerator), a._denominator, _normalize=False)
def __trunc__(a):
"""trunc(a)"""
@@ -555,6 +569,8 @@ class Fraction(numbers.Rational):
def __eq__(a, b):
"""a == b"""
+ if type(b) is int:
+ return a._numerator == b and a._denominator == 1
if isinstance(b, numbers.Rational):
return (a._numerator == b.numerator and
a._denominator == b.denominator)