C语言面试易错点:负数整形的除法和取余

C语言整形的除法的结果需要取整,例如5 / 3 = 1。C语言中的取整方式是向零取整。

取整风格共有3种:

  1. 向零取整。即向坐标轴0的方向,取最近的整数。
  2. 向上取整。也就是向+∞取整,即取不小于结果的最小整数。
  3. 向下取整。也就是向-∞取整,即取不大于结果的最大整数。

所以,C语言中计算-5除以3,因为实数结果约为-1.67,向零取整,得到结果为-1。

关于除法,人们常常用向右移位的方式来快速计算一个数除以2的幂的结果,例如16 / 4 = 4就是把10000右移2位得到100,即4;9 / 4 = 2就是把1001右移2位得到2。事实上,这种快速计算的方法,是一种向下取整的过程,所以它只适用于被除数为正数的情况。若被除数为负数,这种右移的快速计算方式就是错误的了。下面用代码来验证一下,从10到-10,分别计算他们除以4和右移2位的结果:

#include <stdio.h>

int main()
{
  int i = 0;

  for (i = 10; i >= -10; i--)
  {
    printf("%d / 4 = %d\r\n", i, i / 4);
    printf("%d >> 2 = %d\r\n", i, i >> 2);
    printf("\r\n");
  }

  getchar();
    
  return 0;
}

程序运算结果如下图所示:

可见,当被除数为正数的时候,除以4和右移2位的结果是一样的。但是,当被除数为负数的时候,这两个结果并不一定相同。

关于负数的右移操作的解释:以-6为例,6的二进制形式是110,所以-6的补码形式是第一位符号位为1,数据位是110取反加1,得到1010。1010右移2位,得到10。取出10的符号位1,数据位是0,数据位取反加1得到10,即十进制的2。也就是十进制-6右移2位得到十进制的-2。

有了除法的基础,取余(也叫求模)操作根据公式计算就可以了。设A除以B的结果为Q,余数为R,则A = B * Q + R, R = A - B *Q。例如求-8 % 3,因为-8 / 3 = -2,那么余数就是-8 - 3 * (-2) = -2

取余操作除了套用公式来做,还有一个快捷的经验,就是取余的结果的符号永远和被除数的符号一样。这个经验可以用下面的例子来解释:去银行借了8万块贷款,每个月还3万,还了2个月之后,还剩下2万没还,这个2万依然是欠的,所以和8万的符号相同。

posted @ 2017-02-26 22:26  zhugehq  阅读(11391)  评论(0编辑  收藏  举报