@@ -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,7 +312,19 @@ 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."""
@@ -380,9 +391,9 @@ def limit_denominator(self, max_denominator=1000000):
380
391
# the distance from p1/q1 to self is d/(q1*self._denominator). So we
381
392
# need to compare 2*(q0+k*q1) with self._denominator/d.
382
393
if 2 * d * (q0 + k * q1 ) <= self ._denominator :
383
- return Fraction (p1 , q1 , _normalize = False )
394
+ return Fraction . _from_coprime_ints (p1 , q1 )
384
395
else :
385
- return Fraction (p0 + k * p1 , q0 + k * q1 , _normalize = False )
396
+ return Fraction . _from_coprime_ints (p0 + k * p1 , q0 + k * q1 )
386
397
387
398
@property
388
399
def numerator (a ):
@@ -703,13 +714,13 @@ def _add(a, b):
703
714
nb , db = b ._numerator , b ._denominator
704
715
g = math .gcd (da , db )
705
716
if g == 1 :
706
- return Fraction (na * db + da * nb , da * db , _normalize = False )
717
+ return Fraction . _from_coprime_ints (na * db + da * nb , da * db )
707
718
s = da // g
708
719
t = na * (db // g ) + nb * s
709
720
g2 = math .gcd (t , g )
710
721
if g2 == 1 :
711
- return Fraction (t , s * db , _normalize = False )
712
- return Fraction (t // g2 , s * (db // g2 ), _normalize = False )
722
+ return Fraction . _from_coprime_ints (t , s * db )
723
+ return Fraction . _from_coprime_ints (t // g2 , s * (db // g2 ))
713
724
714
725
__add__ , __radd__ = _operator_fallbacks (_add , operator .add )
715
726
@@ -719,13 +730,13 @@ def _sub(a, b):
719
730
nb , db = b ._numerator , b ._denominator
720
731
g = math .gcd (da , db )
721
732
if g == 1 :
722
- return Fraction (na * db - da * nb , da * db , _normalize = False )
733
+ return Fraction . _from_coprime_ints (na * db - da * nb , da * db )
723
734
s = da // g
724
735
t = na * (db // g ) - nb * s
725
736
g2 = math .gcd (t , g )
726
737
if g2 == 1 :
727
- return Fraction (t , s * db , _normalize = False )
728
- return Fraction (t // g2 , s * (db // g2 ), _normalize = False )
738
+ return Fraction . _from_coprime_ints (t , s * db )
739
+ return Fraction . _from_coprime_ints (t // g2 , s * (db // g2 ))
729
740
730
741
__sub__ , __rsub__ = _operator_fallbacks (_sub , operator .sub )
731
742
@@ -741,15 +752,17 @@ def _mul(a, b):
741
752
if g2 > 1 :
742
753
nb //= g2
743
754
da //= g2
744
- return Fraction (na * nb , db * da , _normalize = False )
755
+ return Fraction . _from_coprime_ints (na * nb , db * da )
745
756
746
757
__mul__ , __rmul__ = _operator_fallbacks (_mul , operator .mul )
747
758
748
759
def _div (a , b ):
749
760
"""a / b"""
750
761
# Same as _mul(), with inversed b.
751
- na , da = a ._numerator , a ._denominator
752
762
nb , db = b ._numerator , b ._denominator
763
+ if nb == 0 :
764
+ raise ZeroDivisionError ('Fraction(%s, 0)' % db )
765
+ na , da = a ._numerator , a ._denominator
753
766
g1 = math .gcd (na , nb )
754
767
if g1 > 1 :
755
768
na //= g1
@@ -761,7 +774,7 @@ def _div(a, b):
761
774
n , d = na * db , nb * da
762
775
if d < 0 :
763
776
n , d = - n , - d
764
- return Fraction (n , d , _normalize = False )
777
+ return Fraction . _from_coprime_ints (n , d )
765
778
766
779
__truediv__ , __rtruediv__ = _operator_fallbacks (_div , operator .truediv )
767
780
@@ -798,17 +811,17 @@ def __pow__(a, b):
798
811
if b .denominator == 1 :
799
812
power = b .numerator
800
813
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 )
814
+ return Fraction ._from_coprime_ints (a ._numerator ** power ,
815
+ a ._denominator ** power )
816
+ elif a ._numerator > 0 :
817
+ return Fraction ._from_coprime_ints (a ._denominator ** - power ,
818
+ a ._numerator ** - power )
819
+ elif a ._numerator == 0 :
820
+ raise ZeroDivisionError ('Fraction(%s, 0)' %
821
+ a ._denominator ** - power )
808
822
else :
809
- return Fraction ((- a ._denominator ) ** - power ,
810
- (- a ._numerator ) ** - power ,
811
- _normalize = False )
823
+ return Fraction ._from_coprime_ints ((- a ._denominator ) ** - power ,
824
+ (- a ._numerator ) ** - power )
812
825
else :
813
826
# A fractional power will generally produce an
814
827
# irrational number.
@@ -832,15 +845,15 @@ def __rpow__(b, a):
832
845
833
846
def __pos__ (a ):
834
847
"""+a: Coerces a subclass instance to Fraction"""
835
- return Fraction (a ._numerator , a ._denominator , _normalize = False )
848
+ return Fraction . _from_coprime_ints (a ._numerator , a ._denominator )
836
849
837
850
def __neg__ (a ):
838
851
"""-a"""
839
- return Fraction (- a ._numerator , a ._denominator , _normalize = False )
852
+ return Fraction . _from_coprime_ints (- a ._numerator , a ._denominator )
840
853
841
854
def __abs__ (a ):
842
855
"""abs(a)"""
843
- return Fraction (abs (a ._numerator ), a ._denominator , _normalize = False )
856
+ return Fraction . _from_coprime_ints (abs (a ._numerator ), a ._denominator )
844
857
845
858
def __int__ (a , _index = operator .index ):
846
859
"""int(a)"""
0 commit comments