2013-06-27 3 views
8

У меня была проблема в руке как это: «Упражнение 2-6. Напишите набор функций (x, p, n, y), который возвращает x с n битами, начинающимися с позиция p установите самые правые n битов y, оставив остальные биты без изменений ».Оптимизация побитовых операций в C

Я написал для этого функцию, как показано ниже. Это работает как ожидалось.

int func_setx(int x,int p,int n,int y) 
{ 
    int a_t= ~0 << (p+n); 
    int b_t= ~a_t >> n; 
    int x_t= x& (a_t | b_t); // a temporary x which has the bits to be changed as 0 , rest of the bits unchanged. 

    int mask= (y << p) & (~(~0 << (p+n)));  // a mask which has required bits from y in positions to be set , rest all bits 0. 

    printf("\nCheckpoint : mask= %x x_t= %x\n",mask,x_t); 

    int result= mask|x_t; 
    return result; 
} 

Но я почему-то чувствует, что логика долго и может быть оптимизирована, но не могу думать о каком-либо другом способе еще. Может ли кто-нибудь предложить любую оптимизацию для этого, пожалуйста?

+1

Вы, вероятно, найти ответ на [Бит Twiddling Hacks] (http: // графика .stanford.edu/~ seander/bithacks.html) - и вы должны пометить страницу, даже если вы не нашли ответа там. –

+0

Многочисленные дубликаты, например. [k & r путаница работы с битовыми операциями] (http://stackoverflow.com/questions/2076084/kr-exercise-confusion-with-bit-operations) и [возвращает x с n битами, которые начинаются с позиции p, установленной на самые правые n бит y, оставив другие биты без изменений] (http://stackoverflow.com/questions/6727351/returns-x-with-the-n-bits-that-begin-at-position-p-set-to- the-rightmost-n-bits-o) и [Setting Bits in C] (http://stackoverflow.com/questions/11590545/setting-bits-in-c) –

ответ

10

Чтобы сделать n битовую маску:

mask_y = (1U << n) - 1; 

Чтобы запустить его на бит p:

mask_x = mask_y << p; 

Очистить соответствующие биты в x:

x &= ~mask_x; 

Извлечение битов из y:

y &= mask_y; 

повышающую передачи их в положение p:

y <<= p; 

Соберем все вместе:

result = x | y; 

Или в более компактной форме:

mask = (1U << n) - 1; 
result = x & ~(mask << p); 
result |= (y & mask) << p; 
+1

Предполагая 32-битные целые числа, если 'n == 32', это решение вызывает неопределенное поведение. Этот случай - это просто 'return y', но это легко сделать в специальном случае. В качестве альтернативы используйте '1ULL' (или вы хотите получить 64-разрядный тип) вместо' 1U'. –

+0

+1 для того, чтобы не просто дать код, но и объяснить, что он делает шаг за шагом – legends2k

+0

Карл, ваш комментарий должен быть надлежащим образом частью вашего ответа. –

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