为什么0xF用于从BCD值转换为整数的按位操作?

iyr7buue  于 2023-10-16  发布在  其他
关注(0)|答案(2)|浏览(158)

这可能是一个非常愚蠢的问题,但是为什么在从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;
}
wsxa1bj1

wsxa1bj11#

表达式(packed_bcd_value >> (4 * i)) & 0xF从BCD编码值中提取第i个数字(编号为0到7):值packed_bcd_value被右移4 * i比特,从具有较低数目比特的数字中移出比特,然后通过用掩码0b1111屏蔽掉其他比特来提取低4比特,即:所有4个低位设置。0xF是这个数字15的十六进制表示。从C23开始,您可以使用0b1111,但并非所有当前编译器都支持此语法。
你可以通过给出以0x开头的命令行参数来测试你的程序,因为以0为基数的strtol()会将这些参数转换为十六进制:

sh$ ./myprogram 0x123 291 100
123
123
64
mgdq6dx1

mgdq6dx12#

十六进制数中的一位表示半字节(4位)。
我知道0xF代表0x15,等于00010101
不,0xf十进制中是15(没有0x),在二进制中是0b1111
当你用0xf(0b1111)与任何值进行二进制AND时,结果将包含这个数字的低4的值。

相关问题