模数为Python中的负红利

时间:2012-04-08 14:28:27

标签: python modulo

正在查看其他答案,我仍然不理解python中负数的模数

例如df的回答

x == (x/y)*y + (x%y)

因此有意义的是(-2)%5 = -2 - (-2/5)* 5 = 3

这不是(-2 - ( - 2/5)* 5)= 0还是我只是疯了? Modulus operation with negatives values - weird thing?

与此相同 negative numbers modulo in python 他从哪里得到-2?

最后,如果该符号取决于股息,为什么负股息与其正股票不具有相同的产出?

例如

的输出
print([8%5,-8%5,4%5,-4%5])

[3, 2, 4, 1]

6 个答案:

答案 0 :(得分:12)

在Python中,modulo是根据两个规则计算的:

  • (a // b) * b + (a % b) == a
  • a % bb具有相同的符号。

将此与整数除法向下舍入(朝向-∞)的事实相结合,并解释所得到的行为。

如果你执行-8 // 5,则得到-1.6向下舍入,即-2。乘以5,你得到-10; 2是你必须添加到的数字才能获得-8。因此,-8 % 5为2。

答案 1 :(得分:6)

在Python中,a // b被定义为floor(a / b),而大多数其他语言则将整数除法定义为trunc(a / b)。 a % b = a - (a // b) * b的解释存在相应的差异。

原因是因为Python对%运算符(和divmod)的定义通常比其他语言更有用。例如:

def time_of_day(seconds_since_epoch):
    minutes, seconds = divmod(seconds_since_epoch, 60)
    hours, minutes = divmod(minutes, 60)
    days, hours = divmod(hours, 24)
    return '%02d:%02d:%02d' % (hours, minutes, seconds)

使用此功能,time_of_day(12345)会返回'03:25:45',正如您所期望的那样。

但在纪元之前的时间是12345秒?使用Python对divmod的定义,time_of_day(-12345)正确返回'20:34:15'

如果我们重新定义divmod以使用/%的C定义会怎样?

def divmod(a, b):
    q = int(a / b)   # I'm using 3.x
    r = a - b * q
    return (q, r)

现在,time_of_day(-12345)会返回'-3:-25:-45',这不是一天中的有效时间。如果以这种方式实现标准Python divmod函数,则必须编写特殊情况代码来处理负输入。但是,就像我的第一个例子一样,它是地板式的划分,它就是Just Works。

答案 2 :(得分:3)

这背后的基本原理实际上是least residue的数学定义。 Python尊重这个定义,而在大多数其他编程语言中,模数运算符实际上更像是“除法后的重新分析”运算符。要计算-5 % 11的最小残差,只需将11添加到-5,直到获得[0,10]范围内的正整数,结果为6。

答案 3 :(得分:0)

当你划分整数(-2/5)* 5时,评估为-2,就像你习惯的代数一样。尝试将其分解为两个步骤,首先评估括号中的部分。

  1. ( - 2/5)* 5 =( - 1)* 5
  2. ( - 1)* 5 = -5
  3. 步骤1的原因是你正在进行int除法,它在python 2.x中返回浮点除法结果的等价值,向下舍入到最接近的整数。

    在python 3及更高版本中,2/5将返回一个浮点数,请参阅PEP 238

答案 4 :(得分:0)

查看this BetterExplained article并查看@David的评论(第6号)以了解其他人正在谈论的内容。

由于我们正在使用整数,我们进行int划分,在 Python floor 答案而不是 C 。有关此内容的更多信息Guido's article

关于你的问题:

>>> 8 % 5  #B'coz (5*1) + *3* = 8
3
>>> -8 % 5 #B'coz (5*-2) + *2* = -8
2

希望有所帮助。它在开始时也困惑了我(它仍然存在)! :)

答案 5 :(得分:0)

说-a%b需要计算。对于前  r = 11%10 找到11之后的下一个数字,它可以完全被10整除,即除以11之后的下一个数字给出余数为0。

在上述情况下,除以10得到的20为0。 因此,20-11 = 9是需要添加到11的数字。

如果60个弹珠需要在8个人之间平均分配的概念,实际上你在划分60/8之后获得的是7.5因为你不能将弹珠减半,60之后的下一个值可以被8完全整除是64因此需要在地块上再添加4个大理石,以便每个人都能分享大理石的快乐。

当使用模数运算符划分负数时,Python就是这样做的。