2

I'm trying to convert an array of bits to an array of bytes, except my operations seem to be reading my bits in the opposite direction from what I want them to be. For example, say the array of binary bits is 10110111 11000000 00000110. I want the byte array to be {B7, C0, 06}. Instead, my code below produces an output of of {ED, 03, 60} i.e. it reads every 8 bits in the opposite direction. Could anyone provide me some suggestions as to where I am going wrong?

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
  • 4
    Reduce your test case to the simplest possible input (e.g. 8 bits) then actually debug the code by running in a debugger and/or adding debug print statements. Commented May 30, 2020 at 1:39
  • Like all numbers, digits in a binary number goes from right to left. The rightmost digit is the least significant digit (bit 0 for binary numbers). Because of that I suggest you start at the rightmost digit and work towards the left. Commented May 30, 2020 at 1:43
  • 2
    If bit_len is not an integral multiple of 8, your malloc will come up short. You want to round up the number of bytes: uint8_t* hex_arr = malloc((bit_len + 7) / 8); Commented May 30, 2020 at 1:51

3 Answers 3

3

Strictly speaking, you don't need two loops, since the two arrays move in lock-step up to a factor of 8.

Your input array is as follows:

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};

The desired output is

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

Notice that the most significant bit comes first in this representation. Bits 0-8 in the array are the most to least significant bits in byte 0 of the output and so on.

This plays very well with how basic looping and bit-shifting works. You can push the bits one by one into the least significant bit of the output array:

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];
}

The moral of the story is that you must be careful as to how you define your representations and your data. Make sure that you understand where you want things to go conceptually, and you won't have a problem with either graphical or internal representations.

Sign up to request clarification or add additional context in comments.

2 Comments

@DavidC.Rankin. For this application, it's irrelevant whether you have an array on the stack or a pointer to an array on the heap.
@DavidC.Rankin. I get no problem with the declaration, although it likely does something other than what I want. I've gone ahead and changed it as you suggest for completeness.
0

The value that you're shifting is where the problem in.

The first time you enter the inner loop, i is 0 and j is 0. This makes j-i 0 so the value in question gets OR'ed into the rightmost bit instead of the leftmost. Then when j is 1 your shift 1 so the bit goes into the second right bit instead of the second left.

So your shift is going from 0 to 7 when it should be going from 7 to 0. You fix this by subtracting the shift amount from 7.

hex_arr[index] |= bit_arr[j] << (7 - (j - i));

1 Comment

Or you could do a single loop and hex[i/8] |= (bit_arr[i] << (7 - (i % 8)));
0

You should change this:

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

into this:

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

because your shifts reorder bits in the opposite direction.

1 Comment

This breaks the loop on i since it uses j in i = j.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.