右移实现除法中的偏置量问题

问题的引出:

int div16(int x){
    int bias=(x>>31)&0xF;
    return (x+bias)>>4;

}

问题就在于代码中的第二行,当x>=0时,bias值为零,当x<0时,bias值为15。如果把这行注释掉,对于正数的计算结果是没有问题的,但是对于负数的计算结果,就比理论值小1(例如当x=-17的时候,结果为-2)。原因如下:

在计算机中,如果两个int型数a和b作除法(a/b),当a不能被b整除的时候,表达式的结果为(a/b)的商。这个商是通过向下取整得来的。即对于17/16,结果在区间(1,2)上,向下取整,得到1。考虑a<0的情况,当a=-17时,结果在(-2,-1)上,向下取整,得到-2。而我们期望的结果是-1。通过与偏置量相加,将结果偏移到(-1,0)上,再向下取整,就得到-1。

当不能整除时,计算机都会采取向下取整运算。对于正数,向下取整是符合我们习惯的,对于负数,我们的期望时绝对值向下取整,即整体向上取整,这与计算机的向下取整不符合,所以就要通过偏置量来实现。

关于偏置量的取值,当a>=0时,偏置量值为0;当a<0时,设偏移量为n,偏置量取值为(2^n-1)。


你可能感兴趣的:(C/C++)