[英]Setting bits in a byte array using C#
I have a byte array of 32 bytes where the first 4 bits of each byte (0 to 3) represent the set or unset state of a number between 1 and 128. For example, If I am given the number 3, I need to set bit 2 in the first byte in the array. 我有一个32字节的字节数组,其中每个字节的前4位(0到3)代表1到128之间数字的置位或未设置状态。例如,如果给定数字3,则需要设置数组第一个字节的第2位。 If I am given the number 9, I need to set bit 0 of the third byte in the array.
如果给我数字9,则需要设置数组第三个字节的位0。 The problem I have is finding a sensible way to do this in C#.
我遇到的问题是在C#中找到一种明智的方式来做到这一点。 I'm sure there must be a simple way to do it mathematically but so far haven't been able to find a method.
我敢肯定,必须有一种简单的数学方法,但是到目前为止,还没有找到一种方法。 Whilst I scratch my head on this one I thought I'd see if anyone can give some advice.
当我抓着这个头时,我以为我会看看是否有人可以提供一些建议。
--------- Update ------------------- ---------更新-------------------
Based on the answers given, I have produced the following function. 根据给出的答案,我产生了以下功能。 This does exactly what I need.
这正是我需要的。 I may not have made it clear in my question what I needed but enough advice was given for me to find the right code.
我可能没有清楚说明我需要什么,但已为我提供了足够的建议以找到正确的代码。
// outputNumber = number passed into this function
byte[] bytes = new byte[32];
int bit = (outputNumber - 1) % 4;
byte byteSetting = (byte)(1 << bit);
bytes[(outputNumber - 1) / 4] |= byteSetting;
int byt = bitNumber / 4; // You could do byt = bitNumber >> 2
int bit = bitNumber % 4; // You could do bit = bitNumber & 3
bytes[byt] |= (byte)(1 << bit);
Where bytes
is your byte array. bytes
是您的字节数组。
To reset it: 重置它:
bytes[byt] &= (byte)(byte.MaxValue ^ (1 << bit));
To read the value of a byte: 读取字节的值:
var res = bytes[byt] & (byte)(1 << bit)
(if you are interested, ^
is the xor operator) (如果您有兴趣,
^
是异或运算符)
You can set the bits in each byte in an array like this: 您可以像这样在数组中的每个字节中设置位:
array[2] |= (byte)(1<<3); // set bit #4 / index 3 in array element #3 / index 2
You can clear a bit like this: 您可以清除如下所示的内容:
array[2] &= unchecked((byte)(~(1<<3))); // clear the same bit we set previously
Needed something similar. 需要类似的东西。 On a 64 bit system use ulongs (32 bit -> uint) instead of bytes.
在64位系统上,请使用ulong(32位-> uint)而不是字节。 The performace difference is quite significant.
性能差异非常明显。
public struct BitField {
private ulong[] _Values;
private BitField(ulong[] values) {
_Values = values;
}
public static BitField New() {
return new BitField(new ulong[] { 0ul, 0ul });
}
public BitField Clone() {
return new BitField(new ulong[] { _Values[0], _Values[1] });
}
public void Clear() {
_Values[0] = ulong.MinValue;
_Values[1] = ulong.MinValue;
}
public void SetAll() {
_Values[0] = ulong.MaxValue;
_Values[1] = ulong.MaxValue;
}
public void AND_Combine(BitField bitField) {
_Values[0] &= bitField._Values[0];
_Values[1] &= bitField._Values[1];
}
public void OR_Combine(BitField bitField) {
_Values[0] |= bitField._Values[0];
_Values[1] |= bitField._Values[1];
}
public bool Intersects(BitField bitField) {
if ((_Values[0] & bitField._Values[0]) > 0) {
return true;
}
else {
if ((_Values[1] & bitField._Values[1]) > 0) {
return true;
}
else {
return false;
}
}
}
public bool this[int index] {
get {
if (index > 127 || index < 0) {
return false;
}
int item = index >> 6;
int bit = index % 64;
ulong compare = 1ul << bit;
return ((_Values[item] & compare) == compare);
}
set {
if (index >= 0 || index < 128) {
int item = index >> 6;
int bit = index % 64;
ulong compare = 1ul << bit;
if (value) {
_Values[item] |= compare;
}
else {
_Values[item] &= ~compare;
}
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.