I have been fighting with this for a while, I'm trying to calculate a checksum for a byte[] as the 1s complement of the 1s complement sum of 16 bit words in the array. The sum is fairly easy (though I'm sure I could be more efficient) but when I flip the bits and get a 'negative' value it sign extends to 4 bytes. performing bitwise and with 0xff gives me the proper value, but because I'm trying to include the checksum in another byte array I need it as a byte. Casting back to a byte gives me the 4 byte int again. Bizarrely, I can store this (4 byte) value in a byte array and print it without causing issues. Is there any way to force Java to leave me with just one single byte with a negative sign bit? In this particular example the bytes are 0xef and 0xfd.
My code for calculating the checksum is:
public byte[] checksum (byte[] b) {
byte[] check = new byte[3] ;
check[1] += b[0];
check[2] += b[1];
check[1] += b[2];
check[2] += b[3];
check[1] += b[4];
check[2] += b[5];
check[1] += b[6];
check[2] += b[7];
check[1] += b[8];
check[2] += b[9];
check[1] += b[10];
check[2] += b[11];
check[1] += b[12];
check[2] += b[13];
check[1] += b[14];
check[2] += b[15];
check[1] += b[16];
check[2] += b[17];
check[1] += b[18];
check[2] += b[19];
check[2] += check[0] ;
byte[] ret = new byte[2] ;
ret[0] = (byte)~check[1];
ret[1] = (byte)~check[2];
return ret ;
}
Again to be clear, this gives me a byte[] with size 2, where each element seems to be 4 bytes.
Printing the returned array with
byte[] r = checksum (b);
for (int i = 0; i < r.length; ++ i) {
System.out.println (String.format("0x%2s", Integer.toHexString(r[i])).replace(' ', '0')) ;
}
displays
0xffffffef
0xfffffffd
How is that even possible, and how can I avoid it? If it's just a display issue that's fine, but it looks like each element of my returned array is actually 4 bytes.
The problem isn't in your byte array, it's in how you're printing it. Integer.toHexString()
expects an int
. When you pass a byte
as int
, an automatic widening conversion is performed, which includes sign extension. You can undo the effects of sign extension like this:
Integer.toHexString(r[i] & 0xFF)
User contributions licensed under CC BY-SA 3.0