2

I was looking into when one would want to/should use the bit shift operators. I understand that we don't need to use them to multiply by two and such, because JIT compilation will take care of that. I came across why do we need to use shift operators in java, and am confused by part of the accepted answer:

For example, say I have two bytes that are the high-order and low-order bytes
of a two-byte (16-bit) unsigned value. Say you need to construct that value. 
In Java, that's:

int high = ...;
int low = ...;
int twoByteValue = (high << 8) | low;

You couldn't otherwise do this without a shift operator.

To answer your questions: you use them where you need to use them! and nowhere else.

I know that I'm missing something, because to me it looks like he's just multiplying high by 2^8 and adding it to low (I've never actually seen | used in this context before, but when I plugged in dummy values and ran my code, it looked like it was just adding the two together). What's actually going on here?

EDIT: For reference, I had high = 10 and low = 3.

Community
  • 1
  • 1
Steve P.
  • 14,489
  • 8
  • 42
  • 72

1 Answers1

3

As an example, lets compose the 16-bit representation of the number 54321: 1101 0100 0011 0001 from its high-order 8 bits and low-order 8 bits.

The high-order 8 bits would be: 1101 0100 The low-order 8 bits would be : 0011 0001

1101 0100 << 8

will produce

1101 0100 0000 0000

We then bitwise OR this (|) against the low order bits

1101 0100 0000 0000
          0011 0001
-------------------
1101 0100 0011 0001

We now have the full binary representation on 54321 (assuming I'm using unsigned ints of course)


Edit: To use your example: high=10 and low=3

high, written out in 8 bits, would be 0000 1010

low, written in the same fashion, would be 0000 0011

If we shift high to the left 8 bits:

0000 1010 0000 0000

If we OR that against low:

0000 1010 0000 0000
          0000 0011
-------------------
0000 1010 0000 0011

If we treat this pattern as a decimal integer it would mean 2563

Perhaps the confusing part is that the 10 and 3 independently really hold no meaning at all in this context. It is the composition of the two that has value here.

Perhaps you are reading a file byte by byte but in one part of the file there is a sequence of 16-bit integers. You would have to take every pair of bytes and combine them in exactly this fashion to get the 16-bit integers.

Now imagine if, on a platform where the largest integer possible is 64 bits, you wanted to store an integer that is so large it occupies 128 bits. Well, you could use a trick similar to this one to fudge the math and store that really big integer in two separate values. OK, maybe its more complicated than this example, but hopefully that makes it hit home why we would need bitwise operators like these.

Brian
  • 3,091
  • 16
  • 29
  • My issue was that I thought that this was simply multiplying by 2^8 and adding, but that's only true in some cases. This makes sense now. Thanks. – Steve P. Jun 21 '13 at 04:14