取模和取余

近日在读C++ Primer第五版,在2.1.2类型转换一节中,有这样一个例子:

unsigned char c = -1; //假设char占8比特,c的值位255

当看到255这个值,一脸蒙圈,为什么是这个值呢?
书上的解释是:当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。例如,8比特大小的unsigned char可以表示0至255区间内的值,如果我们赋了一个区间以外的值,则实际的结果是该值对256取模后所得的余数。因此,把-1赋给8比特大小的unsigned char所得的结果是255。

取模和取余

书中提到取模运算,这里来说一下取模和取余运算:
假设有整数a和b,那么取模/取余运算可以分为两步运算:

  1. 求整数商:c = a/b;
  2. 计算模/余数:r = a - (c*b);

取模和取余运算的差别在于第一步中c的取值:

  • 取余运算在计算商值时向0的方向舍弃小数位
  • 取模运算在计算商值时向负无穷方向舍弃小数位

例如:4/(-3)约等于-1.3,那么在取余运算中,c取-1(商值向0的方向舍弃小数位),所欲余数r=1;在取模运算中,c取-2(商值向负无穷方向舍弃小数位),所以模数r=-2;

根据上述的说明,我们似乎已经弄清了取模的概念,让我们回到书中的例子,令a=-1,b=256,此时计算可得c=0;根据上述概念我们c应该取何值呢,在我百思不得其解之时,博客园中一篇博客给了我答案。

负数取模

取余/取模运算在除数和被除数同号时,结果是相等的,在两者异号时会有差别;当异号时,我们该如何进行取模运算呢?
在数学中取模运算是这样定义的:

x mod y = x - y[x/y] //[]表示取下界

以-3 mod 2为例:

  -3 mod 2
= -3 - 2 * [-3/2]
= -3 - 2 * [-1.5]
= -3 - 2 * (-2)
= -3 + 4
= 1

通过上述概念,我们便可以解决书上的例子

  -1 mod 256
= -1 - 256 * [-1/256]
= -1 - 256 * [0]
= -1 - 256 * (-1)
= 255

可以愉快的接着啃书了!

本文参考:

  1. CSDN-panyyer:取模和取余的区别
  2. 博客园-张子秋:原码, 反码, 补码 详解
  3. 知乎回答-竹月凉:编程语言中,取余和取模的区别到底是什么?

你可能感兴趣的:(取模和取余)