Difference between Python 3.7 math.remainder and %(modulo operator)

cpython, math, python, python-3.7

Solution

Return the IEEE 754-style remainder of x with respect to y. For finite x and finite nonzero y, this is the difference `x - n*y`, where n is the closest integer to the exact value of the quotient `x / y`. If `x / y` is exactly halfway between two consecutive integers, the nearest even integer is used for n. The remainder `r = remainder(x, y)` thus always satisfies `abs(r) <= 0.5 * abs(y)`.

for the modulo this is `m = x - n*y` where `n` is the `floor(x/y)`, so `0 <= m < y` instead of `abs(r) <= 0.5 * abs(y)` for the remainder.

so

modulo(2.7, 1) = 0.7
remainder(2.7, 1) = -0.3

Problem

From What’s New In Python 3.7 we can see that there is new `math.remainder`. It says Return the IEEE 754-style remainder of x with respect to y. For finite x and finite nonzero y, this is the difference `x - n*y`, where n is the closest integer to the exact value of the quotient `x / y`. If `x / y` is exactly halfway between two consecutive integers, the nearest even integer is used for `n`. The remainder `r = remainder(x, y)` thus always satisfies `abs(r) <= 0.5 * abs(y)`. Special cases follow IEEE 754: in particular, `remainder(x, math.inf)` is x for any finite x, and `remainder(x, 0)` and `remainder(math.inf, x)` raise `ValueError` for any non-NaN x. If the result of the remainder operation is zero, that zero will have the same sign as x. On platforms using IEEE 754 binary floating-point, the result of this operation is always exactly representable: no rounding error is introduced. But we also remember that there is `%` symbol which is remainder of `x / y` We also see that there is a note to operator: Not for complex numbers. Instead convert to floats using `abs()` if appropriate. I haven't tried to run Python 3.7 if it's even possible. But i tried ``` Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04) [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import math >>> 100 % math.inf 100.0 >>> math.inf % 100 nan >>> 100 % 0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: integer division or modulo by zero ``` So difference would be, instead of `nan` and `ZeroDivisionError` we would get `ValueError` as it says in docs. So the question is what is the difference between `%` and `math.remainder`? Would `math.remainder` also work with complex numbers(`%` lacks from it)? What is the main advantage? Here is the source of `math.remainder` from official CPython github repo.

Original source