Getting unsigned bytes in java

Welcome back after long overwork and vacation period :) Let’s start small, it’s still almost summer.

Bytes in java are always signed and are quite horrible to use because of the casting and weird side-effects (or I’m just stupid enough to call it weird).

But we need unsigned bytes quite a lot. Most of the time for reading various streams (networks, 8bit strings etc) some text stream you still end up with byte streams.

There is a nice trick converting them from signed to unsigned in case you want to get normal 0..255 range for the chars.

byte mybyte = -104;
long mynewint = mybyte & 0xFF;

Hope it helps!

I had quite a nice puzzling while trying to find some easier way. Is there?

4 Comments

  1. Nice entry!

    Though if you have, say:
    byte mySignedByte = 0xFE; // = 254 decimal

    You can also do (pseudo code) :
    int num = 16 * ((mySignedByte & 0xf0) >> 4) + mySignedByte & 0x0f

    And of course there is the hard method:
    int num = Byte.valueOf(mySignedbyte).intValue();

    Sincerely,

    Ellie P.

    Ellie
    Posted August 21, 2008 at 11:17 am | Permalink
  2. thanks for the feedback!

    Not sure what is pseudocode expected to do. For 0xFE case (signed byte -2) the equation returns 14;
    Bit-shifting and multiplying is not needed to trim the sign by half-bytes.

    To fix it, mySignedByte&0xf0+(mySignedByte&0x0f) would work (equally to mySignedByte&0xff).

    Well, this hard method is behaving like it should – preserves the sign – so no help:

    “byte mySignedByte = 0xFE;” is illegal code (cannot convert from int to byte) so one should either use
    “(byte) 0xFE;” or “Integer.valueOf(0xFE).byteValue();”.

    Both give signed byte (-2 for this case).

    Next, Byte.valueOf(mySignedbyte).intValue() gives back -2, signed int.

    Byte is signed, however we tweak the bits and intValue() is and should respect the sign bit.

    Posted August 22, 2008 at 7:16 am | Permalink
  3. You are absolutely right, Ahti – at least this is the most optimal way I could think of as well.

    Any other variations such as :
    int i = b<0 ? b+256 : b;
    are maybe simplier to read, but heavier in terms of performance.

    Now to Ellie's version. It returns 14, however because of operator precedence.
    The actual "correct" formula he meant (I think so at least) is:
    int num = 16 * ((mySignedByte & 0xf0) >> 4) + (mySignedByte & 0x0f);
    Otherwise the last &0x0f will be executed last and trim the 4 MSBs.

    It is correct btw, but the question here is why to do it, since it’s actually &0xff.
    And the pattern 16 * (X >> 4) is a nice way to obfuscate identity, kinda pseudo-security by obscurity :)

    Vadim.

    vb@vb
    Posted August 22, 2008 at 3:11 pm | Permalink
  4. Ahh yes correct. I forgot about the possibility for wrong order of operator precedence, just copied it to java to make sure.

    Posted August 22, 2008 at 3:29 pm | Permalink

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Anti-Spam Protection by WP-SpamFree