C#中任意位大小的数据类型

时间:2010-03-09 07:38:01

标签: c# types

在C#中定义一个结构,例如6位数据的最佳方法是什么? 当然,我可以定义2个int + short字段,但我想知道是否有办法将所有数据保存在1个字段中。

5 个答案:

答案 0 :(得分:4)

BitVector32的设计考虑了位填充(当然,您要存储的结构必须适合32位)。

请参阅herehere 举个例子

答案 1 :(得分:2)

您为此目的使用BitArray类。 它在System.Collections

http://msdn.microsoft.com/en-us/library/system.collections.bitarray.aspx

答案 2 :(得分:2)

如果你的意思是6位,那么byte足以容纳它们,因为它有8位。

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;
    }
  }

}

如果你的意思是6个字节,long足以容纳它们,因为它有8个字节。

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));
    }
  }

}

上述结构的单元测试:

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]);
}

答案 3 :(得分:0)

您是否尝试过BitArray(System.Collections.BitArray)?

否则你不是任意的 - int + short仅限于...... 32位(int的长度)。

对于任何更短的内容 - 采用下一个较长的原语并使用它。

答案 4 :(得分:0)

好的,你必须要有6个字节的数据。然后你的数学加起来(int加短是6个字节)。

正如其他人所说,一个集合是最好的,但似乎你必须把所有东西打包成一个结构。

最大的数字类型是小数,它是128位宽,而长是64位。如果你真的真的什么来保存数据,你可以使用它们堆栈和连续(就像你听到的那样)。