关于取模运算和取余运算

事情起因是好久没碰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则为取模。

综上所述,取模和取余其实是同一个算法,区别只在于

  1. 对求商时,对商的取整方式不一样,简单来说:

    • 取余:对商的取整方法为直接去掉小数点
    • 取模:对商的取整方法为floor方法,即向下取整。可以先想象这个数在一条正常的数轴上,当这个数为小数时,取这个小数左边的整数。
  2. 当a、b符号不一致时:

    • 取余:余数符号和a一致
    • 取模:模的符号和b一致

如果要进行简单的测试,可以用Java提供的Math方法:

1
2
3
4
5
6
public static void main(String[] args) {
int a = -7;
int b = 4;
System.out.println(String.format("%d %% %d = %d", a, b, a % b));
System.out.println(String.format("%d mod %d = %d", a, b, Math.floorMod(a, b)));
}

输出:

1
2
-7 % 4 = -3
-7 mod 4 = 1
C++的内存分配 MediaCodec编码摄像头数据时控制帧率的方法

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×