2016-08-23 2 views
0

Я пишу диспетчер физической памяти растрового изображения, и я хочу реализовать функцию, которая проверяет, свободны ли n бит, начиная с определенного бита. Сейчас я использую эту функцию, которая проверяет, является ли один бит свободен и я называю это п раз, чтобы увидеть, если п бит свободны, но я думаю, что это не очень эффективно, чтобы сделать это таким образом:Как проверить, если набор бит равен 0 из определенной позиции?

inline static bool physical_memory_map_test(uint32_t bit) 
{ 
    return physical_memory.blocks[bit/32] & (1 << bit % 32); 
} 

Так Я хочу implemnt что-то вроде этого: (далее «» содержит псевдокод):

static bool physical_memory_map_test(uint32_t starting_bit, uint32_t count) 
{ 
    int excess = (starting_bit%32 + count) -32; 
    if(excess < 0) 
     return (physical_memory.blocks[bit/32] & "-excess number of 1s" << bit % 32)) && (physical_memory.blocks[bit/32] & "count + excess number of 1s" << bit % 32)); 

    return physical_memory.blocks[bit/32] & ("count number of ones, if count is 3, this should be 111" << bit % 32); 
} 

или что-то лучше, чтобы проверить, если все биты равны 0 (возвращает истину) или если хотя бы один из них является 1 (return false) Как я могу это сделать?

+0

Если вы хотите, чтобы общее количество заданных битов в целочисленном типе, вы хотите «popcount», который доступен как машинная инструкция в некоторых архитектурах и как встроенный компилятор. Если вы хотите считать * смежными * установленными битами, вы можете найти 'ffs()' или 'clz/ctz' или' lzcnt/tzcnt' или 'bsf/bsr' или эквивалентные встроенные значения. – EOF

+0

Если вы хотите проверить, что '' 'последовательные * биты являются бесплатными, вы можете проверить тогда 32 за раз, за ​​исключением первого и последнего нескольких. –

ответ

5

Поскольку вы проверяете диапазон слов uint32_t, вы закончите цикл. Ваша задача - сделать его циклом на 32 бита вместо цикла на 1 бит.

Вы должны проверить частичные 32-битовые слова на обоих концах:

Bit groups

Для этого необходимо построить маску с k младшими битами установлены в 1, и верхний (32-k) набор для 0. Вы можете сделать это следующим образом:

uint32_t mask_K = ~(~0U << k); 

Использование

if (block & mask_K) 

, чтобы проверить нижние k биты;

if (block & ~mask_K) 

проверяет верхние k бит.

+0

Вычисление 'mask_K', как представляется, вызывает UB для' k' = 31. – njuffa

+0

Обычно я использую '~ (~ 0U << k)' для построения 32-разрядной маски с последовательными 1-битами 'k' (0 <= k <32), может быть, это подойдет вашей цели? – njuffa

+0

@njuffa Это еще лучше, спасибо! – dasblinkenlight

Смежные вопросы