这个 reverseBytes 方法是如何工作的?
How does this reverseBytes method work?
我在网上查看这个函数,想知道它是如何工作的:
/*
* reverseBytes - reverse bytes
* Example: reverseBytes(0x12345678) = 0x78563412
* Legal ops: ! ~ & ^ | + << >>
*/
int reverseBytes(int x)
{
int newbyte0 = (x >> 24) & 0xff;
int newbyte1 = (x >> 8) & 0xff00;
int newbyte2 = (x << 8) & 0xff0000;
int newbyte3 = x << 24;
return newbyte0 | newbyte1 | newbyte2 | newbyte3;
}
以下是我的理解:
0xff
、0xff00
、0xff0000
二进制分别为1111 1111
、1111 1111 0000 0000
、1111 1111 0000 0000 0000 0000
- 该方法创建四个带有掩码(
0xff
等)的新字节,然后使用 |
运算符 将它们的值相加
不过我真的不明白这是如何反转字节的。我将不胜感激详细的解释。谢谢!
假设您已将 0x12345678
传递给函数。
对于 32 位系统
int newbyte0 = (x >> 24) & 0xff; //will be 0x00000012
int newbyte1 = (x >> 8) & 0xff00; //will be 0x00003400
int newbyte2 = (x << 8) & 0xff0000; //will be 0x00560000
int newbyte3 = x << 24; //will be 0x78000000
return newbyte0 | newbyte1 | newbyte2 | newbyte3; will be 0x78563412
这个函数只是将字节移动到整数中的正确位置,然后将它们全部放在一起。
例如 x 是 0xAABBCCDD:
对于第一个字节,我们将所有字节向右移动,所以我们有 0x00000000AA 和 0xFF,即 0xAA。
对于第二个字节,我们有 0x00AABBCC 和 0xFF00,即 0x0000BB00
等等。
我们只是将位移动到正确的位置并擦除所有其他位。
是的,您正确理解了代码,但当然它假定 int 为 32 位值。
int newbyte0 = (x >> 24) & 0xff; // Shift the bits 24~31 to 0~7
int newbyte1 = (x >> 8) & 0xff00; // Shift the bits 16~23 to 8~15
int newbyte2 = (x << 8) & 0xff0000; // Shifts bit bits 8~15 to 16~23
int newbyte3 = x << 24; // Shift bits 0~7 to 24~31
return newbyte0 | newbyte1 | newbyte2 | newbyte3; // Join all the bits
int newbyte0 = (x >> 24) & 0xff;
将数字向右移动 24 位,这样最左边的字节现在将成为最右边的字节。然后它使用掩码 (0xff
) 将其余字节归零,这是多余的,因为移位无论如何都会将它们归零,因此可以省略掩码。
int newbyte1 = (x >> 8) & 0xff00;
将数字右移 8 位,这样从左边数第二个字节现在是从右边数第二个字节,其余字节用掩码清零。
int newbyte2 = (x << 8) & 0xff0000;
这次将数字向左移动 8 位 - 本质上与上一行相同,只是现在从右数第二个字节变为从左数第二个字节。
int newbyte3 = x << 24;
和第一行一样(这次真的省略了多余的掩码)——最右边的字节变成最左边的字节。
return newbyte0 | newbyte1 | newbyte2 | newbyte3;
最后你只需OR
所有字节即可完成反转。
您实际上可以通过使用 printf("%x", newbyte)
打印每个字节来在代码中逐步执行此过程 - %x
格式允许您以十六进制打印。
代码采用 32 位整数和 8 位字节。一个 32 位整数由 4 个字节组成:
假设这 4 个字节在内存中的布局如下:
+---------------------------------+
|Byte 4 | Byte 3 | Byte 2 | Byte 1|
+---------------------------------+
这可能与给定 CPU 类型的 Endianess 有关。当解释一个由几个字节组成的整数时,一些 CPU 系列将最左边的字节,具有较低内存地址的字节视为整数的最高有效字节 - 这样的 CPU 被称为大端。其他 CPUs 会做相反的事情,他们会将整数中最右边的字节,具有最大内存地址的字节作为最高有效字节 - little endian CPUs。因此,您的函数将整数从一种字节序转换为另一种字节序。
int newbyte0 = (x >> 24) & 0xff;
这采用上面描述的整数(4 个字节),将其向右移动 24 位,并屏蔽除低 8 位以外的所有内容,newbyte0 现在看起来像这样,其中字节 4 是原始字节 4 x
其他 3 个字节的所有位都设置为零。
+---------------------------------+
| 0 | 0 | 0 | Byte 4 |
+---------------------------------+
同样
int newbyte1 = (x >> 8) & 0xff00;
将位向右移动 8 位,并从左侧屏蔽掉第 2 个字节中除 8 位以外的所有内容。结果看起来像这样,x
的原始值只剩下字节 3
+---------------------------------+
| 0 | 0 | Byte 3 | 0 |
+---------------------------------+
最左边的2个字节处理类似,只是x
左移完成同样的事情。
你终于有了
newbyte0 | newbyte1 | newbyte2 | newbyte3;
它结合了您在上面创建的所有整数,每个整数只剩下原始 x
的 8 位。对它们进行按位 or
,最后得到
+---------------------------------+
|Byte 1 | Byte 2 | Byte 3 | Byte 4|
+---------------------------------+
我在网上查看这个函数,想知道它是如何工作的:
/*
* reverseBytes - reverse bytes
* Example: reverseBytes(0x12345678) = 0x78563412
* Legal ops: ! ~ & ^ | + << >>
*/
int reverseBytes(int x)
{
int newbyte0 = (x >> 24) & 0xff;
int newbyte1 = (x >> 8) & 0xff00;
int newbyte2 = (x << 8) & 0xff0000;
int newbyte3 = x << 24;
return newbyte0 | newbyte1 | newbyte2 | newbyte3;
}
以下是我的理解:
0xff
、0xff00
、0xff0000
二进制分别为1111 1111
、1111 1111 0000 0000
、1111 1111 0000 0000 0000 0000
- 该方法创建四个带有掩码(
0xff
等)的新字节,然后使用|
运算符 将它们的值相加
不过我真的不明白这是如何反转字节的。我将不胜感激详细的解释。谢谢!
假设您已将 0x12345678
传递给函数。
int newbyte0 = (x >> 24) & 0xff; //will be 0x00000012
int newbyte1 = (x >> 8) & 0xff00; //will be 0x00003400
int newbyte2 = (x << 8) & 0xff0000; //will be 0x00560000
int newbyte3 = x << 24; //will be 0x78000000
return newbyte0 | newbyte1 | newbyte2 | newbyte3; will be 0x78563412
这个函数只是将字节移动到整数中的正确位置,然后将它们全部放在一起。 例如 x 是 0xAABBCCDD: 对于第一个字节,我们将所有字节向右移动,所以我们有 0x00000000AA 和 0xFF,即 0xAA。
对于第二个字节,我们有 0x00AABBCC 和 0xFF00,即 0x0000BB00
等等。 我们只是将位移动到正确的位置并擦除所有其他位。
是的,您正确理解了代码,但当然它假定 int 为 32 位值。
int newbyte0 = (x >> 24) & 0xff; // Shift the bits 24~31 to 0~7
int newbyte1 = (x >> 8) & 0xff00; // Shift the bits 16~23 to 8~15
int newbyte2 = (x << 8) & 0xff0000; // Shifts bit bits 8~15 to 16~23
int newbyte3 = x << 24; // Shift bits 0~7 to 24~31
return newbyte0 | newbyte1 | newbyte2 | newbyte3; // Join all the bits
int newbyte0 = (x >> 24) & 0xff;
将数字向右移动 24 位,这样最左边的字节现在将成为最右边的字节。然后它使用掩码 (0xff
) 将其余字节归零,这是多余的,因为移位无论如何都会将它们归零,因此可以省略掩码。
int newbyte1 = (x >> 8) & 0xff00;
将数字右移 8 位,这样从左边数第二个字节现在是从右边数第二个字节,其余字节用掩码清零。
int newbyte2 = (x << 8) & 0xff0000;
这次将数字向左移动 8 位 - 本质上与上一行相同,只是现在从右数第二个字节变为从左数第二个字节。
int newbyte3 = x << 24;
和第一行一样(这次真的省略了多余的掩码)——最右边的字节变成最左边的字节。
return newbyte0 | newbyte1 | newbyte2 | newbyte3;
最后你只需OR
所有字节即可完成反转。
您实际上可以通过使用 printf("%x", newbyte)
打印每个字节来在代码中逐步执行此过程 - %x
格式允许您以十六进制打印。
代码采用 32 位整数和 8 位字节。一个 32 位整数由 4 个字节组成: 假设这 4 个字节在内存中的布局如下:
+---------------------------------+
|Byte 4 | Byte 3 | Byte 2 | Byte 1|
+---------------------------------+
这可能与给定 CPU 类型的 Endianess 有关。当解释一个由几个字节组成的整数时,一些 CPU 系列将最左边的字节,具有较低内存地址的字节视为整数的最高有效字节 - 这样的 CPU 被称为大端。其他 CPUs 会做相反的事情,他们会将整数中最右边的字节,具有最大内存地址的字节作为最高有效字节 - little endian CPUs。因此,您的函数将整数从一种字节序转换为另一种字节序。
int newbyte0 = (x >> 24) & 0xff;
这采用上面描述的整数(4 个字节),将其向右移动 24 位,并屏蔽除低 8 位以外的所有内容,newbyte0 现在看起来像这样,其中字节 4 是原始字节 4 x
其他 3 个字节的所有位都设置为零。
+---------------------------------+
| 0 | 0 | 0 | Byte 4 |
+---------------------------------+
同样
int newbyte1 = (x >> 8) & 0xff00;
将位向右移动 8 位,并从左侧屏蔽掉第 2 个字节中除 8 位以外的所有内容。结果看起来像这样,x
+---------------------------------+
| 0 | 0 | Byte 3 | 0 |
+---------------------------------+
最左边的2个字节处理类似,只是x
左移完成同样的事情。
你终于有了
newbyte0 | newbyte1 | newbyte2 | newbyte3;
它结合了您在上面创建的所有整数,每个整数只剩下原始 x
的 8 位。对它们进行按位 or
,最后得到
+---------------------------------+
|Byte 1 | Byte 2 | Byte 3 | Byte 4|
+---------------------------------+