2015-01-20 2 views
1

Я новичок в программировании на С и не уверен, что уже есть хорошее объяснение того, как это сделать, если так мне жаль. Я пытаюсь установить биты в пределах диапазона, указанного мне. функция подписи выглядит следующим образом:Маскировка битов в диапазоне, заданном в параметре в C

unsigned int setBits(int low, int high, unsigned int source) { 

source является число, которое будет работать на, low самый низкий бит в диапазоне, и high самый высокий разряд в диапазоне. Я понимаю, что бит-сдвиг просто прекрасен, когда вы пытаетесь получить конкретно последние 4 бита или первые 4 или любую их комбинацию, но не понимаете, как получить биты из диапазона, который будет изменен в параметре. Любая помощь будет принята с благодарностью.

+0

что-то вдоль линии '(1 << высокий) - (1 << низкий)', в зависимости от того, 'high' /' low' включают или нет. – SleuthEye

+0

они включаются, считая справа налево от 0, при этом низкий справа. Я уже обрабатывал исключения для них равными или низкими> высокими. Вы говорите, что это то, из чего должна быть сделана моя маска, а затем | маску с моим источником? –

+0

Получить n бит из позиции p для числа x .. сделать что-то вроде .... return ((x >> (p + 1n) & ~ (~ 0 << n)) –

ответ

3

Если его включено

mask = ~(~0 << (end - start + 1)); 
value = (n >> start) & mask; 

где п исходное целое число, а величина выделенных битов.

+0

Что будет n в значении = (n >> start ... mask)? high - low? –

+0

N - ваше исходное целое число или параметр в вашем case..от того, что вы извлекаете –

+0

ах, я вижу. Я попробую это. –

3

2 подхода: Итерационный метод для установки бита в source от low до high:

unsigned int setBitsI(int low, int high, unsigned int source) { 
    while (low <= high) { 
    source |= 1u << low; 
    low++; 
    } 
    return source; 
} 

Non-итерационного метода:

unsigned int setBitsNI(int low, int high, unsigned int source) { 
    unsigned setmask = 1u << (high - low); 
    setmask <<= 1; 
    setmask--; 
    setmask <<= low; 
    return source | setmask; 
} 

Важно, чтобы избежать 1u << (1u + high - low) для того, когда high является «бит ширины -1 "и low - 0, 1u << bit_width - UB.

Должно ли low или high иметь значение вне диапазона бит, возникают проблемы.

0

Вот несколько простых примеров смены и создания масок для мотивации более общего выражения.

1    == 00001b 
1<<2   == 00100b 
(1<<2)-1  == 00011b 
((1<<2)-1)<<2 == 01100b 

Так,

((1<<(high-low+1))-1)<<low 
-1

Это было мое решение: Условный заявления на фронте только покрыть условными о низкой и высокой. Это проходит все тесты, которые мне дали.

unsigned int setBits(int low, int high, unsigned int source) 
{ 
if (low < 0)   {return source;} 
else if (high > 31) {return source;} 
else if (low > high) {return source;} 
else { 
     unsigned int mask = 0xFFFFFFFF << (31 - high); 
     mask = mask >> ((31 - high) + low); 
     mask = mask << low; 
     return source | mask; 
    }   

}

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