Shifting bytes left in different languages

Recently I must have had a really bad day, because I wrote a very stupid line of code in java:

int x = 2 << (s - 1);

when I wanted something a little simpler:

int x = 1 << s;

It gave unexpected (for me) behavior for shifting negative number of bits. I was having hope that shifting -1 place left would be equal to shifting 1 place right. But I was wrong, and the result was always zero, no matter what number I would try to shift. After a little search I have found: Bitwise and Bit Shift Operators but is says nothing about this case.

So I tried the same code in different languages to check how they behave. I started with my favorite – Ruby:

def shift(no, s) 
  [no << (s - 1), (no << s) / 2]
end
shift(2, 8) # => [256, 256]
shift(2, 1) # => [2, 2]
shift(2, 0) # => [1, 1]
shift(256, -4) # => [8, 8]

Here the results were as I would like them to be.

So what does our good, old friend C has to say?

#include <stdio.h>
void shift(int no, int s) {
  int one = no << (s - 1);
  int two = (no << s) / 2;
  printf("Shift(%d, %d): %d, %d\n", no, s, one, two);
}
int main() {
  shift(2, 8); // 256, 256
  shift(2, 1); // 2, 2
  shift(2, 0); // 0, 1
  shift(256, -4); // 0, 0
  return 0;
}

It gives the same results as Java code. So I have to assume that it is described in some specification, or maybe is processor specific as shifting is simple assembler instruction.

Last language I have tried is Ruby companion, Python, which behave more elegantly than C or Java:

def shift(no) :
  return (2 << (no - 1), (2 << no) / 2)
print shift(8) # (256, 256)
print shift(1) # (2, 2)
print shift(0) # ValueError: negative shift count

It actually checked for nonsensical value and raised an exception not giving me silently wrong (from my perspective) value. Sadly Python does not behave similarly for other basic mistakes, as:

>>> 2 < "1"
True

Comments
blog comments powered by Disqus
[Valid Atom 1.0]
Fork me on GitHub