Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 815
vishes_shell Avatar asked May 08 '17 10:05

vishes_shell


1 Answers

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
like image 139
Maarten Fabré Avatar answered Sep 19 '22 18:09

Maarten Fabré