这可能是一个非常愚蠢的问题,但是当从 BCD 值转换为整数时,为什么在按位运算中使用 0xF?我理解0xF代表类似0x15的东西,它等于二进制的00010101。 但是,为什么在上面的程序中按位运算使用这个特定的值呢?这个值有什么意义?
#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;
}
表达式
(packed_bcd_value >> (4 * i)) & 0xF
从BCD编码值中提取第i位数字。移出 4 * i
位,然后使用掩码 0b1111
提取 4 个低位,即:设置所有 4 个低位。 0xF
是该数字的十六进制表示形式 15
,从 C23 开始,您可以使用 0b1111
,但并非所有当前编译器都支持此语法。
您可以通过提供以
0x
开头的命令行参数来测试您的程序,因为以 strtol()
为基数的 0
会将这些参数转换为十六进制:
sh$ ./myprogram 0x123 291 100
123
123
64