将bytes上调至8的倍数

在<<STL源码剖析>>的空间配置一章的二级配置器中,有如下一段源代码,功能是将bytes上调至8的倍数。

enum{_ALIGN=8}; //小型区块的上调边界

private:
static size_t ROUND_UP(size_t bytes){
    return (((bytes)+_ALIGN-1)&~(_ALIGN-1));
}

这里的源码乍一看很难懂,但是十分高效,现在具体看一下实现原理。

这里82^3,二进制表示为00001000。前面的0先省略了,不影响分析。

_ALIGN-1:

00001000->00000111;

~_ALIGN-1:

00000111->11111000;

bytes+ALIGN-1:

x这里如果bytes是8的倍数,那么低3位全是0。

xxxxx000->xxxxx111

(bytes+ALIGN-1)&(~_ALIGN-1):

xxxxx111->xxxxx000

这里得到的是bytes本身。

 

如果bytes不是8的倍数呢?那么首先

8n<bytes<8(n+1)

我们要求的就是8(n+1)。

bytes用二进制表示,低三位不全为0,加上ALIGN-1会向第4位进位。此时将第三位清零,使用取反后相与,得到的就是8(n+1)。

 

这里的简单推导一下:

8n<bytes<8(n+1)

bytes=8n+p,p<8

p存在低3位,8n存在高三位,执行加法bytes+ALIGN-1,产生进位。

现在bytes=8(n+1)+p,清零后为8(n+1)。

 

这个问题还可以推广到将一个数字上调到2^n的倍数。因为2^n的低n位必定全是0,上面是实例n=3的情况。

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