使用位移和或运算的整数标识符的来回计算
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
中得到的 boardId
和 unitType
在你移动有点值。
如果您仍然对它的工作原理感到有点困惑,我建议您在纸上尝试一些值,以二进制显示所有内容 - 从消息 ID、板 ID 和单元类型开始,构建您的标识符(可能画线在数字的不同部分之间)然后看看当你像上面那样应用 shifting/masking 时会发生什么。
早上好,不知道这个问题是否在正确的 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
中得到的 boardId
和 unitType
在你移动有点值。
如果您仍然对它的工作原理感到有点困惑,我建议您在纸上尝试一些值,以二进制显示所有内容 - 从消息 ID、板 ID 和单元类型开始,构建您的标识符(可能画线在数字的不同部分之间)然后看看当你像上面那样应用 shifting/masking 时会发生什么。