BitConverter 如何将字节重构为短字节
How does the BitConverter reconstruct bytes to a short
所以我目前正在尝试了解更多关于字节顺序以及字节如何转换为短裤、整数等的信息。
我想我应该从简单的开始,首先将一个短的 ("30000")
转换为两个字节并将其存储在 MemoryStream
中
private static void WriteShort(short constValue)
{
_stream.WriteByte((byte)(constValue & 255));
_stream.WriteByte((byte)(constValue >> 8));
}
如果我理解正确,我首先使用按位与运算符 &
.
进行一些位掩码
0000 0000 1111 1111 &
0111 0101 0011 0000
这将导致一个看起来像这样的字节 0011 0000
,我会将其写入 MemoryStream
。所以现在 MemoryStream
包含一个字节数组,看起来像这样 [48]
然后我根据相同的值写另一个字节 30000
但我将字节向右移动 8 位以获得最左边的 8 位 0111 0101 (117)
并将其写为MemoryStream
的一个字节。所以现在字节数组看起来像这样 [48, 117]
我觉得那部分很清楚,是短片的重构让我有点困惑。
为什么我需要在重建短片时进行相同的位移?我认为这个问题与我的另一个问题有些相关,即“+”运算符如何将“48”和“117”转换为 30000?
BitConverter.ToInt16(_stream.ToArray());
如何知道要移动哪些字节等以输出正确的值?
private static short ReadShort()
{
_stream.Position = 0;
return (short)((_stream.ReadByte() & 255) +
(_stream.ReadByte() << 8));
}
整个程序
internal class Program
{
private static MemoryStream _stream;
static void Main(string[] args)
{
Console.WriteLine(117 << 8);
_stream = new MemoryStream();
short constValue = 30000;
WriteShort(constValue);
var v = ReadShort();
/* True */
Console.WriteLine($"Is Little Endian: {BitConverter.IsLittleEndian}");
}
private static void WriteShort(short constValue)
{
_stream.WriteByte((byte)(constValue & 255));
_stream.WriteByte((byte)(constValue >> 8));
}
private static short ReadShort()
{
_stream.Position = 0;
return (short)((_stream.ReadByte() & 255) +
(_stream.ReadByte() << 8));
}
}
所以你有两个字节,
0011 0000
0111 0101
让我们也对两个值进行零扩展,以便它们都是 16 位值:
0000 0000 0011 0000
0000 0000 0111 0101
将这些数字加在一起显然不会得到原始数字。我们还可以看到 _stream.ReadByte() & 255
并没有对 _stream.ReadByte()
做任何有意义的事情。但是,移动最后一个数字将导致
0000 0000 0011 0000
0111 0101 0000 0000
而且我们可以看到将这些数字相加或 OR-ing 在一起会得到原始值。请注意,BitConverter
不一定需要执行此舞蹈,它可以简单地使用本机代码直接复制字节。将较大的整数转换为字节时,您可能需要考虑 Endianness,因为整数的表示方式因平台而异。
所以我目前正在尝试了解更多关于字节顺序以及字节如何转换为短裤、整数等的信息。
我想我应该从简单的开始,首先将一个短的 ("30000")
转换为两个字节并将其存储在 MemoryStream
private static void WriteShort(short constValue)
{
_stream.WriteByte((byte)(constValue & 255));
_stream.WriteByte((byte)(constValue >> 8));
}
如果我理解正确,我首先使用按位与运算符 &
.
0000 0000 1111 1111 &
0111 0101 0011 0000
这将导致一个看起来像这样的字节 0011 0000
,我会将其写入 MemoryStream
。所以现在 MemoryStream
包含一个字节数组,看起来像这样 [48]
然后我根据相同的值写另一个字节 30000
但我将字节向右移动 8 位以获得最左边的 8 位 0111 0101 (117)
并将其写为MemoryStream
的一个字节。所以现在字节数组看起来像这样 [48, 117]
我觉得那部分很清楚,是短片的重构让我有点困惑。
为什么我需要在重建短片时进行相同的位移?我认为这个问题与我的另一个问题有些相关,即“+”运算符如何将“48”和“117”转换为 30000?
BitConverter.ToInt16(_stream.ToArray());
如何知道要移动哪些字节等以输出正确的值?
private static short ReadShort()
{
_stream.Position = 0;
return (short)((_stream.ReadByte() & 255) +
(_stream.ReadByte() << 8));
}
整个程序
internal class Program
{
private static MemoryStream _stream;
static void Main(string[] args)
{
Console.WriteLine(117 << 8);
_stream = new MemoryStream();
short constValue = 30000;
WriteShort(constValue);
var v = ReadShort();
/* True */
Console.WriteLine($"Is Little Endian: {BitConverter.IsLittleEndian}");
}
private static void WriteShort(short constValue)
{
_stream.WriteByte((byte)(constValue & 255));
_stream.WriteByte((byte)(constValue >> 8));
}
private static short ReadShort()
{
_stream.Position = 0;
return (short)((_stream.ReadByte() & 255) +
(_stream.ReadByte() << 8));
}
}
所以你有两个字节,
0011 0000
0111 0101
让我们也对两个值进行零扩展,以便它们都是 16 位值:
0000 0000 0011 0000
0000 0000 0111 0101
将这些数字加在一起显然不会得到原始数字。我们还可以看到 _stream.ReadByte() & 255
并没有对 _stream.ReadByte()
做任何有意义的事情。但是,移动最后一个数字将导致
0000 0000 0011 0000
0111 0101 0000 0000
而且我们可以看到将这些数字相加或 OR-ing 在一起会得到原始值。请注意,BitConverter
不一定需要执行此舞蹈,它可以简单地使用本机代码直接复制字节。将较大的整数转换为字节时,您可能需要考虑 Endianness,因为整数的表示方式因平台而异。