Reputation: 309
I am aware -that in Java- int is 4 bytes. But I wish to covert an int to n-bytes array, where n can be 1, 2, 3, or 4 bytes. I want to have it as signed byte/bytes, so that if I need to convert them back to int (event if it was 1 byte), I get the same signed int. I am fully aware about the possibility of precision loss when converting from int to 3 or lower bytes.
I managed to convert from int to n-byte, but converting it back for a negative number yield unsigned results.
Edit:
int to bytes (parameter n specify the number of bytes required 1,2,3, or 4 regardless of possible precession loss)
public static byte[] intToBytes(int x, int n) {
byte[] bytes = new byte[n];
for (int i = 0; i < n; i++, x >>>= 8)
bytes[i] = (byte) (x & 0xFF);
return bytes;
}
bytes to int (regardless of how many bytes 1,2,3, or 4)
public static int bytesToInt(byte[] x) {
int value = 0;
for(int i = 0; i < x.length; i++)
value += ((long) x[i] & 0xffL) << (8 * i);
return value;
}
There is probably a problem in the bytes to int converter.
Upvotes: 6
Views: 34146
Reputation: 16545
BigInteger.toByteArray()
will do this for you ...
Returns a byte array containing the two's-complement representation of this
BigInteger
. The byte array will be in big-endian byte-order: the most significant byte is in the zeroth element. The array will contain the minimum number of bytes required to represent thisBigInteger,
including at least one sign bit, which is(ceil((this.bitLength() + 1)/8))
. (This representation is compatible with the(byte[])
constructor.)
Example code:
final BigInteger bi = BigInteger.valueOf(256);
final byte[] bytes = bi.toByteArray();
System.out.println(Arrays.toString(bytes));
Prints:
[1, 0]
To go from the byte array back to a int, use the BigInteger(byte[])
constructor:
final int i = new BigInteger(bytes).intValue();
System.out.println(i);
which prints the expected:
256
Upvotes: 6
Reputation: 200148
Anyway, this is the code I threw together:
public static void main(String[] args) throws Exception {
final byte[] bi = encode(-1);
System.out.println(Arrays.toString(bi));
System.out.println(decode(bi));
}
private static int decode(byte[] bi) {
return bi[3] & 0xFF | (bi[2] & 0xFF) << 8 |
(bi[1] & 0xFF) << 16 | (bi[0] & 0xFF) << 24;
}
private static byte[] encode(int i) {
return new byte[] { (byte) (i >>> 24), (byte) ((i << 8) >>> 24),
(byte) ((i << 16) >>> 24), (byte) ((i << 24) >>> 24)
};
}
Upvotes: 6
Reputation: 109547
Something like:
int unsignedByte = ((int)bytes[i]) & 0xFF;
int n = 0;
n |= unsignedByte << 24;
Upvotes: 1