Home > Blockchain >  C binary number in array to decimal
C binary number in array to decimal

Time:05-11

What is happening inside the loop in binary_array_to_numbers(). I know what it is doing, I don't understand how its doing it though. First time seeing the use of << and |. Thanks in advance.

unsigned binary_array_to_numbers(const unsigned *bits, size_t count) {
   unsigned res = 0;
   for (size_t i = 0; i < count; i  )
      res = res << 1 | bits[i];
   return res;
}

int main(void) {
   unsigned bits[] = {0, 0, 1, 0};
   unsigned received = binary_array_to_numbers(bits, sizeof(bits) / sizeof(bits[0]));
   return 0;
}

CodePudding user response:

The left shift operator res << 1 shifts the res by 1 bit, so the the right-most bit is now zero. Then you apply the bit-wise or operator | to set that right-most bit to the value of bits[i] (this assumes bits is an array of 0 or 1 and stored big-endian, if it's not your algorithm will not work).

Let's say bits = { 1, 0, 1 } (i.e. 5; it's more interesting than 2 in your example). Here is what happens on each iteration:

0.

res = res << 1 | bits[0]
res = 0x0 << 1 | 1
res = 1
res = 1 << 1 | bits[1]
res = 0x2 | 0
res = 0x2
res = 0x2 << 1 | bits[2]
res = 0x4 | 1
res = 0x5

CodePudding user response:

Left Shift Operator

Left shift operator shifts all bits towards left by a certain number of specified bits. The bit positions that have been vacated by the left shift operator are filled with 0. The symbol of the left shift operator is <<.

Bitwise OR operator

The output of bitwise OR is 1 if at least one corresponding bit of two operands is 1. In C, bitwise OR operator is denoted by |.

CodePudding user response:

  • sizeof(bits) / sizeof(bits[0]) is a common method to use when you want to calculate the number of items of a fixed size array at compile-time. In this case the compiler will silently replace that whole expression with 4.

  • The resulting integer type of a sizeof operation is the size_t type, which is a large unsigned integer suitable for describing array sizes etc. Therefore this type is used as parameter to the function.

  • The array is passed to the function as const unsigned * which means it is read-only and won't get modified by the function. This is good practice and called const correctness.

  • res in the function forms a binary bit-field.

  • Operator precedence in the expression res = res << 1 | bits[i]; gives [] over << over | over =. That is, it's equivalent to:

    res = ( (res << 1) | bits[i] );
    
  • res << 1 shifts the previous stored result one bit to the left. At the first time of the loop this is all zeroes. When the value is shifted, a zero appears on the least significant bit (LSB).

  • The bitwise OR | is taken between everything stored in res whatever is stored in bits[i], which happens to be either 0 or 1 in this case, stored in the LSB of bits[i].

    Since the rest of bits[i] is zero, only this LSB data matters for the OR. And in case of res we know that its LSB is zero. So in this specific case, it is the same as moving the contents of bits[i] into the LSB of res, without touching any other bits already stored in res.

  • The result will be a binary bitfield of value 0010 or if you will hex 0x2.

  • Related