2015-03-11 2 views
0

Доброе утро, не знаю, попадает ли этот вопрос в правильную сеть StackExchange. Если нет, простите меня.Вычисление целого числа взад и вперёд Идентификатор с использованием сдвига битов и операций OR

Я получил десятичное/целочисленное значение идентификатора, которое мне нужно разделить на три отдельных значения. Предположим, что у нас есть программа ABC. Программа ABC генерирует значение идентификатора десятичного/целого числа, используя следующую формулу:

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

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

identifier делает сейчас содержит значение, основанное на битовом сдвиге и операции ИЛИ.

Теперь нам нужно разработать программу CDE. Программа CDE считывает файл журнала, который содержит десятичный/целочисленный идентификатор и некоторые другие значения, которые не нужны для этого случая. Программа 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); 
     } 
    } 
} 

Может ли кто-нибудь сказать мне, что я делаю неправильно, и если его даже можно получить в начале три значения?

ответ

3

Просто маска и смена. У вас уже есть комментарий, описывающий формат:

// 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 - так «Андинг» с этим просто оставляет нижние 5 битов , 7 равно 111 в двоичном формате - так что «и» с этим просто оставляет нижние 3 бита, что вы хотите от identifier для boardId и unitType после того, как вы немного измените значения.

Если вы все еще немного смущены тем, как это работает, я предлагаю вам попробовать некоторые значения на бумаге, показывая все в двоичном формате - начните с идентификатора сообщения, идентификатора платы и типа устройства, создайте свой идентификатор (возможно, различные части номера), а затем посмотрите, что происходит, когда вы применяете перемещение/маскирование, как указано выше.

+0

Спасибо, сделал трюк. Да, я немного смущен, но я сделаю бумажный трюк! –

Смежные вопросы