c - (size + 7) & ~7 是什么意思?

标签 c bit-manipulation

我正在阅读 Multiboot2 规范。你可以找到它here .与以前的版本相比,它将所有结构命名为“标签”。它们的定义如下:

3.1.3 General tag structure

Tags constitutes a buffer of structures following each other padded on u_virt size. Every structure has following format:

    +-------------------+
u16 | type              |
u16 | flags             |
u32 | size              |
    +-------------------+

type is divided into 2 parts. Lower contains an identifier of contents of the rest of the tag. size contains the size of tag including header fields. If bit 0 of flags (also known as optional) is set if bootloader may ignore this tag if it lacks relevant support. Tags are terminated by a tag of type 0 and size 8.

然后在示例代码中:

for (tag = (struct multiboot_tag *) (addr + 8);
     tag->type != MULTIBOOT_TAG_TYPE_END;
     tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag
     + ((tag->size + 7) & ~7)))

最后一部分让我很困惑。在 Multiboot 1 中,代码简单得多,您可以执行 multiboot_some_structure * mss = (multiboot_some_structure *) mbi->some_addr 并直接获取成员,而不会像这样混淆代码。

谁能解释一下 ((tag->size + 7) & ~7) 是什么意思?

最佳答案

正如 chux 在他的评论中提到的,这会将 tag->size 舍入到最接近的 8 的倍数。

让我们仔细看看它是如何工作的。

假设 size 为 16:

 00010000         // 16 in binary
+00000111         // add 7
 --------
 00010111         // results in 23

表达式 ~7 取值 7 并反转所有位。所以:

 00010111         // 23 (from pervious step)
&11111000         // bitwise-AND ~7
 --------
 00010000         // results in 16

现在假设 size 是 17:

 00010001         // 17 in binary
+00000111         // add 7
 --------
 00011000         // results in 24

然后:

 00011000         // 24 (from pervious step)
&11111000         // bitwise-AND ~7
 --------
 00011000         // results in 24

因此,如果 size 的低 3 位全为零,即 8 的倍数,(size+7)&~7 设置这些位,然后清除它们,所以没有净效应。但是,如果这些位中的任何一位为 1,则对应于 8 的位会递增,然后清除较低的位,即该数字会向上舍入到最接近的 8 的倍数。

关于c - (size + 7) & ~7 是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33308421/

相关文章:

c - 32位Linux上 "_Jv_RegisterClasses"和 "clock_gettime"在哪里定义的?

java - 定义数字是否为三角数的最快方法

java - 计算 n 位 2 的补数的绝对值

algorithm - 通过移位操作替换分支语句

c - 我在哪里可以找到 C 语言的移位指南?

c - getchar() 不会让控制台保持打开状态

java - 给定掩码大小,有效地创建具有低位集的掩码

c - "Shared Exponent"OpenCL C 中浮点 vector 的表示

c - 在 Mac OS X 上实现 faccessat(),如何根据给定的目录文件描述符和路径名构造新路径?

c - 分段故障。错误退出c程序