This question already has an answer here:
- Implementing Logical Right Shift in C 8 answers
Right now I am reading the book Computer Systems : Programmer Perspective.
One problem in the book says to perform a logical right shift on a signed integer, I can't figure out how to start on this.
The following is the actual question from the book:
Fill in code for the following C functions.
Function
srl
performs a logical right shift using an arithmetic right shift (given by valuexsra
), followed by other operations not including right shifts or division.Function
sra
performs an arithmetic right shift using a logical right shift (given by valuexsrl
), followed by other operations not including right shifts or division.You may use the computation
8*sizeof(int)
to determinew
, the number of bits in data typeint
. The shift amountk
can range from0
tow − 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; . . . }
I hope you understand now the question.
I won't give you a complete answer as this is apparently homework, but I'll give you some hints to help you work it out for yourself:
for a logical right shift of N bits you need to clear the top N bits of the result after arithmetic shifting
you can clear bits in a value by applying an appropriate mask, typically using a bitwise AND or XOR
to clear the top N bits of a value you need a mask with N 0s and remaining bits 1
you can generate a suitable mask using left shift by
W - N
bits, where W is the number of bits in a word (which you can calculate asW = sizeof(int) * CHAR_BIT;
)E.g. for a logical right shift by 2
The trickiest part is generating the mask, but if you think about left shifts applied so a suitable value, perhaps followed by one further bitwise operation, you should soon see a fairly simple solution.
It took me little time to create the mask as suggested by Paul. But I created it as follows.
First I left shifted 1 as follows
If I consider k to be 10 and INT size as 32 I will get following mask
Then add it with -1 (0xffffffff)
Anding with the result of arithmetic shift will give logical shift result.
Following is the C code
And It works.