当使用Int32数组初始化时,BitArray以相反的顺序存储位

amh*_*hed 2 c# endianness bitarray

描述我错过理解的最好方法是使用代码本身:

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??)
Run Code Online (Sandbox Code Playgroud)

我一直在读,bitarray从LSB迭代到MSB,那么从十六进制字符串开始初始化bitarray的最佳方法是什么呢?

Jas*_*aat 8

我觉得你在想错了.你为什么甚至使用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
Run Code Online (Sandbox Code Playgroud)

无论架构如何命令字节,16位数字的第0位始终表示最低有效位(此处最右侧),第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
Run Code Online (Sandbox Code Playgroud)

你正在做的是试图将你想要的字节顺序强加到它不属于的位数组.如果你想要反转字节,那么你将在位数组中得到这个,这使得意义不大,并且意味着当你得到整数后退时你将不得不再次反转字节:

---2--- ---1--- ---4--- ---3---
0 1 0 0 1 0 0 0 0 0 1 0 1 1 0 0
Run Code Online (Sandbox Code Playgroud)

我不认为这对存储整数有任何意义.如果你想在BitArray中存储一个32位数字的big-endian表示,那么你真正存储的是一个字节数组,恰好是32位数字的big-endian表示,你应该转换为一个字节数组首先使它成为大端,如果有必要,然后将它放入BitArray:

int number = 0x1234;
byte[] bytes = BitConverter.GetBytes(number);
if (BitConverter.IsLittleEndian)
{
    bytes = bytes.Reverse().ToArray();
}
BitArray ba = new BitArray(bytes);
Run Code Online (Sandbox Code Playgroud)