Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is 0xFF and why is it shifted 24 times?

#define SwapByte4(ldata) \
   (((ldata & 0x000000FF) << 24) | \
   ((ldata & 0x0000FF00) << 8) | \
   ((ldata & 0x00FF0000) >> 8) | \
   ((ldata & 0xFF000000) >> 24))

What does that 0x000000FF represent? I know that decimal 15 is represented in hex as F, but why is it << 24?

like image 920
piyapiya Avatar asked Oct 30 '10 10:10

piyapiya


People also ask

What does 0xff mean?

0xff is a number represented in the hexadecimal numeral system (base 16). It's composed of two F numbers in hex. As we know, F in hex is equivalent to 1111 in the binary numeral system. So, 0xff in binary is 11111111.

What is 0xff Assembly?

Well, 0xff is the hexadecimal number FF which has a integer value of 255. And the binary representation of FF is 00000000000000000000000011111111 (under the 32-bit integer). The & operator performs a bitwise AND operation.

What is 0xff C++?

0xff means "the hexadecimal number ff " - in other words, the integer 255 , which has the binary representation 00000000000000000000000011111111 (when using 32-bit integers). The & operator performs a bitwise AND operation.

What is the value of 0x000000FF?

0x000000FF is the hexadecimal representation of blue color. Performing a bitwise AND between integerCode and 0x000000FF filters the blue bits from the integerCode and assigns it to float b. Similarly 0x0000FF00 is the hex of green and 0x00FF0000 is the hex of red. Notice the shifting of FF between the three hex values.


2 Answers

Here is a hex value, 0x12345678, written as binary, and annotated with some bit positions:

|31           24|23           16|15            8|7         bit 0|
+---------------+---------------+---------------+---------------+
|0 0 0 1 0 0 1 0|0 0 1 1 0 1 0 0|0 1 0 1 0 1 1 0|0 1 1 1 1 0 0 0|
+---------------+---------------+---------------+---------------+

...and here is 0x000000FF:

+---------------+---------------+---------------+---------------+
|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|1 1 1 1 1 1 1 1|
+---------------+---------------+---------------+---------------+

So a bitwise AND selects just the bottom 8 bits of the original value:

+---------------+---------------+---------------+---------------+
|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 1 1 1 1 0 0 0|
+---------------+---------------+---------------+---------------+

...and shifting it left by 24 bits moves it from the bottom 8 bits to the top:

+---------------+---------------+---------------+---------------+
|0 1 1 1 1 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|
+---------------+---------------+---------------+---------------+

...which is 0x78000000 in hex.

The other parts work on the remaining 8-bit portions of the input:

  0x12345678
& 0x000000FF
  ----------
  0x00000078 << 24 = 0x78000000       (as shown above)

  0x12345678
& 0x0000FF00
  ----------
  0x00005600 <<  8 = 0x00560000

  0x12345678
& 0x00FF0000
  ----------
  0x00340000 >>  8 = 0x00003400

  0x12345678
& 0x00000000
  ----------
  0x12000000 >> 24 = 0x00000012

                   | ----------
                     0x78563412

so the overall effect is to consider the 32-bit value ldata as a sequence of four 8-bit bytes, and reverse their order.

like image 137
Matthew Slattery Avatar answered Oct 06 '22 00:10

Matthew Slattery


This kind of code tends to be used to swap things between big endian and little endian format. There is also a little trick that will convert a word in some known format (lets say, little endian) into whatever endianness the current machine happens to be, and vice versa. That would go something like this:

unsigned long littleEndian;
unsigned char* littleBytes = &littleEndian;
unsigned long result = 0;
for (i = 0; i < 4; i++)
    result += unsigned long(littleBytes[i]) << (8 * i);

This works (assuming I haven't messed it up) because regardless of how bytes are actually stored, shift left is guaranteed to shift towards more significant bits. Converting to a char* allows you to access the bytes in the order they are actually stored in memory. Using this trick you don't need to detect the machine endianness to read/write stuff in a known format. Admittedly you could also just use the standard functions (hton etc.) :P

(Note: You have to be a little careful and cast the char before shifting, otherwise it just overflows all over your shoes. Also, += isn't the only option, |= would probably make more sense but might be less clear if you aren't used to it, I'm not sure)

like image 45
David Avatar answered Oct 05 '22 23:10

David