What is the best way of defining in C# a structure with, say, 6 bits of data? I can, of course, define 2 fields of int + short, but I wonder if there's a way of holding all the data in 1 filed.
Regards, Yaakov
What is the best way of defining in C# a structure with, say, 6 bits of data? I can, of course, define 2 fields of int + short, but I wonder if there's a way of holding all the data in 1 filed.
Regards, Yaakov
You an use the BitArray class for this purpose. It's in System.Collections
http://msdn.microsoft.com/en-us/library/system.collections.bitarray.aspx
Did you try BitArray (System.Collections.BitArray)?
Otherwise you are not arbitrary - int+short is limited to.... 32 bits (length of int).
For anything shorter - take next longer primitive and just use it.
BitVector32 was designed with bit packing in mind (of course the structure you want to store has to fit on 32 bits).
Ok, you must have meant 6 bytes of data. Then your math adds up ( int plus short is 6 bytes ).
As others have said, a collection would be best, but it seems like you have to pack everything into a struct.
The largest numeric type is the decimal and it's 128bits wide, while a long is 64. You can use those if you really, really what to keep that data on the stack and contiguous ( like it sounds you do ).
If you mean 6 bits, then a byte
is enough to hold them as it has 8 bits.
public struct SixBits {
private byte _data;
private SixBits(byte value) {
_data = value;
}
public SixBits ChangeBit(int index, bool value) {
if (index < 0 || index > 5) throw new IndexOutOfRangeException();
return new SixBits((byte)(_data & ~(1 << index) | ((value ? 1 : 0) << index)));
}
public bool this[int index] {
get {
if (index < 0 || index > 5) throw new IndexOutOfRangeException();
return ((_data >> index) & 1) != 0;
}
}
}
If you mean 6 bytes, a long
is enough to hold them as it has 8 bytes.
public struct SixBytes {
private long _data;
private SixBytes(long value) {
_data = value;
}
public SixBytes ChangeByte(int index, byte value) {
if (index < 0 || index > 5) throw new IndexOutOfRangeException();
return new SixBytes(_data & ~(0xFFL << (index * 8)) | (long)value << (index * 8));
}
public byte this[int index] {
get {
if (index < 0 || index > 5) throw new IndexOutOfRangeException();
return (byte)(_data >> (index * 8));
}
}
}
Unit test for the above structures:
SixBits x = new SixBits();
for (int i = 0; i < 6; i++) Assert.AreEqual(false, x[i]);
for (int i = 0; i < 6; i++) x = x.ChangeBit(i, true);
for (int i = 0; i < 6; i++) Assert.AreEqual(true, x[i]);
for (int i = 0; i < 6; i++) x = x.ChangeBit(i, false);
for (int i = 0; i < 6; i++) Assert.AreEqual(false, x[i]);
for (int i = 0; i < 6; i++) x = x.ChangeBit(i, (i & 1) == 0);
for (int i = 0; i < 6; i++) Assert.AreEqual((i & 1) == 0, x[i]);
for (int i = 0; i < 6; i++) x = x.ChangeBit(i, (i & 1) == 1);
for (int i = 0; i < 6; i++) Assert.AreEqual((i & 1) == 1, x[i]);
SixBytes y = new SixBytes();
for (int i = 0; i < 256; i++) {
for (int j = 0; j < 6; j++) y = y.ChangeByte(j, (byte)i);
for (int j = 0; j < 6; j++) Assert.AreEqual((byte)i, y[j]);
}
byte[] test = { 0, 1, 64, 2, 255, 3, 14, 32, 4, 96, 6, 254, 7, 12, 255, 128, 127 };
for (int i = 0; i < test.Length - 6; i++) {
for (int j=0;j<6;j++) y = y.ChangeByte(j, test[i+j]);
for (int j=0;j<6;j++) Assert.AreEqual(test[i+j], y[j]);
}