3

I am right shifting an unsigned int by 32 but it doesn't affect the number at all, why is it happening?

int main()
{
  unsigned int rnd=2347483648;
  cout<<rnd;
  rnd=rnd>>32;
  cout<<endl<<rnd;
}

When the code runs, it displays rnd twice,showing no affect at all. I believe that after right shifting a 32 bit int, shouldn't it display zero?

Ahmed
  • 2,176
  • 5
  • 26
  • 40
  • 1
    Gotta love these "core language feature X not working" questions... couldn't you just pay a little more attention to the book/tutorial you are reading? –  Jan 14 '14 at 13:10
  • Well rnd=rnd>>32 shows the same result, i tried that too... but it should display 0 right? – Ahmed Jan 14 '14 at 13:12
  • Now see the question again, this is the question actually.. – Ahmed Jan 14 '14 at 13:13
  • Oh, I see. It is marked as a duplicate. I have to admit that the title of this question is much better and search-friendlier. To be honest, quite likely the question is duplicate only once you know the answer and know where to look for duplicates. – Roland Pihlakas May 08 '15 at 09:47

5 Answers5

11

You are missing an assignment operator - the >> shift operator does not perform the operation "in-place":

rnd = rnd >> 32;

You could also use the compound shift operator, which applies the shift operation and then assigns the result back to the variable:

rnd >>= 32;

However, in both cases, this code results in undefined behaviour, see Shifting a 32 bit integer by 32 bits:

If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

So you could get any result from that operation.

Community
  • 1
  • 1
Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
  • 1
    Note that there's also compound shift operators, `a <<= b` and `a >>= b` – SBI Jan 14 '14 at 13:12
  • @SBI good point - that would probably count as "in-place" :) – Andreas Fester Jan 14 '14 at 13:13
  • see the question now... this is what i mean.... shifting by 32 should result 0 but why it's not happening? – Ahmed Jan 14 '14 at 13:15
  • 4
    Read the answer carefully. The important point is: This is undefined behavior! That means: It should not result in 0. It can be anything, including NOP. – dornhege Jan 14 '14 at 13:19
  • Under x86 that "undefined" behaviour means that shifting does not occur. The second argument is interpreted modulo the first argument width in bits. So, shift 33 bits means shift 1 bit. Shift 64 bits means again no shift. – Roland Pihlakas May 08 '15 at 09:45
4

Shifting by the number of bits in the promoted operand type, or more, gives undefined behaviour. unsigned int is typically 32 bits, so that typically applies when shifting by 32 or more bits as you do here.

This is because different processors behave in different ways when a shift overflows, and the language designers didn't want to prevent implementations from using the processor's built-in shift instruction by specifying a particular behaviour.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
3

The bit-shift operator doesn't modify the original data. It simply returns a modified copy.

I think this is what you meant to do:

rnd = rnd >> 32;

Assuming your unsigned int is 32-bits in size though, that's not really a useful operation to do.

Peter Bloomfield
  • 5,578
  • 26
  • 37
  • It tried that too... but result is same – Ahmed Jan 14 '14 at 13:09
  • You'll probably find that shifting by a smaller amount will work. Shifting beyond the range of the data type can result in undefined behaviour. On some builds/compilers it may zero the variable, on others it may fill it with garbage data, or simply do nothing at all. Basically, don't do it. :) – Peter Bloomfield Jan 14 '14 at 13:15
  • i don't understand why down votes, it's basically an important issue that why isn't it showing zero because i'm implementing universal hashing and i need it to return 0 (which is quite logical) for my hash function to index hash table – Ahmed Jan 14 '14 at 13:19
  • 1
    It might seem logical to you, but it's not how the language is designed. If you want a 0 then just assign 0 manually. – Peter Bloomfield Jan 14 '14 at 13:57
1

you foget to assign the value to rnd

rnd = rnd>>32
michaeltang
  • 2,850
  • 15
  • 18
1

You forgot to assign the result:

rnd = rnd >> 32;
pentadecagon
  • 4,717
  • 2
  • 18
  • 26