This may be a really dumb question, but why is 0xF used in the bitwise operations when converting from a BCD values to an integer. I understand that 0xF represents something like 0x15, which is equal to 00010101 in binary. However, why is this particular value used in the bitwise operation in the above program? What is the significance of this value?
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#define N_BCD_DIGITS 8
uint32_t packed_bcd(uint32_t packed_bcd);
int main(int argc, char *argv[]) {
for (int arg = 1; arg < argc; arg++) {
long l = strtol(argv[arg], NULL, 0);
assert(l >= 0 && l <= UINT32_MAX);
uint32_t packed_bcd_value = l;
printf("%lu\n", (unsigned long)packed_bcd(packed_bcd_value));
}
return 0;
}
// given a packed BCD encoded value between 0 .. 99999999
// return the corresponding integer
uint32_t packed_bcd(uint32_t packed_bcd_value) {
int result = 0;
for (int i = N_BCD_DIGITS - 1; i >= 0; i--) {
int decimal_digit = (packed_bcd_value >> (4 * i)) & 0xF;
assert(decimal_digit < 10);
result = result * 10 + decimal_digit;
}
return result;
}
The expression
(packed_bcd_value >> (4 * i)) & 0xFextracts the i-th digit (numbered 0 to 7) from the BCD encoded value: the valuepacked_bcd_valueis shifted right by4 * ibits, shifting out the bits from the digits with a lower number bits, and then the low 4 bits are extracted by masking off the other bits with a mask of0b1111, ie: all 4 low bits set.0xFis the hex representation for this number15. As of C23, you could use0b1111, but not all current compilers support this syntax.You can test your program by giving command line arguments starting with
0xasstrtol()with a base of0will convert these as hexadecimal: