Python中负数的整数除法和取模运算

10

当我在Python 3.3.0中输入这些表达式时,会出现问题。

-10 // 3  # -4
-10 % 3   #  2
10 // -3  # -4
10 % -3   # -2
-10 // -3 #  3

看起来它似乎采用了近似浮点数(-3.33)?在整数除法中向下取整,但在模操作中完全不同。似乎返回余数+/-1,并根据负操作数所在位置仅切换符号。我感到非常困惑,即使在查阅此网站上的其他答案后仍是如此!我希望有人能够清楚地向我解释这一点!该书中提到提示:回忆一下这个神奇的公式a=(a//b)(b)+(a%b),但是这对我来说似乎并没有澄清问题。

-提前致谢!

编辑:那些只���我个人对发生情况的评估(上面),我知道,我完全错了!


可能是 Python 中的负数 的重复问题。 - k.m
4个回答

7
那里的整数除法只是取最后得到的数字的下限。
10/3  -> floor(3.33)  ->  3
-10/3 -> floor(-3.33) -> -4

(为什么是向下取整)


而另一方面,取模运算则遵循数学定义


6
  • 魔法公式:a = (a // b) * b + (a % b)
  • a: -10
  • b: 3
  • a // b: -4
  • a % b: 2

    将值代入魔法公式:-10 = -4 * 3 + 2 = -12 + 2 = -10

  • a: 10

  • b: -3
  • a // b: -4
  • a % b: -2

    在魔法公式中:10 = -4 * -3 - 2 = 12 - 2 = 10

因此,魔法公式似乎是正确的。

如果您将a // b定义为floor(a / b)(它确实是这样),那么a % b应该是a - floor(a / b) * b。让我们看一下:

  • a: -10
  • b: 3
  • a % b = a - floor(a / b) * b = -10 - floor(-3.33) * 3 = -10 + 4 * 3 = 2

 

a // b始终向下取整这一事实非常容易记住(请阅读Cthulhu的第一个链接,这是Python的创建者的解释)。对于a % b中的负数a..尝试想象一个从0开始并具有b列的数字表:

b = 3:

0  1  2
3  4  5
6  7  8
9 10 11
...

如果一个单元格中有数字a,那么a % b将是列号。
a         a % b
_______________
0  1  2   0 1 2
3  4  5   0 1 2
6  7  8   0 1 2
9 10 11   0 1 2

现在将表格扩展到负数:
   a          a % b
 __________________
-12 -11 -10   0 1 2
 -9  -8  -7   0 1 2
 -6  -5  -4   0 1 2
 -3  -2  -1   0 1 2
  0   1   2   0 1 2
  3   4   5   0 1 2
  6   7   8   0 1 2
  9  10  11   0 1 2

-10 % 3会得到2。在a%b中,当a为负数时会出现这种情况。带有负数ba%b不常见。


谢谢!@Pavel,你有这种情况的经验吗?当这些表达式出现时,你会建议我尝试记住什么?总是将它们插入到魔法公式中吗? - tlands_
好的,谢谢你为我延长时间!不幸的是,这对我没有帮助 :( 我自大学二年级以来就没有上过数学课了,所以我很抱歉我的愚蠢。在方程中只加一或减一来得到正常余数是否不明智?(当然这取决于负操作数在方程中的位置) - tlands_
1
相当不明智,例如:50%13 = 11-50%13 = 2(在-13的情况下,您可以翻转11或2的符号)。您必须在心中将数字线分成大小为“b”的块。然后,a%b是块中a的位置。请参阅维基百科上的图表。我们的是向下取整的除法。 - Pavel Anossov
好的,谢谢你提醒我。我一定会更深入地研究这个问题。 - tlands_

2

一个简单的规则:对于 a % b = c,如果 c 不为零,则应与 b 具有相同的符号。

并应用魔法公式:

10 % -3 = -2 => 10 // -3 = (10 - (-2)) / (-3) = -4

-10 % 3 = 2 => -10 // 3 = (-10 - 2) / 3 = -4

-10 % -3 = -1 => -10 // -3 = (-10 - (-1)) / (-3) = 3


谢谢!所以每当解决这些问题时,总是将它们插入公式中吗?这对我来说仍然很困惑。 - tlands_
@tlands_: 是的,参见:divmod(x, y) == (x//y, x%y) - Kabie

1

好的,我进行了一些调查,我认为问题不是Python,而是取模函数。我基于链接回答这个问题。

10%3使用小于10的最高3倍数。在这种情况下,9. 10-9 = 1

-10%3也是同样的道理。它仍然在寻找小于-10的3的倍数。在这种情况下,-12. (-10) - (-12) = 2


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接