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

|▌冷眼眸甩不掉的悲伤 提交于 2020-07-04 07:21:21

问题


#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?


回答1:


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.




回答2:


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)




回答3:


You need to look at the 0x000000FF as a bitmask, i.e. where it's 1 the value of ldata will be taken and where it's 0 - 0 will be taken.

In order to understand the bitmask u need to convert it to binary, with hex it's very easy, every hex number is 4 binary digits, i.e.:

hex 0 = binary 0000 hex 1 = binary 0001 and so on.

Now to shifts: notice that the shift takes some data from the source, 8 bits exactly, and moves it to another location in the destination.

Now note that there's | i.e. OR operation on all the bitmask AND operations, i.e. zeroes will stay zeroes and in case there's '1' the result will contain one.

Hope it helps :)




回答4:


Let's say data is a 32 bit number represented as 0x12345678 (each number is 4 bits in hex)

Data & 0x000000FF means keep only the last 8 bits (called a bit mask) = 0x00000078

The << 24 means move this value to the left 24 bits (78 starts at position 24 [0 index]) = 0x78000000

The | means logical or which in this case will just be an addition

Final result = 0x78563412

Read on logical manipulations



来源:https://stackoverflow.com/questions/4058339/what-is-0xff-and-why-is-it-shifted-24-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!