1

I was reading through examples trying to understand how to convert signed bytes to unsigned integer counter parts.

The most popular method that I have come across is:

a & 0xFF

Where a is the signed byte.

My question is why is 0xFF stored as unsigned? Are all hex values stored as unsigned? If so why?

And how does "and"-ing turn off the sign bit in the sign integer?

It would be great if someone could break down the process step by step.

Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79
Machina333
  • 602
  • 5
  • 15

3 Answers3

4

You probably saw this in code that converted a byte to an integer, where they wanted to treat the byte as an unsigned value in the range 0-255. It does not apply to integers in general. If you want to make an integer a "unsigned", you can do:

int unsignedA = a & 0x7FFFFFFF;

This will ensure that unsignedA is positive - but it does that by chopping off the high bit, so for example if a was -1, then unsignedA is Integer.MAX_VALUE.

There is no way to turn a 32-bit signed Java integer into a 32-bit unsigned Java integer because there is no datatype in Java for a 32-bit unsigned integer. The only unsigned integral datatype in Java is 16 bits long: char.

If you want to store a 32-bit unsigned integral value in Java, you need to store it in a long:

long unsignedA = a & 0xFFFFFFFFL;
Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79
  • Yes you are right, I have edited my question. I understood better from this answer. http://stackoverflow.com/a/3388321/5826291 – Machina333 Feb 04 '16 at 05:30
2

To elaborate on Erwin's answer about converting a byte to an integer: In Java, byte is a signed integer type. That means it has values in the range -128 to 127. If you say:

byte a;
int b;
a = -64;
b = a;

The language will preserve the value; that is, it will set b to -64.

But if you really want to convert your byte to a value from 0 to 255 (which I guess you call the "unsigned counterpart" of the byte value), you can use a & 0xFF. Here's what happens:

Java does not do arithmetic directly on byte or short types. So when it sees a & 0xFF, it converts both sides to an int. The hex value of a, which is a byte, looks like

a      =       C0

When it's converted to a 32-bit integer, the value (-64) has to be preserved, so that means the 32-bit integer has to have 1 bits in the upper 24 bits. Thus:

a      =       C0
(int)a = FFFFFFC0

But then you "and" it with 0xFF:

a      =       C0
(int)a = FFFFFFC0
       & 000000FF
         --------
a & FF = 000000C0

And the result is an integer in the range 0 to 255.

ajb
  • 31,309
  • 3
  • 58
  • 84
0

In Java, literals (1, 0x2A, etc) are positive unless you explicitly indicate that they are negative. It's how we intuitively write numbers.

This previous question answers you question about converting to unsigned. Understanding Java unsigned numbers

Community
  • 1
  • 1
Matthew Pope
  • 7,212
  • 1
  • 28
  • 49