如何处理不规则的位大小
How to handle irregular bit sizes
我正在研究一个项目,该项目包含来自二进制文件的不同位大小的变量。例如,文件的一行(十六进制)可能看起来像"FF C0 AA 00 FE"。例如,从这一行来看,我需要的信息是4位、7位、11位、8位等。我遇到的问题是,提取的一些数字将被签名,而其他数字将被无符号(4和7位可能被签名,11和8位无符号)。
我最初通过屏蔽和移动十六进制值来提取,以获得4,7,11,8位的c++ char/short/int。然而,如果我看二进制的4位,它会显示为00001011。这个数字应该是基于前导1的负数(应该只有4位1011),但c++将其识别为正数,因为它正在查看所有8位。
另一个澄清的例子,我可能从文件中提取11位为(11100101101),但在c++简短格式中,它显示为(0000011100101101),应该基于11位的前导1进行签名。
我想知道处理这个问题的理想方法是什么。我正在考虑制作一个位/字节类,唯一的问题是不同的位大小(4,7,11,8)。
谢谢,希望这是有意义的。我对c++中的二进制比较陌生,所以可能有一个我没有见过的内置函数。
我将假设您已经可以通过移动和屏蔽以及将不同的部分组合在一起来提取您想要的位,问题只是处理符号位。
int make_signed(int value, int bits)
{
if (value & (1 << (bits - 1)))
value |= -1 & ~((1 << bits) - 1);
return value;
}
首先测试n位数字中的符号位是什么。如果设置了,则int
的上位也通过从-1
的值开始设置(所有位都以2的补码设置)并屏蔽掉底部的有效位来设置。
这已经为您完成了-参见std::bitset -只需拥有它们的数组
对于问题中给出的两个例子,你可以这样做:
char src = 0x0B; // 00001011
char dst = (char)(src<<4)>>4; // 11111011
short src = 0x072D; // 0000011100101101
short dst = (short)(src<<5)>>5; // 1111111100101101
一般来说,您可以实现一个signed
值的函数和一个unsigned
值的函数:
#include <limits.h>
signed int GetSignedVal(signed int val,int numOfBits)
{
int shift = sizeof(val)*CHAR_BITS-numOfBits;
return (val<<shift)>>shift;
}
unsigned int GetUnsignedVal(unsigned int val,int numOfBits)
{
int shift = sizeof(val)*CHAR_BITS-numOfBits;
return (val<<shift)>>shift;
}
在C/c++中有一个很少使用的特性,叫做位字段,它可以解决你的问题。
struct HodgePodgge {
bool oneBooleanBit:1;
int fourBitsOfSignedInteger:4;
unsigned int sixUnsignedIntegerBits:6;
};
'sizeof(HodgePodge)'应该是2(总共11位在两个字节中)
编译器生成代码来为您做移位、屏蔽和签名扩展。这是一件好事,因为它不能保证HodgePodge中的位的布局。
此链接提供详细信息
位字段一直都在那里但是没有人使用它们。注意,你可能需要教育你的同事(或适当地评论)
- 警告处理为错误这里有什么问题
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用流处理接收到的数据
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 基于多个条件处理地图中的所有元素
- 如何用数字处理log(0)
- SSL上的`curl_easy_send`和`curl_asy_recv`:如何处理`CURLE_AGAIN`
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 错误处理.将系统错误代码映射到泛型
- 从文本文件中读取时钟时间和事件时间并进行处理
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 用于矢量处理的多个线程
- 对字符串进行排序时,在c++中处理sort()
- Python中的for循环与C++有何不同
- 如何处理linux终端中带有负号(-)的C++中的命令行参数
- 如何处理不规则的位大小