按位运算符给了我地狱

时间:2011-12-23 05:51:17

标签: c# binary hex bit-manipulation bitwise-operators

我正试图围绕xbox 360的STFS文件结构,我正在阅读的页面给出了这个代码示例来查找代码块的偏移量:

internal int BlockToOffset(int xBlock)
{
    int xReturn = 0;
    if (xBlock > 0xFFFFFF)
        xReturn = -1;
    else
        xReturn = (((MetaData.HeaderSize + 0xFFF) & 0xF000) + (xBlock << 12));
    return xReturn;
}

xBlock将是您尝试查找偏移量的块编号。 我不确定标头大小的重要性是什么,但我认为它决定了其余代码的偏差量。无论如何,我无法理解按位运算符正在做什么。 headerize是38682,块0是0xA000,但是我再也不知道它是如何工作的。

有人可以帮我吗?

编辑:有关使用按位运算符的任何信息都会很棒。我理解它们是如何工作的,但我只是不明白它们是如何被使用的,尤其是在这种情况下,这似乎正在推动它们的效率。

2 个答案:

答案 0 :(得分:2)

让我们从结尾开始分手:

xBlock << 12

这个左移运算符告诉我们块大小是4096,因为:

1 << 12 = 1000000000000 (binary) = 4096 (decimal)

现在,第一部分是在标题大小中添加一个常量:

MetaData.HeaderSize + 0xFFF

0xFFF是4095.请注意,它仅比4096小1。

1000000000000 (4096 in binary)
0111111111111 (4095 in binary)

下一部分现在清除低12位,因为二进制中的0xF000是:

1111000000000000 (1111 followed by 12 0s)

所以,据我所知,发生的事情是:

1)获取标题大小并添加块大小 - 1

2)清除低12位,它将四舍五入到块大小的下一个最大最接近的倍数。 我不是100%肯定这一部分,但我尝试了一些(001 + 111)&amp;的例子。 1000 vs(111 + 111)&amp; 1000似乎就是它正在做的事情。

3)当前值是块0的偏移开始的位置,因此添加适当的4096倍数以获得块的偏移量

答案 1 :(得分:2)

让我们分解一下:

(MetaData.HeaderSize + 0xFFF) & 0xF000

这部分基本上是“找到0x1000的下一个最高倍数”,类似于“天花板”功能 例如,如果HeaderSize从0x0001到0x1000,它将舍入为0x1000。但如果它是从0x1001到0x2000,它将舍入到0x2000,等等。

(xBlock << 12)

这与xBlock * 0x1000相同,因为2 ^ 12 = 0x1000 = 4096.

因此,要找到您的偏移量,您可以获取标题,找到0x1000的下一个最高倍数,并为每个块添加0x1000。