C# 在一个字节中存储3个不同的值

C# 在一个字节中存储3个不同的值,c#,bit-manipulation,C#,Bit Manipulation,我正在使用专有的二进制消息传递协议,在一条消息中,一个字节用于存储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、字节数组长度和字节数据类型。我还需要从这三个属性返回到一个字节 我

我正在使用专有的二进制消息传递协议,在一条消息中,一个字节用于存储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
字节数组长度
字节数据类型
。我还需要从这三个属性返回到一个字节

我很少在这个级别上工作,当我超出设置或获取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);

您能否展示您如何使用这些掩码(即发布一些代码)并告诉我们您的方法如何不起作用?您能否展示您如何使用这些掩码(即发布一些代码)并告诉我们您的方法如何不起作用?您能否展示您如何使用这些掩码(即发布一些代码)并告诉我们您的方法如何不起作用?您能否展示您如何使用这些掩码(即,发布一些代码)并告诉我们你的方法如何不起作用?@PeterSchneider:你的意思是
bool isArray=(val&IsArrayMask)==IsArrayMask
(没有正确的转换)我第一次就搞错了,谢谢@knittl。为了清晰起见,我删除了错误的建议。--我认为更规范的应该是
bool isArray=(val&IsArrayMask)==IsArrayMask;
。位位置是一个可以更改的实现细节。不幸的是,无法使用长度来执行此操作,尽管可以通过(0xf感谢您的回答,它澄清了很多问题。在我自己的解决方案中,从属性到单字节,我在布尔
IsArray
上使用了三元运算符。您会做不同的事情吗?@Walkingsteak使用三元运算符(此处)只是可读性和/或编码风格的问题…所以
(IsArray?1:0)
很好。@PeterSchneider:你是说
bool-isArray=(val&IsArrayMask)==IsArrayMask
(没有右移)我第一次就搞错了,谢谢@knittl。为了清楚起见,我删除了错误的建议。--我认为更规范的应该是
bool-isArray=(val&IsArrayMask)==IsArrayMask;
。位位置是一个可以更改的实现细节。不幸的是,无法使用长度来完成此操作,尽管可以通过定义掩码(0xf感谢您的回答,它澄清了很多问题。在我自己的解决方案中,从属性到单字节,我在布尔
IsArray
上使用了三元运算符。您会做不同的事情吗?@Walkingsteak使用三元运算符(此处)只是可读性和/或编码风格的问题…所以
(IsArray?1:0)
很好。@PeterSchneider:你是说
bool-isArray=(val&IsArrayMask)==IsArrayMask
(没有右移)我第一次就搞错了,谢谢@knittl。为了清楚起见,我删除了错误的建议。--我认为更规范的应该是
bool-isArray=(val&IsArrayMask)==IsArrayMask;
。位位置是一个可以更改的实现细节。不幸的是,无法使用长度来完成此操作,尽管可以通过定义掩码(0xf感谢您的回答,它澄清了很多问题。在我自己的解决方案中,从属性到单字节,我在布尔
IsArray
上使用了三元运算符。您会做不同的事情吗?@Walkingsteak使用三元运算符(此处)只是可读性和/或编码风格的问题…所以
(IsArray?1:0)
很好。@PeterSchneider:你是说
bool-isArray=(val&IsArrayMask)==IsArrayMask
(没有右移)我第一次就搞错了,谢谢@knittl。为了清楚起见,我删除了错误的建议。--我认为更规范的应该是
bool-isArray=(val&IsArrayMask)==IsArrayMask;
。位位置是一个可以更改的实现细节。不幸的是,无法使用长度来完成此操作,尽管可以通过定义掩码(0xf感谢您的回答,它澄清了很多问题。在我自己的解决方案中,从属性到单字节,我在布尔
IsArray
上使用了三元运算符。您会做不同的事情吗?@Walkingsteak使用三元运算符(此处)只是可读性和/或编码风格的问题…所以
(IsArray?1:0)
没问题。
bool isArray = (serialized & IsArrayMask) == IsArrayMask; 
int arrayLength = (serialized & ArrayLengthMask) >> 3;  
int dataType = (serialized & DataTypeMask);             
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