5

在 Python 文档中,它说“ %(模)运算符从第一个参数除以第二个参数产生余数。

所以给定

a % b

据我所知,余数是 A 除以 B 所剩下的数。所以 21 % 3 = 0,-25 % 23 = -2。我不明白的是,当 A 为负数时会发生什么。

例如,

-23 % 22

会产生

21

这是第一个模-1全等的正整数。但是 -1 是 -23 % 22 的余数。那么文档有误吗?Python 中的模运算符 % 不会产生 a % b 中的余数,而是产生与 B 模一致的第一个正整数?我很混乱。

4

2 回答 2

10

有三种不同的明显方式来定义对负数的整数除法,以及三种相应的方式来定义余数:

  • 底除法,其中商向负无穷大下底,余数与除数具有相同的符号。
  • 截断除法,其中商向零截断,余数与被除数相同。
  • 欧几里得除法,其中商在任何方向上被截断,余数为正。

所有这三个都保留了整数除法的基本定律:

dividend = divisor * quotient + remainder

所以,这三个都不是“正确”或“错误”。*

当然,这并不能阻止人们进行圣战。Knuth 以“数学上正确”为基础,主张使用底除法。Wirth 主张截断除法,因为它“不那么令人惊讶”。Raymond Boute 认为整数除法是根据欧几里得算法定义的。我不会试图通过争论他们三个人(包括该领域最重要的两个人)都是错误的来解决一场长达数十年的圣战……

某些语言通过具有两种不同的功能来解决此问题。**

假设 Python 采用了 Knuth 的定义,所以它的模运算符有除数的符号。


* 当然,选择商和余数的不匹配定义是另一回事。或者,更糟糕的是,指定一个并保留另一个实现定义,就像 C 在 C99 之前所做的那样。

** 这特别有趣,因为他们并不总是一致地知道哪个是哪个。至少当它们被称为remand时modrem是与 一起出现的那个div,而当它们被称为and或and时,mod无论是 floored 还是 Euclidean 都不匹配……</p> divremremaindermodmodulo

于 2013-10-10T01:23:30.497 回答
0

如果将 -23 除以 22,则得到 -23 = -2 * 22 + 21。在 Python 中,“余数”始终介于 0 和除数之间(但不等于除数)。对于正除数,商和模数通常在数学中定义。在某些编程语言中,负余数与正除数一起使用,但在 Python 中不使用。

于 2013-10-10T01:24:59.570 回答