Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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.

share|improve this question
5  
Post your conversion code. – Marko Topolnik Jul 10 '12 at 21:07
I just updated the question – ccit Jul 11 '12 at 7:23
add comment (requires an account with 50 reputation)

3 Answers

up vote 2 down vote accepted

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
share|improve this answer
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. – ccit Jul 11 '12 at 7:22
I ended up using new BigInteger(bytes).intValue() for my bytesToInt – ccit Jul 11 '12 at 10:00
add comment (requires an account with 50 reputation)

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)
  };
}
share|improve this answer
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 – ccit Jul 11 '12 at 7:19
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. – Marko Topolnik Jul 11 '12 at 7:53
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. – ccit Jul 11 '12 at 8:53
You need to sign-extend the int if it's less than 4 bytes. Or just use BigInteger for decoding. – Marko Topolnik Jul 11 '12 at 8:55
add comment (requires an account with 50 reputation)

Something like:

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

int n = 0;
n |= unsignedByte << 24;
share|improve this answer
add comment (requires an account with 50 reputation)

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.