fac*_*cha 64 python modulo negative-number
我在Python中发现了一些关于负数的奇怪行为:
>>> -5 % 4
3
Run Code Online (Sandbox Code Playgroud)
谁能解释一下发生了什么?
ken*_*ytm 103
与C或C++不同,Python的模运算符(%)总是返回一个与分母(除数)具有相同符号的数字.你的表达式得到3因为
(-5)%4 =( - 2×4 + 3)%4 = 3.
它是根据C行为选择的,因为非负结果通常更有用.一个例子是计算工作日.如果今天是星期二(第2天),那么N天前的星期几是多少?在Python中我们可以使用
return (2 - N) % 7
Run Code Online (Sandbox Code Playgroud)
但在C中,如果Ñ ≥3,我们得到一个负数,其是无效的号码,我们需要通过添加7手动修复它:
int result = (2 - N) % 7;
return result < 0 ? result + 7 : result;
Run Code Online (Sandbox Code Playgroud)
(有关如何确定不同语言的结果符号,请参见http://en.wikipedia.org/wiki/Modulo_operator.)
Dee*_*ant 28
其他答案,尤其是所选答案,已经很好地清楚地回答了这个问题。但我想提出一种可能更容易理解的图形方法,以及在 python 中执行正常数学模数的 python 代码。
Python 取模傻瓜书
模函数是一种方向函数,它描述了在对无限数的 X 轴进行除法过程中进行数学跳跃后,我们必须向前或向后移动多少距离。假设你正在做7%3
所以在向前方向上,你的答案将是+1,但在向后方向上 -
你的答案是-2。两者在数学上都是正确的。
同样,负数也有 2 个模数。例如:-7%3,可以导致 -1 或 +2,如下所示 -
前进方向
向后方向
在数学中,我们选择向内跳跃,即正数为向前方向,负数为向后方向。
但在 Python 中,我们对所有正模运算都有一个前进方向。因此,你的困惑 -
>>> -5 % 4
3
>>> 5 % 4
1
Run Code Online (Sandbox Code Playgroud)
以下是 python 中向内跳转类型取模的 python 代码:
def newMod(a,b):
res = a%b
return res if not res else res-b if a<0 else res
Run Code Online (Sandbox Code Playgroud)
这会给 -
>>> newMod(-5,4)
-1
>>> newMod(5,4)
1
Run Code Online (Sandbox Code Playgroud)
很多人会反对向内跳的方法,但我个人的意见是,这个更好!
Kev*_*vin 26
以下是Guido van Rossum的解释:
http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html
本质上,a/b = q,余数r保留了关系b*q + r = a和0 <= r <b.
正如所指出的,Python modulo为其他语言的约定提供了一个合理的例外。
这为负数提供了无缝行为,尤其是与//整数除法运算符结合使用时,因为%模通常是(如在math.divmod 中):
for n in range(-8,8):
print n, n//4, n%4
Run Code Online (Sandbox Code Playgroud)
产生:
-8 -2 0
-7 -2 1
-6 -2 2
-5 -2 3
-4 -1 0
-3 -1 1
-2 -1 2
-1 -1 3
0 0 0
1 0 1
2 0 2
3 0 3
4 1 0
5 1 1
6 1 2
7 1 3
Run Code Online (Sandbox Code Playgroud)
%总是输出零或正数*//总是向负无穷大舍入* ... 只要正确的操作数为正数。另一方面11 % -10 == -9
在python 中,模运算符的工作方式是这样的。
>>> mod = n - math.floor(n/base) * base
Run Code Online (Sandbox Code Playgroud)
所以结果是(对于你的情况):
mod = -5 - floor(-1.25) * 4
mod = -5 - (-2*4)
mod = 3
Run Code Online (Sandbox Code Playgroud)
而其他语言如C、JAVA、JavaScript使用截断而不是地板。
>>> mod = n - int(n/base) * base
Run Code Online (Sandbox Code Playgroud)
这导致:
mod = -5 - int(-1.25) * 4
mod = -5 - (-1*4)
mod = -1
Run Code Online (Sandbox Code Playgroud)
如果您需要有关 Python 舍入的更多信息,请阅读此。
没有一种最好的方法来处理带有负数的整数除法和mods.如果a/b是相同的幅度和相反的符号将是很好的(-a)/b.如果a % b确实是模数b 那将是很好的.因为我们真的想要a == (a/b)*b + a%b,前两个是不兼容的.
要保留哪一个是一个棘手的问题,双方都有争论.C和C++将整数除以零(so a/b == -((-a)/b)),显然Python没有.
| 归档时间: |
|
| 查看次数: |
50422 次 |
| 最近记录: |