BitArray сохраняет биты в обратном порядке при инициализации с массивом Int32

Лучший способ описать мое непонимание с помощью самого кода:

var emptyByteArray = new byte[2];

var specificByteArray = new byte[] {150, 105}; //0x96 = 150, 0x69 = 105
var bitArray1 = new BitArray(specificByteArray);
bitArray1.CopyTo(emptyByteArray, 0); //[0]: 150, [1]:105

var hexString = "9669";
var intValueForHex = Convert.ToInt32(hexString, 16); //16 indicates to convert from hex
var bitArray2 = new BitArray(new[] {intValueForHex}) {Length = 16}; //Length=16 truncates the BitArray

bitArray2.CopyTo(emptyByteArray, 0); //[0]:105, [1]:150 (inversed, why??)

Я читал, что bitarray выполняет итерации от LSB до MSB, как мне лучше всего инициализировать bitarray, начиная с шестнадцатеричной строки?

1 ответ

Решение

Я думаю, что вы думаете об этом неправильно. Почему вы даже используете BitArray? Endianness - это соглашение, связанное с байтами, BitArray - это просто массив битов. Поскольку вначале это наименее значимый бит, правильный способ хранения 32-битного числа в битовом массиве - это бит 0 в индексе 0 и бит 31 в индексе 31. Это не просто мой личный уклон в сторону порядка байтов (ради бога 0 должен быть в байте 0, а не в байте 3), это потому, что BitArray хранит бит 0 байта с индексом 0 в массиве. Он также хранит бит 0 32-разрядного целого числа в бите 0 массива, независимо от того, какой порядок платформы используется.

Например, вместо целого числа 9669, давайте посмотрим на 1234. Независимо от того, на какой платформе вы находитесь, это 16-битное число имеет следующее битовое представление, потому что мы записываем шестнадцатеричное число с самой значимой шестнадцатеричной цифрой. 1 слева и наименее значимая шестнадцатеричная цифра 4 справа бит 0 справа (человеческое соглашение):

  1    2    3    4
0001 0010 0011 0100

Независимо от того, как архитектура упорядочивает байты, бит 0 16-битного числа всегда означает самый младший бит (самый правый здесь), а бит 15 означает самый старший бит (самый левый здесь). Из-за этого ваш битовый массив всегда будет таким, с битом 0 слева, потому что так я читаю массив (индекс 0 - бит 0, а индекс 15 - бит 15):

---4--- ---3--- ---2--- ---1---
0 0 1 0 1 1 0 0 0 1 0 0 1 0 0 0

То, что вы делаете, это пытаетесь наложить нужный вам порядок байтов в массив битов, где он не принадлежит. Если вы хотите обратить байты в обратном порядке, вы получите это в битовом массиве, что имеет гораздо меньший смысл и означает, что вам придется снова инвертировать байты, когда вы получите целое число обратно:

---2--- ---1--- ---4--- ---3---
0 1 0 0 1 0 0 0 0 0 1 0 1 1 0 0

Я не думаю, что в этом есть какой-то смысл хранить целое число. Если вы хотите сохранить представление с прямым порядком байтов для 32-разрядного числа в BitArray, то на самом деле вы храните байтовый массив, который просто является представлением с прямым порядком байтов для 32-разрядного числа, и вам следует преобразовать его в байтовый массив сначала делает его старшим, если необходимо, перед помещением в BitArray:

int number = 0x1234;
byte[] bytes = BitConverter.GetBytes(number);
if (BitConverter.IsLittleEndian)
{
    bytes = bytes.Reverse().ToArray();
}
BitArray ba = new BitArray(bytes);
Другие вопросы по тегам