I am working on java. I am wondering why java producing this output. I am sharing the code here.
public class vvn {
public static void main(String[] args)
{
byte [] arr = new byte[4];
arr[0] = (byte)157;
arr[1] = 1;
arr[2] = 0;
arr[3] = 0;
System.out.format("read 0x%x 0x%x 0x%x 0x%x \n",arr[3],arr[2],arr[1],arr[0]);
int v = (arr[0] | (arr[1] << 8) | (arr[2] << 16) | (arr[3] << 24));
System.out.format("read 0x%x\n",v);
}
}
And I got the output as
read 0x0 0x0 0x1 0x9d
read 0xffffff9d
I expected the output should be 0x0000019d
You are converting from byte (signed 8 bits) to integer (signed 32 bits). The most significant bit (the leftmost one) holds the sign (see two's complement).
Your
157
is10011101
in binary. Since you assign this value to a signed byte (java has no unsigned byte), this is in fact a negative number,-99
.Now when you convert from byte to int, the value is preserved. In case of negative numbers, this means setting all the bits to the left to preserve the signedness. In your case,
10011101
becomes11111111 11111111 11111111 10011101
.Anyway, working with unsigned bytes in java is a nightmare. Basically, you need to mask everything with 0xff (to cut off the 'ones to the left') like this:
Beautiful, isn't it?
Update 1: Also, you may be interested in Guava's UnsignedBytes...
Update 2: Java 8 Byte has toUnsignedInt() and toUnsignedLong() methods. Your calculation thus becomes: