按位运算符从32位获取字节
Bitwise operator to get byte from 32 bits
我有兴趣编写一个函数getMyByteChunkFunction
,它接受两个参数-一个32位整数和一个字节偏移量(0、1、2或3),然后从32位整数中返回相应的字节。例如,给定这个整数:
(3) (2) (1) (0) ---byte numbers
int word = 10101010 00001001 11001010 00000101
函数调用getMeByteChunkFunction(word, 2)
返回00001001
。
但是,我可以使用的位操作符有限。我只允许使用>>
, <<
和正好一个减法。我知道怎么用AND和XOR,但我不知道怎么用减法。什么好主意吗?
思路如下:假设您有一个像这样的四字节值:
aaaaaaaa bbbbbbbb cccccccc dddddddd
让我们假设你想从中得到字节bbbbbbbb
。如果右移两个字节,就得到
???????? ???????? aaaaaaaa bbbbbbbb
这个值等于你想要的,除了在顶部它有???????? ???????? aaaaaaaa
(因为我们不确定移位是否保留符号,因为我不知道你的值是否是无符号的)。不过不用担心;我们可以去掉这些未知值和a
字节。为了去掉顶部,假设你向右移动另一个字节,得到
???????? ???????? ???????? aaaaaaaa
现在左移一个字节得到
???????? ???????? aaaaaaaa 00000000
如果你再做这个减法,你得到
???????? ???????? aaaaaaaa bbbbbbbb
- ???????? ???????? aaaaaaaa 00000000
---------------------------------------
00000000 00000000 00000000 bbbbbbbb
voilà…你已经得到了你想要的价值!
我将把实际的代码留给读者作为练习。别担心;这并不难。: -)你可以通过移动来实现。向左移位去掉左边的位,然后向右移位去掉右边的位,并将需要的字节移动到最低有效位
下面的代码也应该回答这个问题。
#include <stdio.h>
int getByte(int x, int n);
void main()
{
int x = 0xAABBCCDD;
int n;
for (n=0; n<=3; n++) {
printf("byte %d of 0x%X is 0x%Xn",n,x,getByte(x,n));
}
}
// extract byte n from word x
// bytes numbered from 0 (LSByte) to 3 (MSByte)
int getByte(int x, int n)
{
return (x >> (n << 3)) & 0xFF;
}
输出为
byte 0 of 0xAABBCCDD is 0xDD
byte 1 of 0xAABBCCDD is 0xCC
byte 2 of 0xAABBCCDD is 0xBB
byte 3 of 0xAABBCCDD is 0xAA
这个概念可以根据templatetypedef的解释来解释,并展开如下:
(3) (2) (1) (0)
aaaaaaaa bbbbbbbb cccccccc dddddddd
{(3),(2),(1),(0)} --> {(3)}
???????? ???????? ???????? aaaaaaaa // x>>(3*8) where 3 == n
& 00000000 00000000 00000000 11111111 // 0xFF
-----------------------------------
00000000 00000000 00000000 aaaaaaaa // (x >> (8 * n)) & 0xFF
{(3),(2),(1),(0)} --> {(2)}
???????? ???????? aaaaaaaa bbbbbbbb // x>>(2*8) where 2 == n
& 00000000 00000000 00000000 11111111 // 0xFF
-----------------------------------
00000000 00000000 00000000 bbbbbbbb
{(3),(2),(1),(0)} --> {(1)}
???????? aaaaaaaa bbbbbbbb cccccccc // x>>(1*8) where 1 == n
& 00000000 00000000 00000000 11111111 // 0xFF
-----------------------------------
00000000 00000000 00000000 cccccccc
{(3),(2),(1),(0)} --> {(0)}
aaaaaaaa bbbbbbbb cccccccc dddddddd // x>>(0*8) where 0 == n
& 00000000 00000000 00000000 11111111 // 0xFF
-----------------------------------
00000000 00000000 00000000 dddddddd
Note (x >> (8 * n)) & 0xFF is equivalent to (x >> (n << 3)) & 0xFF.
64 32 16 8 4 2 1
----------------
0 0 0 0 0 1 1 // (n==3)
0 0 1 1 0 0 0 // (n*8==n<<3==24)
----------------
0 0 0 0 0 1 0 // (n==2)
0 0 1 0 0 0 0 // (n*8==n<<3==16)
----------------
0 0 0 0 0 0 1 // (n==1)
0 0 0 1 0 0 0 // (n*8==n<<3==8)
----------------
result = (word >> (n_byte << 3)) & 0xFF;
有一个非常聪明的技巧,我用它来将对象转换为字符串(作为流传输):
//WhichByte should really be an enum to avoid issues
//Counts as 0, 1, 2 or 3
//Modify as unsigned or signed char (for return type and pointer type) as needed
#define BYTE_TYPE unsigned char
BYTE_TYPE GetByte(const unsigned int Source, const unsigned char WhichByte)
{
if(WhichByte < 0){return 0;}
if(WhichByte >= sizeof(Source)){return 0;}
//Converts source into the appropriate pointer
BYTE_TYPE * C_Ptr = (BYTE_TYPE *)&Source;
return *(C_Ptr+WhichByte);
}
#undef BYTE_TYPE
简而言之,上面的代码将source视为4个单独的字符(通常只有1字节大小),并且指针允许您将其视为内存段。在返回之前对它解引用。
用在任何目的(甚至商业)。
压缩格式吗?
#define GetByte(X,Y) (*(((unsigned char *)&X)+Y))
代码如下:
#include <stdio.h>
int main() {
unsigned long n = 0xAA09CA05L; /* 10101010 00001001 11001010 00000101 */
printf("%08lxn", n); /* input */
printf("%02lxn", ((n<<8)>>24)); /* output */
return 0;
}
和输出:
aa09ca05
09
相关文章:
- 如何获取 BITMAPFILEHEADER 和 BITMAPINFOHEADER 的字节表示形式?
- 在 Linux 中使用 ioctl() 获取隐藏功能报告时,零字节消失
- 如何使用CAPL的诊断功能获取CAN传输的数据(256字节)?
- 获取嵌套 stl 容器的大小(以字节为单位)
- 如何从Little Endian UTF-16编码字节中获取C++std::string
- 如何在序列化后获取字节数组
- 如何从 Oracle 数据库中获取 qt 中 SQL 查询的传输字节大小?
- 函数获取参数的变量列表并将它们转换为一系列字节?
- 编码大于原始文本:如何获取零和一的字符串并将它们作为实际字节写入文件
- 如何使用V8引擎从C 获取JavaScript字节码
- 如何使用低级系统调用从 stdin 和输入文件中获取字节数
- 从 Windows::Storage::Streams::IBuffer 中获取字节数组
- 如何在 JNA 中获取字节数组作为从 C 字节指针返回的返回
- 如何从HBITMAP中获取字节数组
- 在c++中获取字节范围的HTTP GET请求
- 从c#中的非托管c++ DLL中获取字节数组上的指针
- 按位运算符从32位获取字节
- c++获取字节等价函数并执行
- 是否可以获取字节(或文本()变量的信息在WiFi中
- 从内存地址中获取字节