2013-07-27 3 views
0

Сейчас я читаю книгу Компьютерные системы: перспектива программиста.Выполнение логического сдвига с использованием оператора арифметического сдвига в C

Одна из проблем в книге говорит о выполнении логического сдвига вправо по целому знаку со знаком, я не могу понять, как начать с этого.

Ниже приведен фактический вопрос из книги.

Заполните код для следующих функций C. Функция srl выполняет логическое правое смещение с использованием арифметического сдвига вправо (задается значением xsra), за которым следуют другие операционные переменные, не включающие сдвиги или деление. Функция sra выполняет арифметику сдвиг вправо с использованием логического сдвига вправо (задается значением xsrl), за которым следуют другие операции , не включающие в себя сдвиги или деление. Вы можете использовать вычисление 8 * sizeof (int), чтобы определить w, количество бит в типе данных int. Сдвиг сумма к может варьироваться от 0 до ж - 1.

unsigned srl(unsigned x, int k) { 
    /* Perform shift arithmetically */ 
    unsigned xsra = (int) x >> k; 
    . 
    . 
    . 
} 

int sra(int x, int k) { 
    /* Perform shift logically */ 
    int xsrl = (unsigned) x >> k; 
    . 
    . 
    . 
} 

Я надеюсь, вы понимаете, теперь вопрос.

+0

Вам нужно будет сказать, что вы пробовали, а что не получилось, что вы ожидали. В противном случае ваш вопрос будет закрыт. – xaxxon

+0

Каково ваше замешательство, может быть, было бы лучше, если бы вы отправили фактический вопрос в слово из книги] – aaronman

+0

Извините за плохой вопрос, я только начал задавать вопросы о переполнении стека. –

ответ

2

Я не дам вам полный ответ, так как это, по-видимому домашнее задание, но я дам вам несколько советов, которые помогут вам решить это для себя:

  • для логического сдвига вправо на N битам вам необходимо очистить верхние N бит результата после арифметики сдвига

  • можно очистить биты в значении, применяя соответствующую маску , как правило, с использованием побитового или XOR

  • , чтобы очистить верхние N бит значения вам необходима маска с N 0s и оставшиеся биты 1

  • вы можете создать подходящую маску, используя сдвиг влево от W - N бит, где W представляет собой число бит в слово (которое вы можете рассчитать как W = sizeof(int) * CHAR_BIT;)

eg для логического сдвига вправо на 3

value    = 10001010 
value >>= 3  = 11100010  // arithmetic right shift 

mask    = 00011111  // mask has top 3 bits set to 0 

value & mask  = 00000010  // apply mask to get logical right shift 

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

+0

Спасибо за ваш ответ. –

+0

Я попытаюсь создать эту маску сейчас –

0

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

Сначала я оставил сдвинуты 1 следующим образом

1 << (sizeof(int)*8-k); 

Если я считаю, что к 10 и размер INT в 32 я буду получать следующие маски

00000000010000000000000000000000 (1 at 23 rd position 32 - 10 = 22) 

Затем добавить его с -1 (0xffffffff)

00000000010000000000000000000000 
+ 11111111111111111111111111111111 
+++++++++++++++++++++++++++++++++++ 

    00000000001111111111111111111111 --> required mask with first 10 bits set to 

Anding с результатом арифметического сдвига даст результат логического сдвига.

Ниже приводится код C

unsigned srl(unsigned x, int k) { 
/* Perform shift arithmetically */ 
     unsigned xsra = (int) x >> k; 
    int mask = (1 << (sizeof(int)*8-k)) + -1; 
    int result = xsra & mask; 
} 

И это работает.

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