Преобразование кода Грея в двоичный код

Итак, я пытаюсь написать функцию, которая преобразует 7-битный код Грея в соответствующий 7-битный двоичный код.

Вот как конвертировать -

  • Биты значения серого ---- бит MS > (G6) G5 G4 G3 G2 G1 G0 *
  • Биты двоичного значения -- бит MS > (B6) B5 B4 B3 B2 B1 B0 *

  • B6 = G6 // биты MS всегда одинаковы

  • B5 = B6 ^ G5 // Исключительное ИЛИ между битами для построения 7-битного двоичного значения
  • B4 = B5 ^ G4
  • B3 = B4 ^ G3
  • B2 = B3 ^ G2
  • B1 = B2 ^ G1
  • B0 = B1 ^ G0

и вот моя функция до сих пор-

unsigned short Gray_to_Bin(unsigned short Gray)
{
unsigned short Bin;
unsigned short i;
unsigned short mask;

mask = 0x40; // Initial mask
Bin = 0;

Gray &= 0x7f; // Mask bit 7 (Index Bit)
Bin = Gray & mask; // Set B6 = G6

for (i=0; i<6; i++) // Set B5, B4, ..., B0
{

// Code needed here!!

}
return Bin;
}

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

Любые идеи/указатели? Спасибо :)


person S_Wheelan    schedule 15.03.2011    source источник


Ответы (7)


Следующее реализует побитовую сборку результата в соответствии с вашим требованием.

  • B6 = G6 // биты MS всегда одинаковы
  • B5 = B6 ^ G5
  • ...

Для B5 я просто сдвигаю значение B6 вправо на один бит, чтобы оно соответствовало серому биту G5, XOR их, а затем отфильтровываю другие биты с помощью операции &. Эти побитовые результаты объединяются по ИЛИ для создания общего результата. Повторите для последовательных битов. Для этого даже не стоит иметь цикл ... просто дополнительные возможные накладные расходы во время выполнения и сложность исходного кода.

unsigned short gray_to_binary(unsigned short gray)
{
    unsigned short result = gray & 64;
    result |= (gray ^ (result >> 1)) & 32;
    result |= (gray ^ (result >> 1)) & 16;
    result |= (gray ^ (result >> 1)) & 8;
    result |= (gray ^ (result >> 1)) & 4;
    result |= (gray ^ (result >> 1)) & 2;
    result |= (gray ^ (result >> 1)) & 1;
    return result;
}
person Tony Delroy    schedule 15.03.2011

Самый быстрый известный мне способ перевести код Грея в двоичный код реализует этот метод Java:

private static int grayToBin(int gray) {
   int bin = 0;
   while (gray != 0) {
      int decremented = gray - 1;
      bin ^= gray;
      bin ^= decremented;
      gray &= decremented;
   }
   return bin;
}
person korsak    schedule 27.12.2019

Более оптимизированный код для преобразования серого в двоичный код будет

int grayToBinary(int gray)
{
int binary=0;
for(;gray;gray=gray>>1)
{
    binary^=gray; //binary=binary^gray;
}
return binary;
}

Этот метод использует побитовый оператор.

person srikrishna123    schedule 23.05.2020

в чем проблема с тем, что вы написали в своем вопросе, я имею в виду, что в вашем заявлении вы можете написать B[i] = B[i+1]^G[i];, вам просто нужно изменить свое, чтобы оно шло от 4 до нуля

person Ali1S232    schedule 15.03.2011
comment
Ну, коды не в форме массива - поступающие коды Грея будут выглядеть как 0101 1100. Я не думал, что вы можете получить доступ к каждой цифре короткого замыкания, как в массиве? (Извините за невежество, я новичок в этом: P). Спасибо! - person S_Wheelan; 15.03.2011

Следующий код должен помочь:

for (int i = 0; i < 6; ++ i) {
    unsigned short j = 5 - i;
    unsigned short m = 1 << j;
    Bin |= ((Bin >> 1) & m) ^ (Gray & m);
}
person Sylvain Defresne    schedule 15.03.2011
comment
@S_Wheelan: не редактируйте код людей. Правильное написание / грамматика в порядке. Но исправление кода — это уловка. - person Martin York; 04.04.2011

Я думаю, что это должно выглядеть примерно так:

for(i=5; i >= 0; i--){
    Bin = Bin | ((Gray & 1<<i)>>i ^ (Bin & 1<<(i + 1))>>i)<<i;
}

Чтобы получить доступ к определенному биту, вы используете 1<<i для сдвига влево "1" i раз, получая число, состоящее из нулей, кроме единицы на i-м месте справа. Это может быть объединено с помощью AND с Gray или Bin, обнуляя все биты, кроме того, который нас интересует. Затем результат сдвигается вправо с помощью >>i, перемещая интересующий нас бит в крайнее правое положение. Мы используем ^ для xor двух битов, затем сдвигаем его влево туда, где принадлежит результирующий бит, и ИЛИ это ints Bin.

Это дает очень полезное объяснение.

person SecretMarmoset    schedule 15.03.2011

Практически для любого преобразования одного семибитного кода в другой самым простым решением является просто таблица, например: static unsigned char fromGray[] = { 0x00, 0x01, 0x03, 0x02, 0x06, 0x07, 0x05, 0x04, 0x0C, 0x0D 0x0F, 0x0E, 0x0A, 0x0B, 0x09, 0x08, 0x18, 0x18, 0x1B, 0x1A, 0x1E, 0x1F, 0x1D, 0x1C, 0x14, 0x15, 0x17, 0x16, 0x12, 0x13, 0x101, // .};

В какой-то момент между 8 и 16 битами вы, вероятно, захотите перейти к алгоритмическому подходу (хотя, учитывая память, доступную на современных процессорах, табличный подход действителен для довольно больших таблиц). Даже тогда я, вероятно, использовал бы таблицу для битов младшего разряда.

person James Kanze    schedule 15.03.2011