欧几里得的定义说,
\n\n\n\n\n给定两个整数 a 和 b,且 b \xe2\x89\xa0 0,存在唯一整数 q 和 r,使得 a = bq + r 且 0 \xe2\x89\xa4 r < |b|,其中 |b| 表示b的绝对值。
\n
根据以下观察,
\n\n>>> -3 % -2 # Ideally it should be (-2 * 2) + 1\n-1\n>>> -3 % 2 # this looks fine, (-2 * 2) + 1 \n1\n>>> 2 % -3 # Ideally it should be (-3 * 0) + 2\n-1\nRun Code Online (Sandbox Code Playgroud)\n\n看起来%运营商正在按照不同的规则运行。
我的问题:
\n\n我如何理解Python中模运算符的行为?我不知道有关%操作员工作的任何其他语言。
The History of Python的一篇文章解释了整数除法和模运算的行为,即:Why Python's Integer Division Floors。我将引用相关部分:
如果其中一个操作数为负,则结果取整,即从零开始舍入(向负无穷大舍入):
Run Code Online (Sandbox Code Playgroud)>>> -5//2 -3 >>> 5//-2 -3这让一些人感到不安,但有一个很好的数学原因。整数除法运算 (
//) 及其兄弟模运算 (%) 一起满足良好的数学关系(所有变量都是整数):
a/b = q与余数r这样
b*q + r = a和0 <= r < b(假设
a和b是>= 0)。如果你想让关系延伸为负数
a(保持b正数),你有两种选择:如果你q向零截断,r就会变成负数,这样不变量就变成了,0 <= abs(r)否则,你可以q向负无穷大下降,不变量仍然是0 <= r < b。在数学数论中,数学家总是更喜欢后者(参见维基百科)。对于 Python,我做出了同样的选择,因为有一些有趣的模运算应用,其中 a 的符号并不有趣。[...] 顺便说一句,对于负 b,一切都会翻转,不变量变为:
Run Code Online (Sandbox Code Playgroud)0 >= r > b.
换句话说,Python 决定在某些情况下打破欧几里得定义,以便在有趣的情况下获得更好的行为。特别是负面的a被认为是有趣的,而负面的则不b被认为是有趣的。这是一个完全任意的选择,在语言之间不共享。
请注意,许多常见的编程语言(C,C ++,Java,...)不满足欧几里得不变量,通常比Python更多的情况(例如,即使b是正数)。其中一些甚至不提供有关余数符号的任何保证,将细节保留为实现定义的。
附带说明:Haskell 提供了模数和除法两种类型。标准欧几里得模数和除法称为rem和quot,而落地除法和“Python 风格”模数称为mod和div。
| 归档时间: |
|
| 查看次数: |
1026 次 |
| 最近记录: |