Skip to content

Commit

Permalink
bpo-32968: Make modulo and floor division involving Fraction and floa…
Browse files Browse the repository at this point in the history
…t consistent with other operations (#5956)

Make mixed-type `%` and `//` operations involving `Fraction` and `float` objects behave like all other mixed-type arithmetic operations: first the `Fraction` object is converted to a `float`, then the `float` operation is performed as normal. This fixes some surprising corner cases, like `Fraction('1/3') % inf` giving a NaN.

Thanks Elias Zamaria for the patch.
  • Loading branch information
elias6 authored and mdickinson committed Aug 27, 2018
1 parent 74734f7 commit 393f1ff
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 12 deletions.
13 changes: 4 additions & 9 deletions Lib/fractions.py
Expand Up @@ -427,23 +427,18 @@ def _div(a, b):

__truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)

def __floordiv__(a, b):
def _floordiv(a, b):
"""a // b"""
return math.floor(a / b)

def __rfloordiv__(b, a):
"""a // b"""
return math.floor(a / b)
__floordiv__, __rfloordiv__ = _operator_fallbacks(_floordiv, operator.floordiv)

def __mod__(a, b):
def _mod(a, b):
"""a % b"""
div = a // b
return a - b * div

def __rmod__(b, a):
"""a % b"""
div = a // b
return a - b * div
__mod__, __rmod__ = _operator_fallbacks(_mod, operator.mod)

def __pow__(a, b):
"""a ** b
Expand Down
10 changes: 7 additions & 3 deletions Lib/test/test_fractions.py
Expand Up @@ -401,15 +401,19 @@ def testMixedArithmetic(self):
self.assertTypedEquals(10.0 + 0j, (1.0 + 0j) / F(1, 10))

self.assertTypedEquals(0, F(1, 10) // 1)
self.assertTypedEquals(0, F(1, 10) // 1.0)
self.assertTypedEquals(0.0, F(1, 10) // 1.0)
self.assertTypedEquals(10, 1 // F(1, 10))
self.assertTypedEquals(10**23, 10**22 // F(1, 10))
self.assertTypedEquals(10, 1.0 // F(1, 10))
self.assertTypedEquals(1.0 // 0.1, 1.0 // F(1, 10))

self.assertTypedEquals(F(1, 10), F(1, 10) % 1)
self.assertTypedEquals(0.1, F(1, 10) % 1.0)
self.assertTypedEquals(F(0, 1), 1 % F(1, 10))
self.assertTypedEquals(0.0, 1.0 % F(1, 10))
self.assertTypedEquals(1.0 % 0.1, 1.0 % F(1, 10))
self.assertTypedEquals(0.1, F(1, 10) % float('inf'))
self.assertTypedEquals(float('-inf'), F(1, 10) % float('-inf'))
self.assertTypedEquals(float('inf'), F(-1, 10) % float('inf'))
self.assertTypedEquals(-0.1, F(-1, 10) % float('-inf'))

# No need for divmod since we don't override it.

Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Expand Up @@ -1814,6 +1814,7 @@ Masazumi Yoshikawa
Arnaud Ysmal
Bernard Yue
Moshe Zadka
Elias Zamaria
Milan Zamazal
Artur Zaprzala
Mike Zarnstorff
Expand Down
@@ -0,0 +1 @@
Modulo and floor division involving Fraction and float should return float.

0 comments on commit 393f1ff

Please sign in to comment.