Kaydet (Commit) 3c286e2e authored tarafından Mark Dickinson's avatar Mark Dickinson

Issue #21136: Avoid unnecessary normalization in Fractions resulting from power…

Issue #21136: Avoid unnecessary normalization in Fractions resulting from power and other operations.
üst 2a322008
...@@ -70,7 +70,7 @@ class Fraction(numbers.Rational): ...@@ -70,7 +70,7 @@ class Fraction(numbers.Rational):
__slots__ = ('_numerator', '_denominator') __slots__ = ('_numerator', '_denominator')
# We're immutable, so use __new__ not __init__ # 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. """Constructs a Rational.
Takes a string like '3/2' or '1.5', another Rational instance, a Takes a string like '3/2' or '1.5', another Rational instance, a
...@@ -165,9 +165,12 @@ class Fraction(numbers.Rational): ...@@ -165,9 +165,12 @@ class Fraction(numbers.Rational):
if denominator == 0: if denominator == 0:
raise ZeroDivisionError('Fraction(%s, 0)' % numerator) raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
if _normalize:
g = gcd(numerator, denominator) g = gcd(numerator, denominator)
self._numerator = numerator // g numerator //= g
self._denominator = denominator // g denominator //= g
self._numerator = numerator
self._denominator = denominator
return self return self
@classmethod @classmethod
...@@ -453,10 +456,12 @@ class Fraction(numbers.Rational): ...@@ -453,10 +456,12 @@ class Fraction(numbers.Rational):
power = b.numerator power = b.numerator
if power >= 0: if power >= 0:
return Fraction(a._numerator ** power, return Fraction(a._numerator ** power,
a._denominator ** power) a._denominator ** power,
_normalize=False)
else: else:
return Fraction(a._denominator ** -power, return Fraction(a._denominator ** -power,
a._numerator ** -power) a._numerator ** -power,
_normalize=False)
else: else:
# A fractional power will generally produce an # A fractional power will generally produce an
# irrational number. # irrational number.
...@@ -480,15 +485,15 @@ class Fraction(numbers.Rational): ...@@ -480,15 +485,15 @@ class Fraction(numbers.Rational):
def __pos__(a): def __pos__(a):
"""+a: Coerces a subclass instance to Fraction""" """+a: Coerces a subclass instance to Fraction"""
return Fraction(a._numerator, a._denominator) return Fraction(a._numerator, a._denominator, _normalize=False)
def __neg__(a): def __neg__(a):
"""-a""" """-a"""
return Fraction(-a._numerator, a._denominator) return Fraction(-a._numerator, a._denominator, _normalize=False)
def __abs__(a): def __abs__(a):
"""abs(a)""" """abs(a)"""
return Fraction(abs(a._numerator), a._denominator) return Fraction(abs(a._numerator), a._denominator, _normalize=False)
def __trunc__(a): def __trunc__(a):
"""trunc(a)""" """trunc(a)"""
......
...@@ -330,7 +330,6 @@ class FractionTest(unittest.TestCase): ...@@ -330,7 +330,6 @@ class FractionTest(unittest.TestCase):
self.assertTypedEquals(F(-2, 10), round(F(-15, 100), 1)) self.assertTypedEquals(F(-2, 10), round(F(-15, 100), 1))
self.assertTypedEquals(F(-2, 10), round(F(-25, 100), 1)) self.assertTypedEquals(F(-2, 10), round(F(-25, 100), 1))
def testArithmetic(self): def testArithmetic(self):
self.assertEqual(F(1, 2), F(1, 10) + F(2, 5)) self.assertEqual(F(1, 2), F(1, 10) + F(2, 5))
self.assertEqual(F(-3, 10), F(1, 10) - F(2, 5)) self.assertEqual(F(-3, 10), F(1, 10) - F(2, 5))
...@@ -402,6 +401,8 @@ class FractionTest(unittest.TestCase): ...@@ -402,6 +401,8 @@ class FractionTest(unittest.TestCase):
self.assertTypedEquals(2.0 , 4 ** F(1, 2)) self.assertTypedEquals(2.0 , 4 ** F(1, 2))
self.assertTypedEquals(0.25, 2.0 ** F(-2, 1)) self.assertTypedEquals(0.25, 2.0 ** F(-2, 1))
self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** F(1, 10)) self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** F(1, 10))
self.assertRaises(ZeroDivisionError, operator.pow,
F(0, 1), -2)
def testMixingWithDecimal(self): def testMixingWithDecimal(self):
# Decimal refuses mixed arithmetic (but not mixed comparisons) # Decimal refuses mixed arithmetic (but not mixed comparisons)
......
...@@ -29,6 +29,9 @@ Core and Builtins ...@@ -29,6 +29,9 @@ Core and Builtins
Library Library
------- -------
- Issue #21136: Avoid unnecessary normalization of Fractions resulting from
power and other operations. Patch by Raymond Hettinger.
- Issue #17621: Introduce importlib.util.LazyLoader. - Issue #17621: Introduce importlib.util.LazyLoader.
- Issue #21076: signal module constants were turned into enums. - Issue #21076: signal module constants were turned into enums.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment