事情起因是好久没碰C艹了,想着看看《C++ Primer》复习一下。然后看到了第33页中讲的unsigned char
转型的描述:
例如,8比特大小的
unsigned char
可以表示0至255区间内的值,如果我们赋了一个区间意外的值,则实际的结果是该值对256取模后所得的余数。因此,把-1赋给8比特大小的unsigned char所得的结果是255。
看到这里,第一直觉是取余运算,即C艹或Java中的%
,例如 3 % 2 = 1 。但后来发现取模和取余其实是不同的计算方式。以下引用百度百科中的描述:
对于整型数a,b来说,取模运算或者求余运算的方法都是:
1.求 整数商: c = a/b;
2.计算模或者余数: r = a - c*b.
求模运算和求余运算在第一步不同: 取余运算在取c的值时,向0 方向舍入(fix()函数);而取模> 运算在计算c的值时,向负无穷方向舍入(floor()函数)。
例如计算:-7 Mod 4
那么:a = -7;b = 4;
第一步:求整数商c,如进行求模运算c = -2(向负无穷方向舍入),求余c = -1(向0方向舍入);
第二步:计算模和余数的公式相同,但因c的值不同,求模时r = 1,求余时r = -3。
归纳:当a和b符号一致时,求模运算和求余运算所得的c的值一致,因此结果一致。
当符号不一致时,结果不一样。求模运算结果的符号和b一致,求余运算结果的符号和a一致。
另外各个环境下%运算符的含义不同,比如c/c++,java 为取余,而python则为取模。
综上所述,取模和取余其实是同一个算法,区别只在于
对求商时,对商的取整方式不一样,简单来说:
- 取余:对商的取整方法为直接去掉小数点
- 取模:对商的取整方法为floor方法,即向下取整。可以先想象这个数在一条正常的数轴上,当这个数为小数时,取这个小数左边的整数。
当a、b符号不一致时:
- 取余:余数符号和a一致
- 取模:模的符号和b一致
如果要进行简单的测试,可以用Java提供的Math方法:
1 | public static void main(String[] args) { |
输出:
1 | -7 % 4 = -3 |
评论