Произвольный тип данных разрядного размера в C#

Каков лучший способ определить в C# структуру с, скажем, 6 битами данных? Я могу, конечно, определить 2 поля интервала + короткий, но интересно, существует ли способ содержать все данные в 1 зарегистрированном.

5
задан Qantas 94 Heavy 26 October 2013 в 09:32
поделиться

5 ответов

BitVector32 был разработан с учетом упаковки битов (конечно, структура, которую вы хотите сохранить, должна соответствовать 32 битам).

См. здесь и здесь для некоторых примеров

4
ответ дан 14 December 2019 в 04:35
поделиться

Если вы имеете в виду 6 бит, тогда байт достаточно для их хранения, поскольку он имеет 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 байтов, для их хранения достаточно , так как он имеет 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]);
}
2
ответ дан 14 December 2019 в 04:35
поделиться

Для этой цели используется класс BitArray. Он есть в System.Collections

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

2
ответ дан 14 December 2019 в 04:35
поделиться

Вы пробовали BitArray (System.Collections.BitArray)?

В противном случае вы не произвольны - int+short ограничивается.... 32 бита (длина int).

Для чего-нибудь короче - возьмите следующий более длинный примитив и просто используйте его.

0
ответ дан 14 December 2019 в 04:35
поделиться

Хорошо, вы, должно быть, имели в виду 6 байтов данных. Затем ваша математика складывается (int плюс short составляет 6 байтов).

Как говорили другие, коллекция была бы лучше, но похоже, что вам нужно упаковать все в структуру.

Самый большой числовой тип - десятичный, его ширина - 128 бит, а long - 64. Вы можете использовать их, если вы действительно , действительно что хранить эти данные в стеке и смежные (как это звучит так).

0
ответ дан 14 December 2019 в 04:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: