关于python:具有负值的模运算-奇怪的事情吗?

关于python:具有负值的模运算-奇怪的事情吗?

Modulus operation with negatives values - weird thing?

您能告诉我(-2) % 5多少吗?
根据我的Python解释器是3,但是您对此有一个明智的解释吗?

我读过某些语言的结果可能与机器有关,但是我不


顺便说一句:大多数编程语言会不同意Python并给出结果-2。根据模量的解释,这是正确的。但是,最公认的数学定义是a和b的模数是a / b除法的(严格为正)余数r。更确切地说,0 <= r


对负数进行模运算的结果似乎与编程语言有关,下面是列表http://en.wikipedia.org/wiki/Modulo_operation


您的Python解释器是正确的。
一种计算模数的(愚蠢的)方法是减去或增加模数,直到结果值在0到(模数≥1)之间。

例如。:
13 mod 5 =(13?5)mod 5 =(13?10)mod 5 = 3

或您的情况:?2 mod 5 =(?2 + 5)mod 5 = 3


就像文档在二进制算术运算中所说的那样,Python确保:

The integer division and modulo operators are connected by the following identity: x == (x/y)*y + (x%y). Integer division and modulo are also connected with the built-in function divmod(): divmod(x, y) == (x/y, x%y).

确实

1
2
>>> divmod(-2, 5)
(-1, 3).

可视化此方法均匀性的另一种方法是为一小序列数字计算divmod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
>>> for number in xrange(-10, 10):
...     print divmod(number, 5)
...
(-2, 0)
(-2, 1)
(-2, 2)
(-2, 3)
(-2, 4)
(-1, 0)
(-1, 1)
(-1, 2)
(-1, 3)
(-1, 4)
(0, 0)
(0, 1)
(0, 2)
(0, 3)
(0, 4)
(1, 0)
(1, 1)
(1, 2)
(1, 3)
(1, 4)

好吧,0%5应该是0,对吧?

-1%5应该为4,因为这是下一个允许的反向数字(即,不能为5,因为这超出了范围)。

遵循该逻辑,-2必须为3。

考虑它如何工作的最简单方法是,您不断加减5,直到数字介于0(含)和5(不含)之间。

我不确定机器的依赖性-我从未见过这样的实现,但是我不能说它从未完成。


如其他答案所述,对于具有负值的模运算,有很多选择。通常,不同的语言(和不同的机器体系结构)将给出不同的结果。

根据Python参考手册,

The modulo operator always yields a result with the same sign as its second operand (or zero); the absolute value of the result is strictly smaller than the absolute value of the second operand.

是Python采取的选择。基本上定义了模,以便始终保持:

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

所以说(-2)%5 = -2-(-2/5)* 5 = 3很有意义


术语"模"和"余数"之间似乎存在一个常见的混淆。

在数学中,应始终定义与商一致的余数,以便如果a / b == c rem d(c * b) + d == a。根据您对商的舍入方式,您会得到不同的余数。

但是,取模应始终给出结果0 <= r < divisor,仅当允许负整数时,才与舍入到负无穷除法保持一致。如果除法取整为零(这很常见),则模和余数仅对非负值等效。

某些语言(尤其是C和C ++)没有定义所需的舍入/余数行为,并且%是不明确的。许多人将舍入定义为接近零,但在剩余数会更正确的地方使用术语取模。 Python相对不寻常,因为它四舍五入为负无穷大,因此取模和余数相等。

Ada朝着零IIRC四舍五入,但同时具有modrem运算符。

C策略旨在允许编译器为计算机选择最有效的实现,但是IMO至少在最近这些天是错误的优化。一个好的编译器可能会在不会出现负数的地方(并且几乎可以肯定,如果使用无符号类型)可以使用等效项进行优化。另一方面,在可能出现负数的地方,您几乎可以肯定会在乎细节-出于可移植性的原因,您必须使用精心设计的过度复杂算法和/或检查以确保无论舍入和余数如何都得到想要的结果行为。

换句话说,这种"优化"的收益大部分(如果不是总是)是一种幻想,而在某些情况下却存在非常实际的成本-因此这是错误的优化。


注意不要在所有OS和体系结构上都依赖C / C ++中的mod行为。如果我没记错的话,我尝试依赖C / C ++代码,例如

1
float x2 = x % n;

将x2的范围保持在0到n-1之间,但是当我在一个OS上进行编译时,负数会逐渐增加,但是在另一个OS上一切正常。因为它只发生一半的时间,所以调试很麻烦!


一种解释可能是负数使用2的补码存储。当python解释器尝试执行模运算时,它将转换为无符号值。因此,实际上不是计算(-2)%5,而是计算0xFFFF_FFFF_FFFF_FFFD%5,即3。


结果取决于语言。 Python返回除数的符号,例如c#返回除数的符号(即-2%5在c#中返回-2)。


确实为3。在模算术中,模数只是除法的余数,而-2除以5的余数是3。


好吧,-2除以5等于0,其余为3。我不认为这应该与平台密切相关,但是我已经看到了一些奇怪的东西。


推荐阅读

    探探语言设置|探探怎么设置语言

    探探语言设置|探探怎么设置语言,,1. 探探怎么设置语言打开探探软件,然后就有消息提示的红点,点开就行了!其实这些软件都是挺简单的操作的,都是

    git设置编码|git语言设置

    git设置编码|git语言设置,,git设置编码点击cap4j搜索从git直接链接上拉代码。git语言设置Git是一个开源的分布式版本控制系统,可以有效、高

    区域语言设置|区域语言设置工具

    区域语言设置|区域语言设置工具,,区域语言设置工具你好,大致的方法如下,可以参考:1、按下键盘的windows 图标,再开始菜单中单击“设置”;出现的

    c4d语言设置|c4d汉语设置

    c4d语言设置|c4d汉语设置,,1. c4d汉语设置mac版的C4D是这样的,中文字体是有的,但是是以拼音的形式存在,比如黑体就是ht。中文字体以拼音方式

    电脑宣传语|电脑宣传语言

    电脑宣传语|电脑宣传语言,,1. 电脑宣传语言1.我做好了与你过一辈子的打算,也做好了你随时要走的准备,2.每段青春都会苍老,但我希望记忆里的你

    office语言设置|微软office语言设置

    office语言设置|微软office语言设置,,微软office语言设置一、首先点击桌面左下角“WIN键”。二、弹出选项内点击“所有程序”。三、接着点

    dip医保通俗解释?dip和drg医保区别

    dip医保通俗解释?dip和drg医保区别,医保,医疗机构,本文目录dip医保通俗解释dip和drg医保区别医保dip是什么意思DIP是什么意思电子厂dip是什

    小米设置日语|小米设置日语语言

    小米设置日语|小米设置日语语言,,1. 小米设置日语语言MIUI系统文字目前只支持简体中文、繁体中文、英文、藏文和维吾尔文,不支持日文 2. 小