views:

122

answers:

4
+2  Q: 

bit shifting in C

int x = 2;

x = rotateInt('L', x, 1); // should return 4

x = rotateInt('R', x, 3); // should return 64

Here is the code, can someone check it and let me know what the error is?

Compilation is successful, but it says Segmentation Fault when I execute it.

int rotateInt(char direction, unsigned int x, int y)
{
  int i;

  for(i = 0; i < y; i++)
  {  

    if(direction == 'R')
    {
       if((x & 1) == 1)
       {
         x = x >> 1;
         x = (x ^ 128);     
       }
       else    
         x = x >> 1;
     }
     else if(direction == 'L')
     {
       if((x & 128) == 1)  
       {
         x = x << 1;
         x = (x ^ 1);     
       }  
       else
       x = x << 1;
     }
   }
   return x;   
 }
+9  A: 

Start honing your debugging skills now. If you are going to be any form of an engineer, you'll need to write programs of some variety, and will thus be debugging all of your life.

A simple way to start debugging is to put print statements in to see how far your code makes it before it dies. I recommend you start by isolating the error.

San Jacinto
it prints nothing but segmentation fault, that is it.
Tim
That mens it's crashing before your first `print` statement. Move the print statement earlier and retry. Repeat until you know which line is causing the segfault
Josh
@Josh that's exactly what I was going to say, thanks. Don't forget to put a \n in your printf statement to flush the stream.
San Jacinto
Yeah, this is good advice @San!
Josh
@Josh thank you , that is really helping.
Tim
For bonus points, learn how to use a debugger. You'll usually find the problem much faster than with printfs.
bstpierre
@bstpierre true, but I figured that if we hadn't discovered printf-debugging yet that we weren't quite ready for the concept of a debugger :)
San Jacinto
+2  A: 

Not sure about the seg fault, but I think

if((x & 128) == 1)  

should be

if((x & 128) == 128)

or just

if(x & 128)  
Andrew Cooper
A: 

When you use ^ don't you mean the or operator | ?

No one in particular
A: 

I tried on my computer (MacBookPro / Core2Duo) and it worked. By the way, what's your target architecture ? Some (many) processors perform rotation instead of shifts when you use the C operators ">>" and "<<".

Antoine Trouve
i do this program on a linux machine, which is run by my instructor..
Tim
OK, so I asmume it is an Intel Machine, which does not rotate (at least it is not the case of ny Intel Core2Duo). However it masks the argument with 0xff in the case of integer rotation (i.e. "0xff00 >> 16 = 0" but "0xff00 >> 40 = 0xff").
Antoine Trouve
A compiler that did an actual bit rotation rather than a pure shift for the `<<` and `>>` operators would be non-compliant. I don't see any wiggle-room in the definitions of the operators. They are shifts and not rotates, and have been since the dawn of the language. See C99, section 6.5.7 where it says "The result of `E1 << E2` is `E1` left-shifted `E2` bit positions; vacated bits are filled with zeros." It goes on to describe the boundaries of the defined behavior in gory detail. Right shifts are described similarly, but with slightly different boundaries.
RBerteig
It is not a matter of compiler, but processor. For instance PowerPC's shift instruction does rotation.
Antoine Trouve
@Antoine, shifting by more bits than the number of bits in your integral type is explicitly Undefined Behavior. Anything can happen. The compiler is not obligated to be "reasonable" or to generate code that does something "reasonable".
RBerteig
@Antoine, rotation is simply not allowed as the implementation of the << operator. The language of the standard is *extremely* clear. It goes on to say that `E1<<E2` is equivalent to multiplication by a power of 2, as long as the values are in bounds. It is also clear that shifting by a zero or negative amount is UB, as is shifting by more than the bits in the integral type.
RBerteig
OK, but "0xff00 << 24" with gcc on my PowerPC retrieves "0xff". So I guess you can say that gcc does not fit the standard, but we are working with compilers, not standards. Anyway, for my personal enhancement (sorry for Josh), do you have a link to the part of the reference which says that ?
Antoine Trouve
@Antoine gcc on Suse x86_64 produces 0 for me with that operation. I HIGHLY doubt that gcc made an exception to break the standard just for the PowerPC architecture.
San Jacinto