логический сдвиг прямо на подписанных данных

Прежде всего, нет, это не моя домашняя работа, это лаборатория, которую дала книга под названием «Компьютерные системы: взгляд программиста» (кстати, отличная книга)

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

  • Кастинг
  • если, while, выберите, для, do-while,?:
  • указатели любого типа

Разрешенные операторы:
! + ~ | >> << ^

Что я пробовал до сих пор?

/*
* logicalShift - shift x to the right by n, using a logical shift
*   Can assume that 0 <= n <= 31
*   Examples: logicalShift(0x87654321,4) = 0x08765432
*   Legal ops: ~ & ^ | + << >>
*   Max ops: 20
*   Rating: 3
*/
int logicalShift(int x, int n) {
int mask = ~0;
int shiftAmount = 31 + ((~n)+1);//this evaluates to 31 - n on two's complement machines
mask = mask << shiftAmount;
mask = ~mask;//If n equals 0, it means we have negated all bits and hence have mask = 0
x = x >> n;
return x & mask;
}

Это работает просто отлично, если n не равно 0, когда это делает этот код, обрывается, потому что маска превратится во все 0 и функция вернет 0.

Я был бы признателен за любую подсказку в правильном направлении, а не полный код.

Опять же, это не домашняя работа; лабораторные задания находятся в открытом доступе здесь http://csapp.cs.cmu.edu/public/labs.html

P.S Не дублировать, не публиковать решения, которые включают приведение к неподписанному и затем смещение.

8

Решение

Вы можете сделать маску таким образом:

int mask = 1 << shiftAmount;
mask |= mask - 1;

Что по сравнению с другим подходом, как это

                    this approach | other approach
can have 0 bits set :     no      |      yes
can have 32 bits set:    yes      |       no
5

Другие решения

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

int logicalShift(int x, int n) {
int mask = ( 1 << sizeof(int) - n ) - 1;
return x >> n & mask;
}

Маска устанавливает самый верхний n биты в 0.

Конечно, это можно записать как:

int logicalShift(int x, int n) {
return x >> n & ( 1 << sizeof(int) - n ) - 1;
}

Но компилятор, вероятно, поймет, как оптимизировать первый.

0

По вопросам рекламы [email protected]