使用位移和或运算的整数标识符的来回计算

Back and forth calculation of integer Identifier using bit shifting and OR operations

早上好,不知道这个问题是否在正确的 StackExchange 网络上。如有不妥请见谅

我得到了一个 decimal/integer 标识符值,我需要将其拆分为三个单独的值。假设我们有程序 ABC。程序 ABC 正在使用以下公式生成 decimal/integer 标识符值:

int identifier = 0;
int unitTypeId = 1;
int boardId = 4;
int messageId = 20;

identifier = (((unitTypeId) << 8) | ((boardId) << 5) | (messageId));

identifier 现在确实包含一个基于移位和 OR 运算的值。

现在我们要开发程序CDE了。程序 CDE 读出一个日志文件,其中包含 decimal/integer 标识符和一些在这种情况下不需要的其他值。程序 CDE 必须将读取标识符拆分为三个值:

int unitTypeId = 1;
int boardId = 4;
int messageId = 20;

第一:有办法实现吗?

我的第一次尝试看起来像这样,但说实话,我没有得到标识符所基于的原始值。

private void resolveIdentifier()
{
    this.IdentifierBits = Convert.ToString(this.OriginIdentifier, 2); //Convert to binary in a string

    // Message identifiers are constructed:         
    // Unit Type                    Bit 8-10
    // Board ID                     Bit 5-7
    // Unit Specific Message Ids    Bit 0-4

    int[] bits = this.IdentifierBits.PadLeft(11, '0') // Add 0's from left
                     .Select(c => int.Parse(c.ToString())) // convert each char to int
                     .ToArray(); // Convert IEnumerable from select to Array

    Array.Reverse(bits);

    for (int i = 0; i < bits.Length; i++)
    {
        int calcValue = i;
        if (i < 5) // Message Id
        {
            this.MessageId += (int)Math.Pow(2, calcValue);
        }
        else if (i > 4 && i < 8)
        {
            calcValue -= 5;
            this.BoardId += (int)Math.Pow(2, calcValue);
        }
        else
        {
            calcValue -= 8;
            this.Unit += (int)Math.Pow(2, calcValue);
        }
    }
}

有人能告诉我我做错了什么吗,是否有可能得到原始的三个值?

只需掩码和移动即可。您已经收到描述格式的评论:

// Message identifiers are constructed:         
// Unit Type                    Bit 8-10
// Board ID                     Bit 5-7
// Unit Specific Message Ids    Bit 0-4

所以反转码是:

int messageId = identifier & 0x1f;
int boardId = (identifier >> 5) & 7;
int unitType = (identifier >> 8) & 7;

这里的 0x1f 是二进制的 11111 - 所以 "anding" 只留下底部的 5 位。 7 在二进制中是 111 - 所以 "anding" 只留下底部的 3 位,这就是你想要从 identifier 中得到的 boardIdunitType 在你移动有点值。

如果您仍然对它的工作原理感到有点困惑,我建议您在纸上尝试一些值,以二进制显示所有内容 - 从消息 ID、板 ID 和单元类型开始,构建您的标识符(可能画线在数字的不同部分之间)然后看看当你像上面那样应用 shifting/masking 时会发生什么。