如何将BCD转换为十进制?

Amm*_*mar 5 c bcd

如何在表示方面将二进制编码的十进制数转换为十进制数?我不想转换它的值,而是它的表示,这就是我的意思.

我想转换0x11成十进制11(不17),并0x2020(不32).

unsigned char day = 0x11;
unsigned char month = 0x12;

int dayDecimal, monthDecimal;
Run Code Online (Sandbox Code Playgroud)

我希望dayDecimal 11和monthDecimal = 12.我将使用0x00到0x60之间的范围,所以它应该是可能的.不会有'A','B','C','D','E','F.

更新:

我实际上是从RTCC芯片中读取时间,作为我正在进行的嵌入式项目的一部分.以该形式返回小时,分钟,日和月.例如,如果分钟是0x40则表示40分钟而不是64分钟,所以我需要能够正确地解释它.我需要以某种方式将0x40转换为40而不是64.我希望这是可能的.

谢谢!

Jon*_*ler 13

您需要使用两个nybbles,将更重要的nybble乘以10并添加不太重要的:

uint8_t hex = 0x11;
assert(((hex & 0xF0) >> 4) < 10);  // More significant nybble is valid
assert((hex & 0x0F) < 10);         // Less significant nybble is valid
int dec = ((hex & 0xF0) >> 4) * 10 + (hex & 0x0F);
Run Code Online (Sandbox Code Playgroud)

如果断言被禁用但输入是伪造的(例如0xFF),那么你得到了你应得的东西:GIGO - 垃圾输入,垃圾输出.您可以轻松地将其包装到(内联)函数中:

static inline int bcd_decimal(uint8_t hex)
{
    assert(((hex & 0xF0) >> 4) < 10);  // More significant nybble is valid
    assert((hex & 0x0F) < 10);         // Less significant nybble is valid
    int dec = ((hex & 0xF0) >> 4) * 10 + (hex & 0x0F);
    return dec;
}       
Run Code Online (Sandbox Code Playgroud)

这种转换让人联想到BCD - Binary Coded Decimal.

  • 在大多数系统中,`uint8_t`(来自`<stdint.h>`)等同于`unsigned char`.事实上,我认为可以说,如果系统提供`uint8_t`,那么它相当于`unsigned char`,但这种类型在理论上是可选的.如果你不喜欢它,你可以在不改变功能的情况下将类型更改为`unsigned char`.这些断言是为了确保您对所声称的有效输入诚实.如果您从未提供虚假数据,则断言永远不会触发.如果您不喜欢断言并且不介意玩火,则可以删除断言. (2认同)

chq*_*lie 5

没有错误检查的非常简单的方法:

int bcd_to_decimal(unsigned char x) {
    return x - 6 * (x >> 4);
}
Run Code Online (Sandbox Code Playgroud)