Home > Mobile >  How do i convert multi-byte integer values to 4bytes array using the two's compliment notation
How do i convert multi-byte integer values to 4bytes array using the two's compliment notation

Time:04-24

I need to convert integers that I send over 4bytes per socket in java. The problem is that when the integer exceeds 9, ie [10, inf] my crash code.

I read in the instructions this line: All multi-byte integer values are encoded using the two's compliment notation in the big-endian order.

The problem is that I don't know how to write the appropriate conversion function. Here is the one I had implemented and which seems to work for integers from 0 to 9. Can someone help me.

byte[] size_buffer = new byte[4];
for (int i = 0; i < 4; i  ) {
   size_buffer[i] = (byte)(msg_size >>> (i * 8));
}

CodePudding user response:

ByteBuffer has nice functionality for this:

byte[] bytes = new byte[4];
ByteBuffer.wrap(bytes)
        .order(ByteOrder.BIG_ENDIAN) // make explicit
        .putInt(intValue);
// bytes is now updated

ByteBuffer Doc in java SE 8

CodePudding user response:

I need to convert integers that I send over 4bytes per socket in java.

Probably no actual conversion is required.

The problem is that when the integer exceeds 9, ie [10, inf] my crash code.

Nothing in what you have presented suggests why that would be, though in fact the conversion presented is wrong.

All multi-byte integer values are encoded using the two's compliment notation in the big-endian order.

This is Java's native representation for type int. You can write ints to the socket's output stream by wrapping it in a DataOutputStream and using DataOutputStream.writeInt(). Or if you are using NIO then you can put an int into a ByteBuffer via the buffer's putInt() method. Either of these approaches sidesteps any need to manually encode integers into byte arrays.

But if you insist on doing your own conversion, completely manually, then this ...

byte[] size_buffer = new byte[4];
for (int i = 0; i < 4; i  ) {
   size_buffer[i] = (byte)(msg_size >>> (i * 8));
}

... reads out the bytes in little-endian order instead of big-endian (most-significant to least). This would be a correct alternative:

byte[] size_buffer = new byte[4];
for (int i = 0; i < 4; i  ) {
   size_buffer[i] = (byte)(msg_size >>> ((3 - i) * 8));
}

CodePudding user response:

You state you tried Inf, but that is not an int value. The only number type you can stick Inf into is double or float, but it's a compiler error to attempt to do >>> to a double or float.

Also, the code snippet you wrote doesn't work for anything - it turns things into little endian order. It treats 9 the exact same way it treats 10: 9 turns into [9, 0, 0, 0] (which is 9 in 2's complement int, but, little endian), and 10 becomes [10, 0, 0, 0].

In other words, you've either thoroughly misanalysed your own code, or you aren't running that snippet.

This will work fine:

int n = -2;
byte[] sizeBuffer = new byte[4];
for (int i = 0; i < 4; i  ) {
   sizeBuffer[i] = (byte)(n >>> (24 - (i * 8)));
}

Turns -1 into [255, 255, 255, 254] (in java bytes are rendered signed, so if you try to print that, it'll probably show as -1, -1, -1, -2. It's the same thing) - and that is indeed -2 in 2's complement big endian.

You can make a ByteBuffer and write that way as well.

  • Related