2
Decimal         Binary 

x1 = 105        0110 1001
x2 = -38        1101 1010  

1. (byte) (x>>2) 
2. (byte) (x>>>26)

I understand the first shift will shift it two times to the right, and replace the missing bits with a 1. so the shift results in: 1111 0110

but I have no idea why the second shifts results in: 0011 1111 or 63.

My understanding is that the x >> adds 1 if x is negative and adds a 0 if x is positive. The >>> adds a 0 regardless of the sign. So if that is the case wouldn't the result of x2 >>> 26 be 0000 0000?

Federico klez Culloca
  • 26,308
  • 17
  • 56
  • 95
  • 3
    `(byte) (x>>>26)` first shifts, then casts to `byte`. What type was `x`? I bet it was wider than 8 bits. – Federico klez Culloca Feb 21 '19 at 15:44
  • 1
    Might help. [Bitwise Tutorial](https://www.geeksforgeeks.org/bitwise-shift-operators-in-java/) as @FedericoklezCulloca said; you may want to experiment with using an int to hold the correct value. I found casting variables to be tricky even when trying to write high performance networking when I first started trying bit shifting.. – Mr00Anderson Feb 21 '19 at 15:45
  • x2 is a byte also – blondiefunk69 Feb 21 '19 at 15:46
  • 1
    Ok, please fix your example (including types for `x1` and `x2` and placing the correct thing instead of `x` in the shifts. – Federico klez Culloca Feb 21 '19 at 15:47
  • Please also take a look at [Stackoverflow Printing Bits Representation](https://stackoverflow.com/questions/5263187/print-an-integer-in-binary-format-in-java) this may help you debug whats happening with your bit shifts. EDIT: I personally use @M2X answer. – Mr00Anderson Feb 21 '19 at 15:51
  • 2
    I don't think the types matter, because the values are widened to 32 bit (`int`) before the shift anyway. I. e. -38 isn't `1101 1010` here, but `1111 1111 1111 1111 1111 1111 1101 1010`. Which should make it clear why `-38 >>> 26` is `0000 0000 0000 0000 0000 0000 0011 1111` (63). – Harald K Feb 21 '19 at 15:54
  • 1
    Since you'll edit your question anyway, can you plaese provide a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) (that is, a small program that shows what your problem is). – Federico klez Culloca Feb 21 '19 at 15:54

1 Answers1

4

The reason for the "strange" bit shift result is because the values are widened to 32 bit (int) before the shift.

I. e. -38 isn't 1101 1010 here, but 1111 1111 1111 1111 1111 1111 1101 1010.

Which should make it clear why -38 >>> 26 is 0000 0000 0000 0000 0000 0000 0011 1111 (or 63).

The widening is described in the the Java Language Specification:

Otherwise, if the operand is of compile-time type byte, short, or char, it is promoted to a value of type int by a widening primitive conversion (§5.1.2).


If you want to perform bit shift operations on an 8 bit (byte) value, you could mask the value to use only the lower 8 bits, after widening but before shifting, like Federico suggests:

byte x = -38;
(x & 0xFF) >>> 26;

This would give the expected value of 0 (though I'm not sure if it makes sense, as any 8 bit value will be 0 if you right shift by more than 8).

Harald K
  • 26,314
  • 7
  • 65
  • 111
  • If `x` is a `byte` you would probably want `(x & 0xFF) >>> 26`, but yes, it would make the result 0, if that is the goal. – Harald K Feb 21 '19 at 16:15
  • Sorry, I got carried away with the `F`s. Anyway, yes, I think that's what they're trying to achieve. By "solve the problem" I meant "give the expected result". – Federico klez Culloca Feb 21 '19 at 16:17
  • thanks all! it's not a program per say, it's more of practice exercise in using bit operators. why is -38 represented as 1111 1111 1111 1111 1111 1111 1101 1010?@haraldK – blondiefunk69 Feb 21 '19 at 16:44
  • @blondiefunk69 If this is indeed an exercise, I'll leave it to you to figure that out. Here's some suggested reading though: [Two's complenent](https://en.wikipedia.org/wiki/Two%27s_complement). ;-) – Harald K Feb 22 '19 at 07:47