6

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.

0

3 Answers 3

6

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 this BigInteger, 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
Sign up to request clarification or add additional context in comments.

2 Comments

I am aware of BigInteger. But BigInteger return exact bytes not 1,2,3, or 4 as instructed. for example 5 will be 1 byte always, but I want the option to have it 2/3/4-bytes.
I ended up using new BigInteger(bytes).intValue() for my bytesToInt
6

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)
  };
}

4 Comments

This is for 4 bytes only, and not for 1,2,3, or 4 bytes and back to int as I stated in my question. Also, see what you asked for. Thanks
So what stops you from picking up the ideas from my code, since it's working? You need to replace your + with |. Your use of a long is uncalled for, btw.
Mine is working with 4 bytes, btw. Use of long is left there after trial and errors, and I should have removed it before posting. And replacing + with | changed nothing. The problem is with bytes less than 4 having negative int.
You need to sign-extend the int if it's less than 4 bytes. Or just use BigInteger for decoding.
1

Something like:

int unsignedByte = ((int)bytes[i]) & 0xFF;

int n = 0;
n |= unsignedByte << 24;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.