-------------------------------------------
本文系作者原创, 欢迎大家转载!
转载请注明出处:netwalker.blog.chinaunix.net
-------------------------------------------
圆整通常被理解为为满足某种要求而进行的数据修正。按照修正后的数据在数值上是否比原数据大,又可分为向上圆整和向下圆整。它们很像对模拟信号进行采样,对一定范围的数据向一个固定的数据靠拢。Linux内核中定义了面向整除的圆整计算宏。第一个叫做roundup。
- #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
- #define roundown(x, y) (((x) / (y)) * (y))
那么如何理解roundup的定义呢?看起来是尝试将(x) + ((y) - 1)的结果对y做向下取整,为何这样就可以实现x对y的向上取整呢?除法的本质在于对量的均分,那么观察下图:
图 2. 向上圆整算法证明

对于x = βy + δ来说,β>=0,y>0,并且0<=δ
一种更易被人理解的定义方式如下,它根据取余的结果计算圆整,由于整除的概率很低,所以这种算法每次都要多计算一次取余,而不能完全避免对除法的运算以消减取余算法的影响,它的效率要低。
- #define roundup(x, y) ((x)%(y) ? ((x)/(y) + 1) * (y) : x)
- int divisor = 0;
- printf("divisor\troundup\trounddown\n");
- for(; divisor < 5; divisor++)
- printf("%d:\t%d\t%d\n", divisor, roundup(divisor, 2), roundown(divisor, 2));
输出结果如下:
- divisor roundup rounddown
- 0: 0 0
- 1: 2 0
- 2: 2 2
- 3: 4 2
- 4: 4 4
- #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))