Я работаю над программой, которая работает с файлом, который использует хэши. Данные делятся на блоки длиной 0х1000. Мне нужно рассчитать количество блоков в сегменте с определенным начальным и конечным смещением покрытия.
Например, если начальное смещение сегмента было 0x2000, а окончание было 0x3523, это означало бы, что он занимает два блока, 0x2000 и 0x3000. Он не занимает полных 0x2000 байтов в блоках данных, но считается, что он «занимает блок», когда находится внутри него. Моей первой мыслью было сделать:
( ( EndingOffset - StartingOffset ) + 0xFFF ) >> 0xC
Это эквивалент Math.Ceil((EndingOffset - StartingOffset) / 0x1000)
, но я новичок в побитовых операторах и мне нравится работать с ними.
В любом случае, логика была ошибочной, поскольку, и это тот случай, который меня понял, если начальное смещение 0x3D8A и конечное смещение 0x671D, разница между ними составляет 0x2993. Округлили это 0x3000, или три блока. Сегмент на самом деле занимает четыре, 0x3000, 0x4000, 0x5000 и 0x6000. Поэтому мой следующий поезд, и, к сожалению, мой последний, должен был вместо этого найти разницу между смещением первого блока, в котором находится сегмент, и смещением первого блока, в котором сегмент не находится.
С 0x3D8A и 0x671D это подводит меня к (0x7000 - 0x3000) >> 0xC
, который успешно дает правильное количество блоков, 4. То, как я это написал, я хочу улучшить, а именно:
BlockSize = ((((OffsetEnd + 0xFFF) >> 12) + 1) - ((OffsetStart + 0xFFF) >> 12));
Я знаю, что слишком усложнил простую проблему, но я не могу понять, как написать ее лучше.
править: Это стыдно. Я не знаю, как я пришел к этому вместо
(((OffsetEnd + 0xFFF) >> 12) - (OffsetStart >> 12));
Тем не менее, кажется, не завершено.
edit 2: Извините, забыл упомянуть, что конечное смещение является исключительным, не включающим и является позицией после последнего байта сегмента, означающего:
(((OffsetEnd - 1 + 0xFFF) >> 12) - (OffsetStart >> 12));
править 3: Исходя из ответа Керека, я получаю:
BlockSize = 1 + (offsetEnd - 1 >> 12) - (offsetStart >> 12);
.. или, с учетом 0,
BlockSize = (offsetEnd - 1 >> 12) - (offsetStart >> 12);
edit 4: Забудь отсчет с нуля, я придерживаюсь:
BlockSize = 1 + (offsetEnd - 1 >> 12) - (offsetStart >> 12);