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

时间:2015-04-05 03:34:42

标签: 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??)

我一直在读这个比特阵列从LSB迭代到MSB,那么我最好的方法是从十六进制字符串开始初始化比特阵列呢?

1 个答案:

答案 0 :(得分:8)

我认为你错了。你为什么甚至使用BitArray? Endianness是字节相关的约定,BitArray只是一个位数组。由于它首先是最低有效位,因此在位数组中存储32位数的正确方法是在索引0处将位0和在索引31处的位31,这不仅仅是我个人偏向于-endianness(第0位应该在字节0中,而不是字节3,为了善良),它是因为BitArray存储数组中索引0处的字节的第0位。它还在数组的第0位存储32位整数的第0位,无论您所在平台的字节顺序如何。

例如,不是你的整数9669,而是看看1234.无论你使用什么平台,这个16位数字都有以下位表示,因为我们写了一个最重要的十六进制数字左边是十六进制数字1,右边是最低有效十六进制数字4,右边是第0位(人类约定):

  1    2    3    4
0001 0010 0011 0100

无论架构如何命令字节,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

您正在尝试将您想要的字节顺序强加到它不属于的位数组上。如果你想要反转字节,那么你就会在位数组中得到这个,这使得意义不大,并且意味着当你得到整数时,你必须再次反转字节:

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

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

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