Побитовые операторы дают мне ад - PullRequest
3 голосов
/ 23 декабря 2011

Я пытаюсь сосредоточиться на структуре файла STFS на xbox 360, и на странице, которую я читаю, приведен пример кода для поиска смещения блока кода:

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

xBlock будет номером блока, для которого вы пытаетесь найти смещение.Я не уверен, каково значение размера заголовка, но я думаю, что он определяет, на сколько смещается остальная часть кода.Во всяком случае, я не могу понять, что делают побитовые операторы.Размер заголовка - 38682, а блок 0 - это 0xA000, но опять же, я понятия не имею, как это работает.

Может кто-нибудь помочь мне здесь?

edit: Любая информация об использовании побитовых операторов была бы полезной.Я понимаю, как они работают, но я просто не понимаю, как они используются, особенно в этом случае, что, похоже, повышает их эффективность.

Ответы [ 2 ]

2 голосов
/ 23 декабря 2011

Давайте разберемся:

(MetaData.HeaderSize + 0xFFF) & 0xF000

Эта часть, по сути, «находит следующий по величине кратный 0x1000», аналогично функции «потолка».
Например, если HeaderSize от 0x0001 до 0x1000, оно округляется до 0x1000. Но если оно от 0x1001 до 0x2000, оно округляется до 0x2000 и т. Д.

(xBlock << 12)

Это то же самое, что и xBlock * 0x1000, потому что 2 ^ 12 = 0x1000 = 4096.

Итак, чтобы найти свое смещение, вы берете заголовок, находите следующее наибольшее кратное 0x1000 и добавляете 0x1000 для каждого блока.

2 голосов
/ 23 декабря 2011

Позволяет разбить его на части, начиная с конца:

xBlock << 12

Этот оператор сдвига влево сообщает нам, что размер блока равен 4096, поскольку:

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

Теперь первая часть добавляет константу к размеру заголовка:

MetaData.HeaderSize + 0xFFF

0xFFF равно 4095. Обратите внимание, что это всего на 1 меньше, чем 4096.

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

Следующая часть теперь очищает младшие 12 бит, так как 0xF000 в двоичном виде:

1111000000000000 (1111 followed by 12 0s)

Итак, насколько я могу судить, происходит следующее:

1) Возьмите размер заголовка и добавьте размер блока - 1

2) Очистить младшие 12 битов, которые округляются до следующего наибольшего ближайшего кратного размеру блока. Я не уверен на 100% в этой части, но я попробовал несколько примеров (001 + 111) & 1000 против (111 + 111) & 1000, и похоже, что это то, что он делает.

3) Текущее значение - то, где начинается смещение для блока 0, поэтому добавьте соответствующее кратное 4096, чтобы получить смещение блока

...