从C++和Python除法的区别谈谈求模(Modulus)和取余(Remainder)

今天发现一个很有意思的现象。

当做除法的时候,Python2和C++在负数的情况下会得到不同的整除结果:

当做-5 / 3的时候

C++的结果: -1

Python2的结果:-2

(请注意5 / -3的时候仍然会在C++中得到-1, Python2中得到-2)

 

可以看出C++在进行负数整除的时候执行的是直接舍去小数点后数字的操作,也就是返回和0比较接近的那个数字。

但在Python2中返回的则是小于等于商的最大整数,也就是返回和-∞更接近的数。

 

在做%操作的时候,依据的是这样的逻辑:

a = b * c + r

其中a是被除数,b是除数,c是商,r是%操作的结果。

在上述例子中,a和b是-5和3。

C++的情况下商c是-1,因此r可以算出来是-2。

Python情况下商c是-2,因此r可以算出来是1。

 

!!!值得注意的是:当把操作改成5 % -3的时候,C++的结果是2,Python2的结果是-1,和之前的结果正好符号相反。

如果有同学觉得这里非常乱,请牢记a = b * c + r。

用同样的逻辑,当a是5,b是-3时,c++因为商c是-1,因此r是2,Python时商c是-2因此r是-1。

 

那么造成这种差异的原因是什么呢?

 

其实是因为“求模”(Modulus)和“取余”(Remainder)的区别。

很多同学可能认为,求模运算和取余运算是一回事。实际上在正整数范围内它们确实表现出完全相同的性质。但在负数运算的情况下,它们则会表现出不同的行为。

C++的%表现出的是“取余”操作的结果。

Python的%表现出的是“求模”操作的结果。

 

无论C++还是Python,求模和取余都是根据a = b * c + r这个公式定义的,而唯一的区别就是商c究竟是向0方向取整还是向-∞方向取整。

当商c向0方向取整的时候,得到的r是“余数”,也就是在C++中的结果。

当商c向-∞方向取整的时候,得到的r是“模数”,也就是在Python2中的结果。

 

在Python3中,无论“/”两边是否均为整数,运算的时候都转换成实数运算并返回实数。整除则用“//”来表示。

利用Python这个整除的特性,我们可以得到一个小技巧:

很多时候我们会碰到“某物x个一组,一共需要y个,至少需要多少组?”这样的问题。

在C++中我们必须写成这样的逻辑:answer = y / x; if (y % x != 0) ans += 1;

在Python中我们可以利用负数的特性很方便地得到结果:answer = -(-y // x)。

posted @ 2016-08-05 10:54  Seraph2012  阅读(3943)  评论(1编辑  收藏  举报