【问题标题】:How does the BitConverter reconstruct bytes to a shortBitConverter 如何将字节重构为短字节
【发布时间】:2022-04-20 20:23:15
【问题描述】:

所以我目前正在尝试更多地了解字节顺序以及字节如何转换为短裤、整数等。

我想我会从简单的开始,我会先将一个短 (\"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));
    }
}
  • 它不是同一个位移,而是&lt;&lt;而不是`>>`。
  • 是的,我注意到了,但是为什么我需要在向右移动后向左移动?
  • 撤消“右移”效果
  • 如果您使用 Windows 计算器计算 48 + (117 &lt;&lt; 8) - 或等效的 48 + 116 * 256 - 可能会更清楚?

标签: c# bit-manipulation bitwise-operators bit-shift


【解决方案1】:

所以你有两个字节,

0011 0000
0111 0101

也让零扩展这两个值,因此它们都是 16 位值:

0000 0000 0011 0000
0000 0000 0111 0101

只是将这些数字相加显然不会产生原始数字。我们还可以看到_stream.ReadByte() &amp; 255 并没有比_stream.ReadByte() 做任何有意义的事情。然而,移动最后一个数字将导致

0000 0000 0011 0000
0111 0101 0000 0000

我们可以看到将这些数字相加或 OR-ing 会产生原始值。请注意,BitConverter 不一定需要这样做,它可以简单地使用本机代码直接复制字节。将较大的整数转换为字节时,您可能需要考虑Endianness,因为整数的表示方式因平台而异。

【讨论】:

  • 这很有意义!那么当用位相加时,它与添加任何十进制数一样吗? 5 + 5 会产生一个新数字 10。那么比特也是一样的吗?我想这很令人困惑,因为两者中的一个在第一个字节之前有一堆 0。我想我应该将其视为添加两个短裤而不是添加两个字节?我希望我在这里有意义。
  • 在您的回答中,您显示添加了两个短裤,但代码指出添加了两个字节以创建一个简短的(_stream.ReadByte() &amp; 255) + (_stream.ReadByte() &lt;&lt; 8));,我相信这让我感到困惑。
  • @JohnA 添加字节时,它们将在添加之前在内部转换为 32 位数字。我省略了额外的 16 位,因为它们似乎不相关。关于签名号码的一些细节我不能 100% 确定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-05-04
  • 1970-01-01
  • 2012-06-04
  • 1970-01-01
  • 2023-02-26
相关资源
最近更新 更多