(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);
}