I'm working on making a logical right shift function in C using only bitwise operators. Here's what I have:
int logical_right_shift(int x, int n)
{
    int size = sizeof(int); // size of int
    // arithmetic shifts to create logical shift, return 1 for true
    return (x >> n) & ~(((x >> (size << 3) - 1) << (size << 3) -1)) >> (n-1);
}
This actually works for all cases except if n = 0. I've been trying to figure out a way to fix it so it will work for n = 0 as well, but I'm stuck.
int lsr(int x, int n)
{
  return (int)((unsigned int)x >> n);
}
                        This is what you need:
int logical_right_shift(int x, int n)
{
    int size = sizeof(int) * 8; // usually sizeof(int) is 4 bytes (32 bits)
    return (x >> n) & ~(((0x1 << size) >> n) << 1);
}
Explain
x >> n shifts n bits right. However, if x is negative, the sign bit (left-most bit) will be copied to its right, for example:
Assume every int is 32 bits here, letx     = -2147483648 (10000000 00000000 00000000 00000000), thenx >> 1 = -1073741824 (11000000 00000000 00000000 00000000)x >> 2 = -536870912  (11100000 00000000 00000000 00000000)
and so on.
So we need to erase out those sign extra sign bits when n is negative.
Assume n = 5 here:   
0x1 << size moves 1 to the left-most position:    
(10000000 00000000 00000000 00000000)
((0x1 << size) >> n) << 1 copies 1 to its n-1 neighbors:    
(11111000 00000000 00000000 00000000)
~((0x1 << size) >> n) << 1! reverses all bits:
(00000111 11111111 11111111 11111111)
so we finally obtain a mask to extract what really need from x >> n:
(x >> n) & ~(((0x1 << size) >> n) << 1)
the & operation does the trick.
And the total cost of this function is 6 operations.
Just store your int in an unsigned int, and perform >> upon it.
(The sign is not extended or preserved if you use unsigned int)
http://en.wikipedia.org/wiki/Logical_shift
I think problem is in your ">> (n-1)" part. If n is 0 then left part will be shift by -1. So,here is my solution
int logical_right_shift(int x, int n)
{
  int mask = ~(-1 << n) << (32 - n);
  return  ~mask & ( (x >> n) | mask); 
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With