0

I am working on bit shifts, and I've run into this problem.
I have two int:

int x = 1;
int y = 2;

What is the difference between:

 x = x << (31 + 1);

and

 y = y << 31;

I thought the result would be the same (namely that x and y would both equal 1) , but they aren't.....I don't understand why. 2 is just 1 with a "1" bit moved one space to the left.

Thanks!

I mean when we can't shift-left anymore, don't we wrap around to the beginning?

EDIT: Let me clarify what I THINK is going on:

We start with x = 1, so that's:

 00000000 00000000 00000000 00000001

We then left shift that by 31 +1 (or 32). That gives us:

 00000000 00000000 00000000 00000001

which is also 1.

Then we do y = 2, so that's

 00000000 00000000 00000000 00000010

We left shift that by 31. That also gives us:

 00000000 00000000 00000000 00000001

Therefore, we get x = y = 1. I know this is wrong, but can anyone explain why???

pauliwago
  • 6,373
  • 11
  • 42
  • 52
  • There's not enough information here to give you any assistance. You need to at least say (1) what you expect, and (2) what you get. Also specifying the data types that you're using (int, long, etc) would be enormously helpful. – Chris Eberle Oct 13 '12 at 17:46
  • Edited as you requested! – pauliwago Oct 13 '12 at 17:50
  • What do you get? You only mention they are not equal. – Bart Friederichs Oct 13 '12 at 17:52
  • If I shift too far, I get a compiler warning and now shifting at all takes place. For values lower than 32, the result is indeed equal. – Bart Friederichs Oct 13 '12 at 17:55
  • y << 31 gives me the behavior I want; x << 32 doesn't. I just want to know why this is the case. So are you saying shifting by anything over 31 is going to cause problems automatically? If we shift y << 31, that will wrap around successfully? Thanks. – pauliwago Oct 13 '12 at 17:57
  • 1
    In fact, 2<<31 gives 0 with my compiler / platform. As said in the answer, shifting is not the same as rotating. – Bart Friederichs Oct 13 '12 at 17:58

3 Answers3

1

You are confusing shifting with rotating:

  • Shifting means shifting all bits and filling the empty spot with a 0 or a 1 (depending on value and/or signedness).

  • Rotating is shifting all bits and filling the empty spot with the bit that "fell out" in the end.

AFAIK C does not support rotating, but only shifting (probably because of platform dependencies?). x86 assembler implements both shift and rotate operations.

A explanation better than I can give here, can be found here: http://en.wikibooks.org/wiki/X86_Assembly/Shift_and_Rotate

Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195
0

I mean when we can't shift-left anymore, don't we wrap around to the beginning?

No. That behavior is called circular shifting and it's not how the shift operators work in C.

(By the way, for me, both expressions result in 0 as per printf("%d %d\n", 1 << (31 + 1), 2 << 31);, but this is not very meaningful, since signed integer overflow is undefined behavior.)

  • I guess he might be compiling using warnings, the <<32 for me always triggers a warning, unlike 2<<31. This is really compiler dependent, not language related. – perh Oct 13 '12 at 17:53
  • In fact, in assembly, circular shift is called rotate. More info here: http://en.wikibooks.org/wiki/X86_Assembly/Shift_and_Rotate – Bart Friederichs Oct 13 '12 at 17:59
0

As mentioned by H2CO3, the behavior is undefined. You can reference C99 6.5.7 for some more information. Also, this question is very similar, if not identical to yours. You might find some good information there too.

My system mods the shift by 32, incidentally.

Community
  • 1
  • 1
NickO
  • 731
  • 1
  • 6
  • 20