【C语言笔记】【linux宏定义系列】 判断是否2的n次幂对齐 IS_ALIGNED
linux宏定义系列内容。用于记录在linux kernel之中各式各样的宏定义☺。
宏定义说明
用于判断一个数是否是2的n次幂对齐。如果这个数是2的n次幂对齐,返回真,否则返回假。
例如判断256是否是 2 3 2^3 23(也就是8)对齐。
该宏定义来自linux kernel 3.10。
实现代码
#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0)
宏定义中:
x 表示要判断的数。
a 表示一个 2 的 n 次幂的数,如 2,4,8,16,32,64……。
注意,a 必须填入一个 2 的 n 次幂的数,否则结果未知,判断会出错。
示例程序
示例程序依次判断了 0x80000 是否是 2 12 2^{12} 212 对齐,512 是否是 256 对齐,500 是否是 256 对齐。
int main(int argc, char* argv[])
{
printf("%d\n", IS_ALIGNED(0x80000, 1 << 12));
printf("%d\n", IS_ALIGNED(512, 256));
printf("%d\n", IS_ALIGNED(500, 256));
return 0;
}
运行后,结果为:
1
1
0
表示 0x80000 是 2 12 2^{12} 212 对齐,512 是 256 对齐,500 不是 256 对齐。
实现过程
-
(typeof(x))(a) - 1
将数值 a 的类型转换成和数值 x 相同的类型,然后减 1。
由于 a 是 2 的 n 次幂,减 1 之后低位全部变为 1。
例如 a 为 8 ,二进制就是 0b1000 ,减 1 后变为 0b0111 。
-
(x) & ((typeof(x))(a) - 1)
将数值 x 与第一步的数值相与,高位数值将会变为 0 ,如果 x 是以 2 的 n 次幂对齐,那么低位会为 0,如果不以 2 的 n 次幂对齐,那么低位不为 0。
例如上一步 a 为 8 ,假设 x 为 16 ,二进制就是 0b10000 ,与上一步算出的数值 0b0111 相与,就会为 0 。假设 x 为 18 ,二进制就是 0b10010 ,与数值 0b0111 相与,就会为 0b10 ,不为 0 。
-
(((x) & ((typeof(x))(a) - 1)) == 0)
判断是否等于 0 ,如果等于 0 ,表示是 2 的 n 次幂对齐;如果不等于 0 ,表示不是 2 的 n 次幂对齐。
[参考资料]
linux kernel 3.10
/include/linux/kernel.h
本文链接:https://blog.csdn.net/u012028275/article/details/125835426