sparrow
sparrow

Reputation: 460

Putting 2 integer values to make a long

I took over a project that has a spec partly implemented. I have a message with various fields. One of the fields has an ID (called DestinationID) of type long. Within this ID, it says the first 4 bytes(let's call it left) represent something one thing and the other 4 bytes(let's call it right) represents another. Currently, it's been implemented as 2 ints. Giving that I have these 2 ints, is there a way to put it back together to get the original long value? Also, these fields are little endian, so the 2 ints are read as little endian. And when putting together I want to get a little endian long too. I've doing trial and error and below are my results so far. Please point out any errors you see. Thank you.

    int left = 262388740;  // 1st 4 bytes
    int right = 671091961; // Rest of 4 bytes

    long destinationID = ((right) << 32) | (left & 0xffffffffL); // Trying to put the 2 together to get the long value

    //Expected - f9 0c 00 28  04 bc a3 0f
    //Received - 28 00 0c f9  0f a3 bc 04 

When I print (Long.toHexString(destinationID), I don't get the expected value. They seem reversed.

Upvotes: 0

Views: 68

Answers (2)

Darkman
Darkman

Reputation: 2981

Try this.

int left = 0x0FA3BC04; //262388740;  // 1st 4 bytes
int right = 0x28000CF9; //671091961; // Rest of 4 bytes

long destinationID = ((right & 0xFFL) << 56) | ((right & 0xFF00L) << 40) | ((right & 0xFF0000L) << 24) | ((right & 0xFF000000L) << 8) | ((left & 0xFFL) << 24) | ((left & 0xFF00L) << 8) | ((left >> 8) & 0xFF00L) | ((left >> 24) & 0xFFL);
        
System.out.printf("left: %08X%n", left); //left: 0FA3BC04
System.out.printf("right: %08X%n", right); //right: 28000CF9
System.out.println("Expected - f9 0c 00 28  04 bc a3 0f");
System.out.println(Long.toHexString(destinationID)); //f90c002804bca30f

Explanation.

Let change the value of left and right for clarity.

int left = 0x01234567; int right = 0x89ABCDEF;

  1. ((right & 0xFFL) << 56) = filter 8 rightmost bits or 1 byte (0x00000000000000_EF), then pad with 56 bits or 7 bytes of zeros to its right (0xEF_00000000000000).
  2. ((right & 0xFF00L) << 40) = filter 16 rightmost bits or 2 bytes (0x000000000000_CD00), then pad with 40 bits or 5 bytes of zeros to its right (0x00CD00_0000000000).
  3. ((right & 0xFF0000L) << 24) = filter 24 rightmost bits or 3 bytes (0x0000000000_AB0000), then pad with 24 bits or 3 bytes of zeros to its right (0x0000AB0000_000000).
  4. ((right & 0xFF000000L) << 8) = filter 32 rightmost bits or 4 bytes (0x00000000_89000000), then pad with 8 bits or 1 byte of zeros to its right (0x00000089000000_00).
  5. ((left & 0xFFL) << 24) = filter 8 rightmost bits or 1 byte (0x00000000000000_67), then pad with 24 bits or 3 bytes of zeros to its right (0x0000000067_000000).
  6. ((left & 0xFF00L) << 8) = filter 16 rightmost bits or 2 bytes (0x000000000000_4500), then pad with 8 bits or 1 byte of zeros to its right (0x00000000004500_00).
  7. ((left >> 8) & 0xFF00L) = remove 8 rightmost bits or 1 byte from 0x01234567 to 0x00012345, then get 16 rightmost bits or 2 bytes (0x000000000000_2300).
  8. ((left >> 24) & 0xFFL) = remove 24 rightmost bits or 3 byte from 0x01234567 to 0x00000001, then get 8 rightmost bits or 1 byte (0x00000000000000_01).

Bitwise OR (|) between value is to merge them all into one.

0xEF00000000000000
0x00CD000000000000
0x0000AB0000000000
0x0000008900000000
0x0000000067000000
0x0000000000450000
0x0000000000002300
0x0000000000000001
------------------------
0xEFCDAB8967452301
------------------------

Upvotes: 0

Elliott Frisch
Elliott Frisch

Reputation: 201507

Your bytes are being written in LITTLE_ENDIAN. Note that f9 0c 00 28 and 28 00 0c f9 are reversed. I would prefer ByteBuffer over direct bit-fiddling. Like,

int left = 262388740;  
int right = 671091961; 
ByteBuffer bb = ByteBuffer.allocate(8);
bb.putInt(left);
bb.putInt(right);
bb.order(ByteOrder.LITTLE_ENDIAN);
long r = bb.getLong(0);
System.out.println(Long.toHexString(r));

Outputs (as requested)

f90c002804bca30f

Upvotes: 1

Related Questions