Преобразование массива битов в массив шестнадцатеричных чисел C посредством побитовых операций - PullRequest
2 голосов
/ 30 мая 2020

Я пытаюсь преобразовать массив бит в массив байтов, за исключением того, что мои операции, кажется, читают мои биты в противоположном направлении от того, что я хочу, чтобы они были. Например, предположим, что массив двоичных разрядов равен 10110111 11000000 00000110. Я хочу, чтобы байтовый массив был {B7, C0, 06}. Вместо этого мой код ниже дает на выходе {ED, 03, 60}, т.е. он читает каждые 8 ​​бит в противоположном направлении. Может ли кто-нибудь дать мне несколько советов относительно того, где я ошибаюсь?

void find_hex_arr(uint8_t* bit_arr, int bit_len) {
  uint8_t* hex_arr = malloc(bit_len/8);
  int index = 0;
  unsigned int i = 0;
  unsigned int j = 0;
  for (i = 0; i < bit_len; i = j) {
    for (j = i; j < i + 8; ++j) {
      hex_arr[index] |= bit_arr[j] << (j - i);
    }
    index++;
  }
}

Ответы [ 3 ]

3 голосов
/ 30 мая 2020

Строго говоря, вам не нужны два цикла, так как два массива перемещаются синхронно с коэффициентом 8.

Ваш входной массив выглядит следующим образом:

uint8_t bit_arr[] = {
    1, 0, 1, 1, 0, 1, 1, 1,
    1, 1, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 1, 1, 0};

Желаемый результат:

uint8_t expected[] = {0xB7, 0xC0, 0x06}

Обратите внимание, что старший бит идет первым в этом представлении. Биты 0-8 в массиве - это биты от старшего к младшему в байте 0 вывода и т. Д.

Это очень хорошо сочетается с принципами работы базовых c циклов и битового сдвига. Вы можете поместить sh биты один за другим в наименее значимый бит выходного массива:

uint8_t *hex_arr = malloc(bit_len / 8);
memset(hex_arr, 0, bit_len / 8);
for(int i = 0; i < bit_len; i++) {
    hex_arr[i / 8] <<= 1;
    hex_arr[i / 8] += bit_arr[i];
}

Мораль истории состоит в том, что вы должны быть осторожны при определении ваших представлений и данные. Убедитесь, что вы понимаете, где вы хотите, go концептуально, и у вас не будет проблем ни с графическим, ни с внутренним представлением.

0 голосов
/ 30 мая 2020

Значение, которое вы меняете, и есть проблема.

При первом вводе внутреннего l oop, i равно 0, а j равно 0. Это составляет j-i 0, поэтому значение, о котором идет речь, будет объединено оператором ИЛИ в крайний правый бит, а не в крайний левый. Затем, когда j равно 1, ваш сдвиг равен 1, поэтому бит переходит во второй правый бит, а не второй левый.

Итак, ваш сдвиг идет от 0 до 7, когда он должен идти от 7 до 0. Вы исправите это, вычтя величину сдвига из 7.

hex_arr[index] |= bit_arr[j] << (7 - (j - i));
0 голосов
/ 30 мая 2020

Вы должны изменить это:

for (i = 0; i < bit_len; i = j) {
    for (j = i; j < i + 8; ++j) {
      hex_arr[index] |= bit_arr[j] << (j - i);

на это:

for (i = 0; i < bit_len; i += 8) {
    for (j = 0; j < 8; ++j) {
      hex_arr[index] |= bit_arr[i+j] << (7 - j);

, потому что ваши биты переупорядочения сдвигаются в противоположном направлении.

...