views:

386

answers:

4
+2  Q: 

Bitwise operations

Hello

A) (Int32)X | ((Int32)Y << 16);

B) (Int32)X + (Int32)Y * (Int32)Int16.MaxValue;

Shouldn't both be equivalent? I know from testing that the first works as expected, but for some reason the second doesn't. Both X and Y are shorts (Int16), and the return type is an integer (Int32).

Shouldn't Y << 16 <=> Y * Int16.MaxValue?

+2  A: 

There are 2 problems with your second approach:

  • Int16 is signed, so the max value is actually only 15 bits.
  • The maximum value that can be represented by 16 bits is 2^16 - 1.
Tal Pressman
+1  A: 
Right-shift 16 bits = * 2^16

But:

Int16.MaxValue = 2^15-1

I think that you want an unsigned 16-bit max value + 1

RBarryYoung
Unsigned 16-bit max value is still 2^16-1.
Tal Pressman
Corrected, thanks.
RBarryYoung
+6  A: 

To get the desired behaviour, you need to multiply with 0x10000 (i.e. UInt16.MaxValue+1). Int16.MaxValue is 0x7fff.

5 << 16
327680

5 * 0x10000
327680

Compare to the decimal system: If you want to "shift" the number 5 to 500, you need to multiply with 100, not 99 :-)

dtb
+1  A: 

Overlooking your MaxValue being one less than power-of-2,
Since, you have a bigger problem to cover first.

The OR and SUM operations are not similar.
When you are working with 32-bit integers and 16-bit shifts,
There will be carries with your + operation and,
bit-wise OR'ing with the OR operation.
So, the two ways are quite different.

Then, of course, the MaxValue interpretation makes your to 'shift' attempts different.
Should be (x * MaxValue + x) or (x * (MaxValue+1))

nik
Since the original values are 16-bit there won't be any carry/overflow.
Tal Pressman
Ah! I seem to have overlooked the int16 reference. Then it is also likely that the compiler will use **OR** anyways.
nik