5

Python 3.7 中的新增功能 我们可以看到有新的math.remainder. 它说

返回 x 相对于 y 的 IEEE 754 样式余数。对于有限 x 和有限非零 y,这是差x - n*y,其中 n 是最接近商的精确值的整数x / y。如果x / y恰好在两个连续整数之间,则使用最接近的偶数n。余数r = remainder(x, y)因此总是满足的abs(r) <= 0.5 * abs(y)

特殊情况遵循 IEEE 754:特别是,remainder(x, math.inf)对于任何有限 x,is x,对于任何非 NaN x , remainder(x, 0)and remainder(math.inf, x)raise 。ValueError如果余数运算的结果为零,则该零的符号与 x 相同。

在使用 IEEE 754 二进制浮点的平台上,此操作的结果始终可以精确表示:不引入舍入误差。

但我们也记得有一个%符号是

剩余的x / y

我们还看到操作员有一条注释:

不适用于复数。abs()而是在适当的情况下转换为浮点数。

如果可能的话,我还没有尝试过运行 Python 3.7。

但我试过了

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

所以不同的是,而不是nan我们ZeroDivisionError会得到ValueError文档中所说的那样。

%所以问题是和有什么区别math.remaindermath.remainder也可以处理复数(%缺少它)?主要优势是什么?

这是来自官方 CPython github repo的来源。math.remainder

4

2 回答 2

5

返回 x 相对于 y 的 IEEE 754 样式余数。对于有限 x 和有限非零 y,这是差x - n*y,其中 n 是最接近商的精确值的整数x / y。如果x / y恰好在两个连续整数之间,则使用最接近的偶数作为 n。余数r = remainder(x, y)因此总是满足的abs(r) <= 0.5 * abs(y)

对于模数,这是的m = x - n*y位置,所以不是余数。nfloor(x/y)0 <= m < yabs(r) <= 0.5 * abs(y)

所以

modulo(2.7, 1) = 0.7
remainder(2.7, 1) = -0.3
于 2017-05-08T13:14:03.537 回答
0

感谢@MaartenFabré,我没有注意细节:

math.remainder()是差x - n*y,其中n是最接近商的精确值的整数x / y

我构建了 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

以下是不同之处:

零作为除数:

>>> 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

基本数字,其中math.remainder(x, y) < x % y

>>> math.remainder(5, 3)
-1.0
>>> 5 % 3
2

复数:

>>> 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.

无穷大( 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
于 2017-05-08T13:43:04.000 回答