问题
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 quotientx / y
. Ifx / y
is exactly halfway between two consecutive integers, the nearest even integer is used forn
. The remainderr = remainder(x, y)
thus always satisfiesabs(r) <= 0.5 * abs(y)
.Special cases follow IEEE 754: in particular,
remainder(x, math.inf)
is x for any finite x, andremainder(x, 0)
andremainder(math.inf, x)
raiseValueError
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.
回答1:
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 quotientx / y
. Ifx / y
is exactly halfway between two consecutive integers, the nearest even integer is used for n. The remainderr = remainder(x, y)
thus always satisfiesabs(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
回答2:
Thanks to @MaartenFabré, I wasn't being attentive to details:
math.remainder()
is the differencex - n*y
, wheren
is the closest integer to the exact value of the quotientx / y
I built Python 3.7:
Python 3.7.0a0 (heads/master:f34c685020, May 8 2017, 15:35:30)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import math
And here are differences:
Zero as divisor:
>>> math.remainder(1, 0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math domain error
>>> 1 % 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
Basic numbers, where math.remainder(x, y) < x % y
>>> math.remainder(5, 3)
-1.0
>>> 5 % 3
2
Complex numbers:
>>> math.remainder(3j + 2, 4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't convert complex to float
>>> (3j + 2) % 4
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't mod complex numbers.
Infinity(math.inf
)
>>> math.remainder(3, math.inf)
3.0
>>> 3 % math.inf
3.0
>>> math.remainder(math.inf, 3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math domain error
>>> math.inf % 3
nan
来源:https://stackoverflow.com/questions/43845375/difference-between-python-3-7-math-remainder-and-modulo-operator