Good morning, don't know if this question is hitting the right StackExchange network. If not please forgive me.
I got an decimal/integer identifier value which i need to split into three separate values. Lets assume we have program ABC. Program ABC is generating the decimal/integer identifier value using this formula:
int identifier = 0;
int unitTypeId = 1;
int boardId = 4;
int messageId = 20;
identifier = (((unitTypeId) << 8) | ((boardId) << 5) | (messageId));
identifier
does now contain a value based on the bit shift and OR operation.
Now we have to develop Program CDE. Program CDE reads out an log file which contains the decimal/integer identifier and some other values which are not necessary for this case. Program CDE has to split the read identifier into the the three values:
int unitTypeId = 1;
int boardId = 4;
int messageId = 20;
First: Is there a way to achieve this?
My first attempt looks like this, but to be honest i don't get the origin values which the identifier is based on.
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);
}
}
}
Can somebody tell me what I'm doing wrong and if its even possible to get to the origin three values?
Just mask and shift. You've already got a comment describing the format:
// Message identifiers are constructed:
// Unit Type Bit 8-10
// Board ID Bit 5-7
// Unit Specific Message Ids Bit 0-4
So the reversal code is:
int messageId = identifier & 0x1f;
int boardId = (identifier >> 5) & 7;
int unitType = (identifier >> 8) & 7;
Here 0x1f is 11111 in binary - so "anding" with that just leaves the bottom 5 bits. 7 is 111 in binary - so "anding" with that just leaves the bottom 3 bits, which is what you want from identifier
for boardId
and unitType
after you've shift the values a bit.
If you're still slightly confused about how that works, I suggest you try some values on paper, showing everything in binary - start with a message ID, board ID and unit type, construct your identifier (possibly drawing lines between the different parts of the number) and then see what happens when you apply the shifting/masking as above.
See more on this question at Stackoverflow