什么是 0xFF?为什么它移位 24 次?

发布于 2024-09-30 13:30:19 字数 293 浏览 7 评论 0原文

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

0x000000FF 代表什么?我知道十进制的15用十六进制表示为F,但是为什么它<< 24?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

高冷爸爸 2024-10-07 13:30:19

这是一个十六进制值 0x12345678,写为二进制,并用一些位位置进行注释:

|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|
+---------------+---------------+---------------+---------------+

...这里是 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|
+---------------+---------------+---------------+---------------+

因此按位 AND 仅选择原始值的底部 8 位:

+---------------+---------------+---------------+---------------+
|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|
+---------------+---------------+---------------+---------------+

...并将其左移24 位将其从底部 8 位移动到顶部:

+---------------+---------------+---------------+---------------+
|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|
+---------------+---------------+---------------+---------------+

...十六进制为 0x78000000。

其他部分处理输入的剩余 8 位部分:

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

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

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

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

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

因此总体效果是将 32 位值 ldata 视为四个 8 位字节的序列,并反转它们的顺序。

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.

刘备忘录 2024-10-07 13:30:19

这种代码通常用于在大端和小端格式之间交换内容。还有一个小技巧,可以将某种已知格式(例如小尾数法)的单词转换为当前机器恰好采用的任何尾数法,反之亦然。这会是这样的:

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

这有效(假设我没有搞砸),因为无论字节实际如何存储,左移都保证向更有效的位移动。转换为 char* 允许您按照字节实际存储在内存中的顺序访问字节。使用此技巧,您不需要检测机器字节顺序即可以已知格式读/写内容。诚然,您也可以只使用标准函数(hton 等):P

(注意:您必须小心一点,在移动之前转换字符,否则它会溢出您的鞋子。此外, += 不是唯一的选项, |= 可能更有意义,但如果您不习惯的话可能不太清楚,我不确定)

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)

我爱人 2024-10-07 13:30:19

您需要将0x000000FF视为位掩码,即在其为1的位置将采用ldata的值,在其为0 - 0的位置将采用该值。

为了理解位掩码,您需要将其转换为二进制,使用十六进制很容易,每个十六进制数都是 4 个二进制数字,即:

十六进制 0 = 二进制 0000
十六进制 1 = 二进制 0001
等等。

现在进行移位:请注意,移位从源中获取一些数据(精确的 8 位),并将其移动到目标中的另一个位置。

现在请注意,有 | 即所有位掩码 AND 运算上的 OR 运算,即零将保持为零,如果存在“1”,结果将包含 1。

希望它有帮助:)

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 :)

彻夜缠绵 2024-10-07 13:30:19

假设数据是一个 32 位数字,表示为 0x12345678(每个数字为 4 位十六

进制 ) 0x000000FF 表示仅保留最后 8 位(称为位掩码)
= 0x00000078

<< 24 表示将该值向左移动 24 位(78 从位置 24 [0 索引] 开始)
= 0x78000000

|表示逻辑或在本例中只是加法

最终结果 = 0x78563412

读取逻辑操作

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文