C语言 如何将BCD转换为十进制?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28133020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 11:42:44  来源:igfitidea点击:

How to convert BCD to decimal?

cbcd

提问by Ammar

How can I convert a binary-coded decimal number into a decimal number in terms of representation ? I don't want to convert the value of it but rather the representation of it, here is what I mean.

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

I want to convert 0x11to decimal 11(not 17) and 0x20to 20(not 32).

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

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

int dayDecimal, monthDecimal;

I want dayDecimal to be 11and monthDecimal = 12. I will be working with a range between 0x00 to 0x60 so it should be possible. There won't be 'A', 'B', 'C', 'D', 'E', 'F.

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

Update:

更新:

I am actually reading time from an RTCC chip as part of an embedded project I am working on. The hours, minutes, day, and month are returned in that form. For example if minutes are 0x40 then it means 40 minutes and not 64, so I need to able to keep the interpretation of it correctly. I need somehow to convert 0x40 into 40 and not 64. I hope that's possible.

我实际上正在从 RTCC 芯片读取时间,作为我正在处理的嵌入式项目的一部分。小时、分钟、日和月以这种形式返回。例如,如果分钟是 0x40 那么它意味着 40 分钟而不是 64,所以我需要能够正确地保持对它的解释。我需要以某种方式将 0x40 转换为 40 而不是 64。我希望这是可能的。

Thanks!

谢谢!

回答by Jonathan Leffler

You need to work with the two nybbles, multiplying the more significant nybble by ten and adding the less significant:

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

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);

If the assertions are disabled but the input is bogus (e.g. 0xFF), you get what you deserve: GIGO — garbage in, garbage out. You can easily wrap that into an (inline) function:

如果断言被禁用,但输入是虚假的(例如 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;
}       

This conversion is reminiscent of BCD — Binary Coded Decimal.

这种转换让人想起 BCD — Binary Coded Decimal

回答by chqrlie

A very simple method without error checking:

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

int bcd_to_decimal(unsigned char x) {
    return x - 6 * (x >> 4);
}

回答by kavya gupta

Put the desired value in the function and you will get an integer in return.

将所需的值放入函数中,您将得到一个整数作为回报。

#include <stdio.h>
#include <math.h>

typedef int                 INT32;

typedef short int           INT16;

typedef unsigned short int  UINT16;

typedef unsigned long int   UINT32;

UINT32 BCDToDecimal(UINT32 nDecimalValue){
    UINT32 nResult=0;
    INT32  nPartialRemainder, ncnt,anHexValueStored[8];
    UINT16 unLengthOfHexString = 0,unflag=0;

    for(ncnt=7 ;ncnt>=0 ; ncnt--){
        anHexValueStored[ncnt]=nDecimalValue & (0x0000000f << 4*(7-ncnt));
        anHexValueStored[ncnt]=anHexValueStored[ncnt] >> 4*(7-ncnt);
        if(anHexValueStored[ncnt]>9)
        unflag=1;
    }
    if(unflag==1){
        return 0;
    }
    else{
        for(ncnt=0 ;ncnt<8 ; ncnt++)
        nResult= nResult +anHexValueStored[ncnt]*pow(10,(7-ncnt));
        return nResult;
    }
}
int main() {
    printf("%ld\n",BCDToDecimal(0X20));
    return 0;
}