Search code examples
javabooleanbit-manipulationunsignedsigned

Working around no unsigned variables in java


I'm writing file save and load functions for a specific file format that I have no control over and the format specifies that at a specific byte position I must write 4 bytes of data to signify a 32bit unsigned value... in my test file this value is 16052, or 0x00003EB4... so I write to the data to the byte array that will be saved in this manner:

data[index] = 0xB4;
data[index+1] = 0x3E;
data[index+2] = 0x00;
data[index+3] = 0x00;

You can see the data is in little-endian format, which is correct... the problem is when I try to load this data with my file load function java sees the data in as such:

-76, 62, 0, 0

the 0xB4 value is being interpreted as -76 because bytes are signed in java... when I try to recompose these 4 bytes into a single 32bit value using the following code the value ends up as -76...

value = data[index+3];
value <<= 8;
value |= data[index+2];
value <<= 8;
value |= data[index+1];
value <<= 8;
value |= data[index];

What this should do is the following: set value to 0x00 (high order byte), shift left 8 bits, or 0x00 onto the lower 8 bits, shift left 8 bits, or 0x3E onto the lower 8 bits, shift left 8 bits, or 0xB4 (low order byte) onto the lower 8 bits.

This should produce the value 0x00003EB4... which is what I started with... however for some reason I cannot figure out it is giving me the value -76 after that operation.

I am convinced this is due to java's interpretation of the 0xB4 byte as the value -76 which is screwing up the bitwise OR operation...

My question is what must I do to get around this?

Thank you.


Solution

  • When you are loading the bytes, they are signed. When they are coerced to integers, they are sign extended. To solve this problem, you can do a bitwise AND with 0xFF to take only the 8 LSbs of the signed integer.

    In your case value |= (data[index+i]) should become value |= (data[index+i] & 0xFF) (where i is replaced with the index offsets that you have).