@@ -183,7 +183,7 @@ class Fraction(numbers.Rational):
183
183
__slots__ = ('_numerator' , '_denominator' )
184
184
185
185
# We're immutable, so use __new__ not __init__
186
- def __new__ (cls , numerator = 0 , denominator = None , * , _normalize = True ):
186
+ def __new__ (cls , numerator = 0 , denominator = None ):
187
187
"""Constructs a Rational.
188
188
189
189
Takes a string like '3/2' or '1.5', another Rational instance, a
@@ -279,12 +279,11 @@ def __new__(cls, numerator=0, denominator=None, *, _normalize=True):
279
279
280
280
if denominator == 0 :
281
281
raise ZeroDivisionError ('Fraction(%s, 0)' % numerator )
282
- if _normalize :
283
- g = math .gcd (numerator , denominator )
284
- if denominator < 0 :
285
- g = - g
286
- numerator //= g
287
- denominator //= g
282
+ g = math .gcd (numerator , denominator )
283
+ if denominator < 0 :
284
+ g = - g
285
+ numerator //= g
286
+ denominator //= g
288
287
self ._numerator = numerator
289
288
self ._denominator = denominator
290
289
return self
@@ -301,7 +300,7 @@ def from_float(cls, f):
301
300
elif not isinstance (f , float ):
302
301
raise TypeError ("%s.from_float() only takes floats, not %r (%s)" %
303
302
(cls .__name__ , f , type (f ).__name__ ))
304
- return cls (* f .as_integer_ratio ())
303
+ return cls . _from_coprime_ints (* f .as_integer_ratio ())
305
304
306
305
@classmethod
307
306
def from_decimal (cls , dec ):
@@ -313,17 +312,28 @@ def from_decimal(cls, dec):
313
312
raise TypeError (
314
313
"%s.from_decimal() only takes Decimals, not %r (%s)" %
315
314
(cls .__name__ , dec , type (dec ).__name__ ))
316
- return cls (* dec .as_integer_ratio ())
315
+ return cls ._from_coprime_ints (* dec .as_integer_ratio ())
316
+
317
+ @classmethod
318
+ def _from_coprime_ints (cls , numerator , denominator , / ):
319
+ """Convert a pair of ints to a rational number, for internal use.
320
+
321
+ The ratio of integers should be in lowest terms and the denominator
322
+ should be positive.
323
+ """
324
+ obj = super (Fraction , cls ).__new__ (cls )
325
+ obj ._numerator = numerator
326
+ obj ._denominator = denominator
327
+ return obj
317
328
318
329
def is_integer (self ):
319
330
"""Return True if the Fraction is an integer."""
320
331
return self ._denominator == 1
321
332
322
333
def as_integer_ratio (self ):
323
- """Return the integer ratio as a tuple .
334
+ """Return a pair of integers, whose ratio is equal to the original Fraction .
324
335
325
- Return a tuple of two integers, whose ratio is equal to the
326
- Fraction and with a positive denominator.
336
+ The ratio is in lowest terms and has a positive denominator.
327
337
"""
328
338
return (self ._numerator , self ._denominator )
329
339
@@ -380,9 +390,9 @@ def limit_denominator(self, max_denominator=1000000):
380
390
# the distance from p1/q1 to self is d/(q1*self._denominator). So we
381
391
# need to compare 2*(q0+k*q1) with self._denominator/d.
382
392
if 2 * d * (q0 + k * q1 ) <= self ._denominator :
383
- return Fraction (p1 , q1 , _normalize = False )
393
+ return Fraction . _from_coprime_ints (p1 , q1 )
384
394
else :
385
- return Fraction (p0 + k * p1 , q0 + k * q1 , _normalize = False )
395
+ return Fraction . _from_coprime_ints (p0 + k * p1 , q0 + k * q1 )
386
396
387
397
@property
388
398
def numerator (a ):
@@ -703,13 +713,13 @@ def _add(a, b):
703
713
nb , db = b ._numerator , b ._denominator
704
714
g = math .gcd (da , db )
705
715
if g == 1 :
706
- return Fraction (na * db + da * nb , da * db , _normalize = False )
716
+ return Fraction . _from_coprime_ints (na * db + da * nb , da * db )
707
717
s = da // g
708
718
t = na * (db // g ) + nb * s
709
719
g2 = math .gcd (t , g )
710
720
if g2 == 1 :
711
- return Fraction (t , s * db , _normalize = False )
712
- return Fraction (t // g2 , s * (db // g2 ), _normalize = False )
721
+ return Fraction . _from_coprime_ints (t , s * db )
722
+ return Fraction . _from_coprime_ints (t // g2 , s * (db // g2 ))
713
723
714
724
__add__ , __radd__ = _operator_fallbacks (_add , operator .add )
715
725
@@ -719,13 +729,13 @@ def _sub(a, b):
719
729
nb , db = b ._numerator , b ._denominator
720
730
g = math .gcd (da , db )
721
731
if g == 1 :
722
- return Fraction (na * db - da * nb , da * db , _normalize = False )
732
+ return Fraction . _from_coprime_ints (na * db - da * nb , da * db )
723
733
s = da // g
724
734
t = na * (db // g ) - nb * s
725
735
g2 = math .gcd (t , g )
726
736
if g2 == 1 :
727
- return Fraction (t , s * db , _normalize = False )
728
- return Fraction (t // g2 , s * (db // g2 ), _normalize = False )
737
+ return Fraction . _from_coprime_ints (t , s * db )
738
+ return Fraction . _from_coprime_ints (t // g2 , s * (db // g2 ))
729
739
730
740
__sub__ , __rsub__ = _operator_fallbacks (_sub , operator .sub )
731
741
@@ -741,15 +751,17 @@ def _mul(a, b):
741
751
if g2 > 1 :
742
752
nb //= g2
743
753
da //= g2
744
- return Fraction (na * nb , db * da , _normalize = False )
754
+ return Fraction . _from_coprime_ints (na * nb , db * da )
745
755
746
756
__mul__ , __rmul__ = _operator_fallbacks (_mul , operator .mul )
747
757
748
758
def _div (a , b ):
749
759
"""a / b"""
750
760
# Same as _mul(), with inversed b.
751
- na , da = a ._numerator , a ._denominator
752
761
nb , db = b ._numerator , b ._denominator
762
+ if nb == 0 :
763
+ raise ZeroDivisionError ('Fraction(%s, 0)' % db )
764
+ na , da = a ._numerator , a ._denominator
753
765
g1 = math .gcd (na , nb )
754
766
if g1 > 1 :
755
767
na //= g1
@@ -761,7 +773,7 @@ def _div(a, b):
761
773
n , d = na * db , nb * da
762
774
if d < 0 :
763
775
n , d = - n , - d
764
- return Fraction (n , d , _normalize = False )
776
+ return Fraction . _from_coprime_ints (n , d )
765
777
766
778
__truediv__ , __rtruediv__ = _operator_fallbacks (_div , operator .truediv )
767
779
@@ -798,17 +810,17 @@ def __pow__(a, b):
798
810
if b .denominator == 1 :
799
811
power = b .numerator
800
812
if power >= 0 :
801
- return Fraction (a ._numerator ** power ,
802
- a ._denominator ** power ,
803
- _normalize = False )
804
- elif a ._numerator >= 0 :
805
- return Fraction (a ._denominator ** - power ,
806
- a ._numerator ** - power ,
807
- _normalize = False )
813
+ return Fraction ._from_coprime_ints (a ._numerator ** power ,
814
+ a ._denominator ** power )
815
+ elif a ._numerator > 0 :
816
+ return Fraction ._from_coprime_ints (a ._denominator ** - power ,
817
+ a ._numerator ** - power )
818
+ elif a ._numerator == 0 :
819
+ raise ZeroDivisionError ('Fraction(%s, 0)' %
820
+ a ._denominator ** - power )
808
821
else :
809
- return Fraction ((- a ._denominator ) ** - power ,
810
- (- a ._numerator ) ** - power ,
811
- _normalize = False )
822
+ return Fraction ._from_coprime_ints ((- a ._denominator ) ** - power ,
823
+ (- a ._numerator ) ** - power )
812
824
else :
813
825
# A fractional power will generally produce an
814
826
# irrational number.
@@ -832,15 +844,15 @@ def __rpow__(b, a):
832
844
833
845
def __pos__ (a ):
834
846
"""+a: Coerces a subclass instance to Fraction"""
835
- return Fraction (a ._numerator , a ._denominator , _normalize = False )
847
+ return Fraction . _from_coprime_ints (a ._numerator , a ._denominator )
836
848
837
849
def __neg__ (a ):
838
850
"""-a"""
839
- return Fraction (- a ._numerator , a ._denominator , _normalize = False )
851
+ return Fraction . _from_coprime_ints (- a ._numerator , a ._denominator )
840
852
841
853
def __abs__ (a ):
842
854
"""abs(a)"""
843
- return Fraction (abs (a ._numerator ), a ._denominator , _normalize = False )
855
+ return Fraction . _from_coprime_ints (abs (a ._numerator ), a ._denominator )
844
856
845
857
def __int__ (a , _index = operator .index ):
846
858
"""int(a)"""
0 commit comments