BitArray 在使用 Int32 数组初始化时以相反的顺序存储位
BitArray stores bits in reverse order when initialized with an Int32 array
描述我理解错误的最佳方式是使用代码本身:
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,那么从十六进制字符串开始初始化位数组的最佳方法是什么?
我觉得你想错了。你为什么还要使用 BitArray? Endianness 是一个 byte-related 约定,BitArray 只是一个位数组。因为它是最低有效位在前,所以在位数组中存储 32 位数字的正确方法是在索引 0 处使用位 0,在索引 31 处使用位 31。这不仅仅是我个人对小字节序的偏见(看在上帝的份上,位 0 应该在字节 0 而不是字节 3 中),这是因为 BitArray 将字节的位 0 存储在数组中的索引 0 处。它还将 32 位整数的位 0 存储在数组的位 0 中,无论您所在平台的字节顺序如何。
例如,让我们看一下 1234,而不是您的整数 9669。无论您在哪个平台上,该 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 位数字的大端表示,那么你真正存储的是一个字节数组,它恰好是一个 32 位数字的大端表示,你应该转换为一个字节数组在将它放入 BitArray 之前,如有必要,首先使其成为 big-endian:
int number = 0x1234;
byte[] bytes = BitConverter.GetBytes(number);
if (BitConverter.IsLittleEndian)
{
bytes = bytes.Reverse().ToArray();
}
BitArray ba = new BitArray(bytes);
描述我理解错误的最佳方式是使用代码本身:
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,那么从十六进制字符串开始初始化位数组的最佳方法是什么?
我觉得你想错了。你为什么还要使用 BitArray? Endianness 是一个 byte-related 约定,BitArray 只是一个位数组。因为它是最低有效位在前,所以在位数组中存储 32 位数字的正确方法是在索引 0 处使用位 0,在索引 31 处使用位 31。这不仅仅是我个人对小字节序的偏见(看在上帝的份上,位 0 应该在字节 0 而不是字节 3 中),这是因为 BitArray 将字节的位 0 存储在数组中的索引 0 处。它还将 32 位整数的位 0 存储在数组的位 0 中,无论您所在平台的字节顺序如何。
例如,让我们看一下 1234,而不是您的整数 9669。无论您在哪个平台上,该 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 位数字的大端表示,那么你真正存储的是一个字节数组,它恰好是一个 32 位数字的大端表示,你应该转换为一个字节数组在将它放入 BitArray 之前,如有必要,首先使其成为 big-endian:
int number = 0x1234;
byte[] bytes = BitConverter.GetBytes(number);
if (BitConverter.IsLittleEndian)
{
bytes = bytes.Reverse().ToArray();
}
BitArray ba = new BitArray(bytes);