【问题标题】:C#: How to Rotate Left the Bits of a Byte?C#:如何向左旋转一个字节的位?
【发布时间】:2020-06-30 14:52:04
【问题描述】:

我有一个包含0xE10x04 的字节数组,我需要操纵它来生成0x104,我正在努力解决它。我被告知要执行以下操作:

  1. 0xE1 AND 0x1F = 0x01
  2. 左移 8 位 = 0x100
  3. 0x04 添加 0x100 = 0x104

制造商的原始说明:

  • 0xE1 大于 0xE0
  • 0xE1 AND 0x1F = 0x01
  • 左移 8 位 = 0x100
  • 读取下一个字节 = 0x04
  • 0x04 添加 0x100 = 0x104

我无法让#2 工作。我尝试了this SO questionBitRotator.RotateLeft 方法和BitOperations.RotateLeft 方法的扩展方法,都没有成功获得0x100。我该怎么做才能到达0x100

我以前从来没有做过位级别的操作,所以我很苦恼。

更新

我正在解析 GPS 报告。报告中有大小为 1 或 2 个字节的字段。如果字节0 的值小于0xE0,则该字段的大小为1 个字节。否则,大小为 2 个字节,我应该使用上述步骤来获得实际值。引用文档:

任何指定为 1 字节/2 字节字段的字段都是使用以下编码的无符号整数: 如果第一个字节小于 0xE0(十进制 224),则字段大小为 1 字节,值为整个字节的值。如果第一个字节大于或等于 0xE0,则字段大小为 2 字节,值是 2 字节字段的 lsb 13 位的值(最高有效字节在前)。

这是我正在使用的方法(LINQPad 中的原型设计):

private static OneTwoField<Type> GetItemType(
    ReadOnlySpan<byte> itemBytes) {
    if (itemBytes[0] < 224) {
        return new OneTwoField<Type>(1, (Type)itemBytes[0]);
    }

    itemBytes[0..2].DumpToTable();

    //  What do I do to get to the real value?
    var type = ???;

    return new OneTwoField<Type>(2, type);
}

DumpToTable() 扩展产生以下结果:

这是OneTwoField&lt;T&gt;

public struct OneTwoField<T> {
    public OneTwoField(
        byte size,
        T value) {
        Offset = size == 1 ? 0 : 1;
        Size = size;
        Value = value;
    }

    public int Offset { get; }
    public byte Size { get; }
    public T Value { get; }
}

这是Type

[Flags]
public enum Type :
    short {
    General = 0x00,
    Versions = 0x104
}

【问题讨论】:

  • 0x100 的结果不适合 byte 那么您使用的实际类型是什么?在一个字节上左循环 8 位应该会产生完全相同的值。请显示您尝试过的确切代码,以便我们帮助查明问题。
  • @juharr,我已经更新了这个问题,提供了更多关于我正在处理的内容以及我如何处理它的信息。
  • 那句话说 lsb 13-bits of the 2-byte field。我认为应该是“最后一个”而不是“lsb”?
  • 另外,Type 是一个用于枚举的可怕名称,因为它已经是一个类的名称。这显然不是一组标志(这些标志的幂为 2 从 0 开始增加)。看起来你真的只需要常量值,而 OneTwoField 不需要是通用的
  • 这就是文档所说的,所以我无法真正回答这个问题。我所要做的只是文档(在其他领域已被证明是错误的)和制造商提供的关于如何读取其 2 个字节的说明(我现在也引用了它们)。命名现在都悬而未决。我不得不改变它十几次,因为我勉强凑合。应该是ItemType,但就像我说的,这是一个原型。

标签: c# bit-manipulation bitwise-operators


【解决方案1】:

Bitwise left shift operator &lt;&lt;

byte step1 = 0xE1 & 0x1F; //0x01
short step2 = step1 << 8; //0x100

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-05
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    • 2020-05-27
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    相关资源
    最近更新 更多