【C/C++】字节对齐 ALIGN宏

如何实现

先看一下代码中随处可见的字节对齐宏定义:

#define BYTE_ALIGN(x,a)   ( ((x) + ((a) - 1) ) & ( ~((a) - 1) ) )

字节对齐实现了什么功能呢?
其实就是计算不小x的、a的最小公倍数。

经过实验,我发现,a要为2的n次方,才会实现上面说的对齐功能,如果a不止2的n次方,BYTE_ALIGN(x,a)后的值还是x

实验验证

#include 
#include 

using namespace std;

#define BYTE_ALIGN(x,a)   ( ((x) + ((a) - 1) ) & ( ~((a) - 1) ) )

int main() {
    int a = 15;
    int x = 39;

    for (int i = 0; i < 4; i++) {
        cout << "------    a = " << a + i << "    ------ " << endl;
        for (int j = 0; j < 4; j++) {
            printf("x = %d, a = %d, BYTE_ALIGN(x,a) = %d\n",\
                x + j, a + i, BYTE_ALIGN(x + j, a + i));
        }
        cout << endl;
    }
}

/*
输出结果:
------    a = 15    ------ 
x = 39, a = 15, BYTE_ALIGN(x,a) = 49
x = 40, a = 15, BYTE_ALIGN(x,a) = 48
x = 41, a = 15, BYTE_ALIGN(x,a) = 49
x = 42, a = 15, BYTE_ALIGN(x,a) = 48

------    a = 16    ------
x = 39, a = 16, BYTE_ALIGN(x,a) = 48
x = 40, a = 16, BYTE_ALIGN(x,a) = 48
x = 41, a = 16, BYTE_ALIGN(x,a) = 48
x = 42, a = 16, BYTE_ALIGN(x,a) = 48

------    a = 17    ------
x = 39, a = 17, BYTE_ALIGN(x,a) = 39
x = 40, a = 17, BYTE_ALIGN(x,a) = 40
x = 41, a = 17, BYTE_ALIGN(x,a) = 41
x = 42, a = 17, BYTE_ALIGN(x,a) = 42

------    a = 18    ------
x = 39, a = 18, BYTE_ALIGN(x,a) = 40
x = 40, a = 18, BYTE_ALIGN(x,a) = 40
x = 41, a = 18, BYTE_ALIGN(x,a) = 42
x = 42, a = 18, BYTE_ALIGN(x,a) = 42
*/

可以看到只有当a = 16是BYTE_ALIGN对齐结果都是16的倍数48。a为其他值时实现不了所谓的对齐。

我们把a改为32看一下:

/*
------    a = 31    ------
x = 39, a = 31, BYTE_ALIGN(x,a) = 65
x = 40, a = 31, BYTE_ALIGN(x,a) = 64
x = 41, a = 31, BYTE_ALIGN(x,a) = 65
x = 42, a = 31, BYTE_ALIGN(x,a) = 64

------    a = 32    ------
x = 39, a = 32, BYTE_ALIGN(x,a) = 64
x = 40, a = 32, BYTE_ALIGN(x,a) = 64
x = 41, a = 32, BYTE_ALIGN(x,a) = 64
x = 42, a = 32, BYTE_ALIGN(x,a) = 64

------    a = 33    ------
x = 39, a = 33, BYTE_ALIGN(x,a) = 71
x = 40, a = 33, BYTE_ALIGN(x,a) = 72
x = 41, a = 33, BYTE_ALIGN(x,a) = 73
x = 42, a = 33, BYTE_ALIGN(x,a) = 74
*/

a = 32确实实现了对齐到32的整数倍64。a = 31a = 33算出的结果都是乱的,不知道干了个啥逻辑。

为什么a为2n才可以?

用二进制手动演算一下:
a = 16, x = 40

二进制
a 0000 0001 0000
x 0000 0010 1000
~((a) - 1) ) 1111 1111 0000
((x) + ((a) - 1) 0000 0011 0111
BYTE_ALIGN(x,a) 0000 0011 0000

~((a) - 1) ) 用低位取0,就是为了能与到比a大的结果。
((x) + ((a) - 1)就是为了增加x的值,之后与运算可以得到更大的结果。

应用场景

经常在图片处理的时候做字节对齐,将图像的宽和高对齐为64或512的整数倍。

向下对齐

浏览别人的博客,发现上面说的只是向上对齐,还有向下对齐。

    #define alignment_down(a, size) (a & (~(size-1)) )
    #define alignment_up(a, size)   ((a+size-1) & (~ (size-1)))

a=0, size=8, 则alignment_down(a,size)=0, alignment_up(a,size)=0.
a=6, size=8, 则alignment_down(a,size)=0, alignment_up(a,size)=8.
a=8, size=8, 则alignment_down(a,size)=8, alignment_up(a,size)=8.
a=14, size=8,则alignment_down(a,size)=8, alignment_up(a,size)=16.
注:size应当为2的n次方, 即2, 4, 8, 16, 32, 64, 128, 256, 1024, 2048, 4096 …

你可能感兴趣的:(C++,c++,开发语言,android)