我正在使用专有的二进制消息传递协议,在一条消息中,一个字节用于存储3个不同的值,如下所示:
Bit
7 IsArray (1 bit)
6 ArrayLength, MSB (4 bits, max size 2^4 = 16)
5
4
3
2 DataType, MSB (3 bits, max size = 2^3 = 8)
1
0
我想提取这三个值,并将它们存储在对象bool IsArray
,byte ArrayLength
和byte DataType
中的三个不同属性中。我还需要从这三个属性返回到单个字节
我很少在这个级别上工作,当我超越设置或获得IsArray的单个位,尝试同时设置几个时,事情变得有点混乱。我创造了三种不同的面具,我认为这会对我有所帮助:
var IsArrayMask = 0x80; // 1000 0000
var ArrayLengthMask = 0x78; // 0111 1000
var DataTypeMask = 0x07; // 0000 0111
有没有一种优雅的方式来实现我的目标?
编辑:在@stefankmitph的帮助下,我发现我的变速都搞砸了。这就是我现在从3个属性转到单个字节的方式:
bool IsArray = true;
byte ArrayLength = 6;
byte DataType = 3;
byte serialized = 0x00; // Should end up as 1011 0011 / 0xB3
serialized |= (byte)((IsArray ? 1 : 0) << 7 & IsArrayMask);
serialized |= (byte)(ArrayLength << 3 & ArrayLengthMask);
serialized |= (byte)(DataType & DataTypeMask);
再回来,根据以下答案:
bool isArray = (serialized & IsArrayMask) == IsArrayMask;
int arrayLength = (serialized & ArrayLengthMask) >> 3;
int dataType = (serialized & DataTypeMask);
答案 0 :(得分:3)
int val = 0xBE; //f.e. 1011 | 1110
var IsArrayMask = 0x80; // 1000 0000
var ArrayLengthMask = 0x78; // 0111 1000
var DataTypeMask = 0x07; // 0000 0111
bool isArray = ((val & IsArrayMask) >> 7) == 1; // output: true
// as pointed out by @PeterSchneider & @knittl
// you can get isArray in a probably more elegant way:
isArray = (val & IsArrayMask) == IsArrayMask;
// i keep both ways in my answer, because i think
// the first one illustrates that you have to shift by 7 to get 1 (true) or 0 (false)
int arrayLength = (val & ArrayLengthMask) >> 3; // output: 7
int dataType = (val & DataTypeMask); // output: 6