Laishram Pilot
Laishram Pilot

Reputation: 137

Please explain me why 24,16, 8 were used in converting int to bytes?

The following code is to convert an int to Bytes array. I know the int i is right shifted 24, 16, 8 times and ANDED with 0xFF but what I can't understand is why these numbers were used?

private static byte[] intToBytes(int i)
  // split integer i into 4 byte array
  {
    // map the parts of the integer to a byte array
    byte[] integerBs = new byte[4];
    integerBs[0] = (byte) ((i >>> 24) & 0xFF);
    integerBs[1] = (byte) ((i >>> 16) & 0xFF);
    integerBs[2] = (byte) ((i >>> 8) & 0xFF);
    integerBs[3] = (byte) (i & 0xFF);

    // for (int j=0; j < integerBs.length; j++)
    //  System.out.println(" integerBs[ " + j + "]: " + integerBs[j]);

    return integerBs;
  }  // end of intToBytes()

Upvotes: 2

Views: 4043

Answers (4)

7stud
7stud

Reputation: 48649

Some integer:

1111 1001 1010 1001 1010 1001 1010 1001 1010

Shifted to the right 24 bits:

1111 1001 1010

Anded with 0xFF:

1111 1001 1010

0000 1111 1111


0000 1001 1010

...which is just the 4th byte.

The integer:

1111 1001 1010 1001 1010 1001 1010 1001 1010

Shifted to the right 16 bits:

1111 1001 1010 1001 1010

Anded with 0xFF:

1111 1001 1010 1001 1010

0000 0000 0000 1111 1111


0000 0000 0000 1001 1010

...which is just the 3rd byte.

Etc...

Upvotes: 0

1337holiday
1337holiday

Reputation: 1954

Ok lets pretend you have a 32 bit binary number:

00001111 00000111 00000011 00000001

One byte is equivalent to 8 bits and therefore the number above is comprised of 4 bytes.

To separate these bytes out we need to perform a series of shift and and mask operations.

For instance to get the first byte (00001111) we do the following:

00001111 00000111 00000011 00000001 (original)
00000000 00000000 00000000 00001111 (shifted 24 spaces to the right)

Now we do not want those 3 bytes of zeros infront so we use an 8-bit mask (0xFF) and perform an AND operation between our 32 bit resulting number and the mask.

For example:

00000000 00000000 00000000 00001111
&&                         11111111
-----------------------------------
                           00001111 (the first byte)

Now you can imagine how to get the second byte (only shift 16 bits to the right). The whole purpose is to get the 8 bits you want in the first 8 positions and use the mask to get rid of the garbage infront.

Upvotes: 8

bash.d
bash.d

Reputation: 13207

As an int consists of four bytes, you can "reach" every byte in the int by shifting a multiple of 8 bits = 1 byte.

In order to gain the first byte, you shift the int by 24 bits = 3 bytes, the second byte by shifting it 16 bits = 2 bytes and so on...

The masking & 0xFF serves the purpose preventing overflows and so you take only the byte you want.

To visualize it

31                              0  
 |                              |
 11111111111111111111111111111111

Right shift by 24 equals

 31                             0
 |                              |
 00000000000000000000000011111111

masking it using & 0xFF gives you the 8 bits from 0 to 7.

Upvotes: 0

NPE
NPE

Reputation: 500773

A 32-bit integer consists of four bytes:

  • byte 0 starts at bit 0;
  • byte 1 starts at bit 8;
  • byte 2 starts at bit 16;
  • byte 3 starts at bit 24.

I hope this explains where 8, 16 and 24 come from (they are multiples of eight, which is the width of a byte in bits).

Finally, it is worth noting that

integerBs[3] = (byte) (i & 0xFF);

is the same as

integerBs[2] = (byte) ((i >>> 0) & 0xFF);

This is the missing zero.

Upvotes: 0

Related Questions