(1)圆整

圆整通常被理解为为满足某种要求而进行的数据修正。按照修正后的数据在数值上是否比原数据大,又可分为向上圆整和向下圆整。它们很像对模拟信号进行采样,对一定范围的数据向一个固定的数据靠拢。

 

(2)roundup

(2.1)宏定义

#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))

 

说明:其实向上圆整可以按照下面的宏定义,可能更加容易理解;

#define roundup(x, y) ((x)%(y) ? ((x)/(y) + 1) * (y) : x)

 

(2.2)作用

尝试找到大于等于x并接近x的可以整除y的那个数,也即向上圆整。

(3)roundown

(3.1)定义

#define roundown(x, y) (((x) / (y)) * (y))

(3.2)作用

       尝试找到小于等于x并接近x并且可以整除y的那个数,即向下圆整;

 

(4)DIV_ROUND_UP

(4.1)定义

       #defineDIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))

(4.2)作用

用来对除法的结果进行圆整,即n/d向上取整;

(5)roundup_power_of_two

(5.1)作用

       roundup_power_of_two(x):取大于等于x又最接近x的2的n次幂的一个数;

(5.2)举例

       数据5,它的二进制形式为101,最高位为1的位置是2,然后左移(2+1)位,等于1000,即数字8。也就是数字8是5的接近的2的整数次幂。

 

(5.3)原理

       最主要的任务就是找到该数最高位为1的位置;这个有专门的AT&T汇编指令bsrl。这个指令是个32位指令,位置范围是0到31。

 

(5.4)实现

//得到x的最高位为1的位置;

static inline int fls(int x)
{

int position;

int i;

if(0 != x) {

for (i = (x >> 1), position = 0; i!= 0; ++position)

 i >>= 1;

}

else{

position = -1;

}

return position+1;

}

 

最后把要得到的数字用1左移那么多次数,即可。考虑到0的特殊性,我们把数字都减1,其他都不会受影响,这样0会取值成-1,然后取到的位置为32,1左移32位后还是为0。

实现代码如下:

static inline unsigned introundup_pow_of_two(unsigned int x)
{

return 1UL<< fls(x - 1);
}