5

在 C 语言中,我有一个代表地址的 32 位字(我将它存储在一个无符号长整数中,希望没问题)。现在根据我的收集,地址的一部分包含页码,另一部分包含偏移量。我想知道如何仅提取给我页码的位。我已经计算出前 22 个最高有效位是页码,其他 10 个位是页偏移量。我怎样才能只抓住作为页码的位?我想我可以用一些按位运算来做到这一点,但不知道怎么做。

4

2 回答 2

11

使用位移运算符来提取您需要的位。

pageNumber = x >> 10;
offset = x & ((1 << 10) - 1);

对于页码,>> 运算符将位向下移动,因此您会丢失最不重要的位。

对于偏移量, ((1 << 10) - 1) 创建一个由 10 个 1 组成的位掩码,用于仅选择 10 个最低有效位并忽略最高有效位。

于 2009-11-29T22:45:33.773 回答
2

我是“两班制”字段提取方法的忠实拥护者。它适用于签名和未签名。w要从 中提取具有最低有效位lsb的宽度字段word

#define BITSIN(W) (8*sizeof(W))
return (word << (BITSIN(word) - (lsb+width))) >> (BITSIN(word) - width);

在这种情况下BITSIN(word) == 32lsb+width == 32,只要有问题的单词是无符号的,你就可以右移 10 而不加掩码。

一个警告:当心 32 位类型上的 32 位移位!C 标准让编译器可以做任何事情,而普通英特尔芯片所做的事情并没有什么用处: x << y左移一位(前提x是具有 32 位整数类型)。这意味着如果您尝试将 32 位整数向左或向右移动 32 位,结果与无操作相同。64 位类型的 64 位移位也有类似的问题。y % 32x

于 2009-11-30T00:32:58.557 回答