当前位置: 首页 > 知识库问答 >
问题:

为什么Python的模运算符(%)与欧几里德定义不匹配?

华佐
2023-03-14

欧几里德的定义是,

给定两个整数a和b,其中≠ 存在唯一的整数q和r,使得a=bq r和0≤ R

根据以下观察,,

>>> -3 % -2   # Ideally it should be (-2 * 2) + 1
-1
>>> -3 % 2    # this looks fine, (-2 * 2) + 1 
1
>>> 2 % -3    # Ideally it should be (-3 * 0) + 2
-1

看起来%运算符正在使用不同的规则运行。

  • link1没有帮助,
  • link2给出了递归的答案,因为我不理解%是如何工作的,所以很难理解(a//b)*b(a%b)=a是如何工作的

我的问题:

如何理解python中模运算符的行为?我不知道与%操作员工作相关的任何其他语言。

共有1个答案

杨波娃
2023-03-14

整数除法和模运算的行为在Python历史的一篇文章中进行了解释,即:为什么Python的整数除法是最小的。我将引用相关部分:

如果其中一个操作数为负数,则结果为零,即从零开始四舍五入(朝向负无穷大):

>>> -5//2
-3
>>> 5//-2
-3

这让一些人感到不安,但有一个很好的数学原因。整数除法运算(/)及其同级模运算(%)一起进行,并满足一个良好的数学关系(所有变量都是整数):

a/b=q带余数r

这样那样

b*qr=a0

(假设ab

如果希望关系扩展为负值a(保持b为正值),则有两种选择:如果将q截断为零,r将变为负值,从而使不变量变为0

在数学数论中,数学家总是倾向于后一种选择(参见维基百科)。对于Python,我做了同样的选择,因为有一些有趣的模运算应用程序,其中a的符号是无趣的。[...] 对于负b,顺便说一句,所有东西都会翻转,不变量变成:

0 >= r > b.

换句话说,python决定在某些情况下打破欧几里德定义,以便在有趣的情况下获得更好的行为。尤其是负a被认为是有趣的,而负b则不被认为是有趣的。这是一个完全任意的选择,语言之间不共享。

请注意,许多常见编程语言(C、C、Java等)不满足欧几里德不变量,通常在比python更多的情况下(例如,即使b为正)。它们中的一些甚至不提供关于剩余符号的任何保证,将细节留给实现定义。

作为旁注:Haskell提供了两种模块和划分。标准欧几里德模数和除法称为remquot,而底层除法和“python风格”模数称为moddiv

 类似资料:
  • 问题内容: 操作员如何确定两个对象是否相同?它是如何工作的?我找不到记录。 问题答案: 从文档中: 每个对象都有一个标识,一个类型和一个值。一旦创建了对象,其身份就永远不会改变。您可能会认为它是对象在内存中的地址。“ is”运算符比较两个对象的身份;id()函数返回一个表示其身份的整数(当前实现为其地址)。 这似乎表明它在比较参数的内存地址,尽管它说“您可能将其视为对象在内存中的地址”这一事实可能

  • 这个问题基本上是说迭代一个整数,然后计算这个数是否可以被它的左边数整除,如果它可以整除,则返回一个布尔数组。 73312 第一个数字没有左边的数字,所以它是假的 我运行了测试,一切都很好,但是有了这个数字(73312),当它应该返回false时,它会返回true。 预期输出 实际输出

  • 问题内容: 我注意到我可以使用运算符比较所有本机数据类型(整数,字符串,布尔值,浮点数等),还可以比较包含本机数据类型的列表,元组,集合和字典。在这些情况下,操作员将检查两个对象是否相等。但是在某些其他情况下(试图比较我创建的类的实例),该运算符只是检查两个变量是否引用同一对象(因此在这些情况下,该运算符等效于该运算符) 我的问题是:什么时候操作员不只是比较身份? 编辑:我正在使用Python 3

  • 首先,我想问为什么默认三向运算符的行为不同于用户定义运算符? 其次,这个问题的解决方案对于类是正确的,还是应该以不同的方式处理? 这只是一个简单的例子,我想到了更复杂的情况,有几十个字段和联合(如果您不知道我的意思,请查看一些Intel API;))。 我稍微修改了示例中的类,以便更多地描述实际生活中的问题(当默认运算符不是有效的解决方案时)。我还想澄清,我想知道这些差异背后的原因(用户定义和默认

  • 问题内容: 我在3D中有两点: 我想计算距离: 使用NumPy或一般使用Python的最佳方法是什么?我有: 问题答案: 用途 背后的理论:如数据挖掘导论所述 之所以有效,是因为欧几里得距离为l2范数,并且 中ord参数的默认值为2。

  • 在 C (n1570 7.21.6.1/10) 和 C(通过包含 C 标准库)中,向类型与其转换规范不匹配的 printf 提供参数是未定义的行为。一个简单的例子: 格式字符串指定 int,而参数是浮点类型。 这个问题的灵感来自一个用户的问题,他遇到了大量转换不匹配的遗留代码,这显然没有伤害,参见。理论和实践中的未定义行为。 最初,仅仅声明格式不匹配的UB似乎很激烈。很明显,输出可能是错误的,这取