I am porting some C code that uses a lot of bit manipulation into Java. The C code operates under the assumption that int is 32 bits wide and char is 8 bits wide. There are assertions in it that check whether those assumptions are valid.
I have already come to terms with the fact that I'll have to use long
in place of unsigned int
. But can I safely use byte
as a replacement for unsigned char
?
They merely represent bytes, but I have already run into this bizarre incident: (data
is an unsigned char *
in C and a byte[]
in Java):
/* C */
uInt32 c = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
/* Java */
long a = ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]) & 0xffffffff;
long b = ((data[0] & 0xff) << 24) | ((data[1] & 0xff) << 16) |
((data[2] & 0xff) << 8) | (data[3] & 0xff) & 0xffffffff;
You would think a left shift operation is safe. But due strange unary promotion rules in Java, a
and b
are not going to be the same if some of the bytes in data
are "negative" (b
gives the correct result).
What other "gotchas" should I be aware of? I really don't want to use short
here.