无论是C语言还是在Python中,取模运算,比如,6%5都得到1,一切是那么和谐。
如果被除数是负数,比如,C语言中,-6%5=-1, Python中,-6%5=4,问题来了,这是为什么?
还有6%(-5), -6%(-5), 它们在C语言和Python中的运算结果分别是什么?
// C语言的
#include <stdio.h>
int main(int argc, char **argv)
{
int a, b, c, d;
a = 6; b = 5; c = a%b; d=a/b;
printf("a=%d, b=%d, a%%b=%d, a/b=%d\n", a, b, c, d);
a = 6; b = -5; c = a%b; d=a/b;
printf("a=%d, b=%d, a%%b=%d, a/b=%d\n", a, b, c, d);
a = -6; b = 5; c = a%b; d=a/b;
printf("a=%d, b=%d, a%%b=%d, a/b=%d\n", a, b, c, d);
a = -6; b = -5; c = a%b; d=a/b;
printf("a=%d, b=%d, a%%b=%d, a/b=%d\n", a, b, c, d);
}
# Python的
#!/usr/bin/python3
a = 6; b = 5; c = a%b; d=int(a/b);
print("a=%d, b=%d, a%%b=%d, a/b=%d"%(a, b, c, d) );
a = 6; b = -5; c = a%b; d=int(a/b);
print("a=%d, b=%d, a%%b=%d, a/b=%d"%( a, b, c, d) );
a = -6; b = 5; c = a%b; d=int(a/b);
print("a=%d, b=%d, a%%b=%d, a/b=%d"%( a, b, c, d) );
a = -6; b = -5; c = a%b; d=int(a/b);
print("a=%d, b=%d, a%%b=%d, a/b=%d"%( a, b, c, d) );
实际输出是这样的:
//C语言的 a=6, b=5, a%b=1, a/b=1 a=6, b=-5, a%b=1, a/b=-1 a=-6, b=5, a%b=-1, a/b=-1 a=-6, b=-5, a%b=-1, a/b=1 # Python的 a=6, b=5, a%b=1, a/b=1 a=6, b=-5, a%b=-4, a/b=-1 a=-6, b=5, a%b=4, a/b=-1 a=-6, b=-5, a%b=-1, a/b=1
如果输出结果和你想的不一样,请继续往下看,其实第一次见到这样的结果我也搞不懂是怎么回事。
其实wikipedia已经说的比较详细了: Modulo_operation(不知道wikipedia被土啬后有没有解除啊? 打不开链接也无所谓,影响不大), 只是不那么直接,我再加工加工,更容易理解。
C语言进行%运算的时候,采用的是truncated divison, Python在进行%运算的时候,采用的是floored division。truncated divison是把一个小数向0的方向进行截断取整, floored divison是把一个小数向负无穷的方向截断整。
还是例子比如实在。约定:trunc(a/b)表示对a和b进行truncated divison, floor(a/b)表示对a和b进行floored divison。
对于正数,两种方法没有区别。trunc(6/5)= floor(6/5) = 1。
对于负数,有区别了:trunc(-6/5)=-1, floor(-6/5) = -2。
约定:a表示被除数,n表示除数, r表示余数(r即我们的主角,%运算的结果, a, b, n为整数,b不等于0)。我们认为取模运算和%运算是一样的。 那么有:
C语言中的取模运算: r=a-n*trunc(a/n)
Python中的取模运算:r=a-n*floor(a/n)
我们可以用这两种不同规则解释上面程序的输出了。
// C语言的 6%5 = 6-5*trunc(6/5) = 6-5 = 1 6%(-5) = 6-(-5)*trunc(6/(-5)) = 6+5*trunc(-1.2) = 1 -6%5 = -6-5*trunc(-6/5) = -6+5 = -1 -6%(-5) = -6-(-5)*trunc(-6/(-5)) = -6+5*trunc(1.2) =-1 # 6%5= 6-5*floor(6/5) = 1 6%(-5) = 6-(-5)*floor(6/(-5)) = 6+5*floor(-1.2) = 6-10 = -4 -6%5 = -6-5*floor(-6/5) = -6-5*floor(-1.2) = -6+10 = 4 -6%-5 = -6-(-5)*floor(-6/(-5)) = -6+5*floor(1.2) = -1
嗯,总算讲完了。应该够清晰了。