前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文攻破BCD码转换与各进制转换

一文攻破BCD码转换与各进制转换

作者头像
公众号guangcity
发布2019-09-20 17:38:10
3.8K0
发布2019-09-20 17:38:10
举报
文章被收录于专栏:光城(guangcity)光城(guangcity)

一文攻破BCD码转换与各进制转换

0.导语

最近做的项目中时刻看到时间戳用BCD[xx]来定义,那么针对这种定义,究竟代表什么意思,如何来使用呢,本节来阐述BCD码与其他进制转换以及在笔试当中,会碰到进制转换问题,放在C/C++中,又究竟如何操作,本文来逐个攻破!

1.BCD码

BCD码(Binary-Coded Decimal‎)亦称二进码十进数或二-十进制代码。

用4位二进制数来表示1位十进制数中的0~9这10个数码。

是一种二进制的数字编码形式,用二进制编码的十进制代码。

BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。

这种编码技巧最常用于会计系统的设计里,因为会计制度经常需要对很长的数字串作准确的计算。相对于一般的浮点式记数法,采用BCD码,既可保存数值的精确度,又可免去使电脑作浮点运算时所耗费的时间。

此外,对于其他需要高精确度的计算,BCD编码亦很常用。

BCD码的运算规则:BCD码是十进制数,而运算器对数据做加减运算时,都是按二进制运算规则进行处理的。这样,当将 BCD码传送给运算器进行运算时,其结果需要修正。

修正的规则:当两个BCD码相加,如果和等于或小于 1001(即十进制数9),不需要修正;如果相加之和在 1010 到1111(即十六进制数 0AH~0FH)之间,则需加 6 进行修正;如果相加时,本位产生了进位,也需加 6 进行修正。

这样做的原因是,机器按二进制相加,所以 4 位二进制数相加时,是按“逢十六进一”的原则进行运算的,而实质上是 2 个十进制数相加,应该按“逢十进一”的原则相加,16 与10相差 6,所以当和超过 9或有进位时,都要加 6 进行修正。

上述学习自:https://blog.csdn.net/morixinguan/article/details/50682650

BCD码与任意进制数的转换实现如下:

举个例子:比如0x2A----->二进制表示为:0010 1010 -> BCD 二进制码 0100 0010 对应的十进制为66 十六进制42 字符为B。

代码语言:javascript
复制
/**
 * 任意进制转BCD
 * @param src
 * @return
 */
unsigned char BcdFromHex(const BYTE &src) {
  unsigned char temp;

  temp = ((src / 10) << 4) + (src % 10);

  return temp;
}
/**
 * BCD转任意进制
 * @param src
 * @return
 */
unsigned char HexFromBcd(const BYTE &src) {
  unsigned char temp;

  temp = (src >> 4)*10 + (src & 0x0f);
  return temp;
}

2.进制之间转换

十六进制是逢16进1,八进制是逢8进1,其他进制依次类推,就不多阐述。

2.1 十进制转任意进制

思路两个,分为递归与非递归实现。

递归实现:假设十进制转n进制,那么就让十进制数不断除以n,最终余数为0,递归终止,不断弹出栈即可。

代码语言:javascript
复制
/**
 * 十进制转任意进制 递归法
 * @param vec
 * @param m
 * @param b
 */
void DecConvertOther(vector<char> &vec, int m, int b) {
    // 余数为0 递归结束,开始返回栈
    if(!m)
        return;
    int yushu;
    DecConvertOther(vec, m / b, b);
    yushu = m % b;
    if (yushu < 10) {
        //小于10直接输出
        vec.push_back(yushu + '0');
    }
    else {
        //大于10转换成字符输出
        vec.push_back(yushu+55+'0');
    }
}

非递归实现:每次得到的余数插入头部即可。

代码语言:javascript
复制
/**
 * 十进制转任意进制 非递归法
 * @param vec
 * @param m
 * @param b
 */
void DecConvertOther1(vector<char> &vec, int m, int b) {
    int yushu=0;
    do {
       yushu=m%b;
       vec.insert(vec.begin(),yushu+'0');
       m = m/b;
    }while (m!=0);
}

2.2 任意进制转十进制

只需要判断任意进制的高位是否是数字,是否在A-F或a-f之间,然后高位乘以进制再加上最低位。

代码语言:javascript
复制
/**
 * 任意进制转十进制
 * @param a
 * @param b
 * @return
 */
int OtherConvertDec(char a[], int b) {
    int len, i, num;
    int sum = 0;
    len = strlen(a);                    //求得字符串长度
    for (i = 0; i < len; i++) {
        if (a[i] >= '0' && a[i] <= '9')
            num = a[i] - '0';
        else if (a[i] >= 'A' && a[i] <= 'F')
            num = a[i] - 'A' + 10;
        else if (a[i] >= 'a' && a[i] <= 'f')
            num = a[i] - 'a' + 10;
        sum = sum * b + num;
    }
    return sum;
}

2.3 C/C++进制转换

在C/C++中没有像Python中的int(),hex()这样的函数,可以将十进制转换为十六进制,但是有另外一些函数可以完成此类工作。

C实现

使用C语言来完成这个任务,将十进制数转换为十六进制数时使用sprinf(),而将十六进制数转换为十进制数时使用strtol()

代码语言:javascript
复制
int de=19;
char ch[10];
// 方法1
// 十进制转十六进制
sprintf(ch,"%X",de);
cout<<ch<<endl;
// 十六进制转十进制
de=strtol(ch,NULL,16);
cout<<de<<endl;

C++实现

代码语言:javascript
复制
// 十进制转十六进制
stringstream ss;
ss<<hex<<de;
string s = ss.str();
cout<<s<<endl;
// 十六进制转十进制
int raw;
ss>>hex>>raw;
cout<<raw<<endl;

3.总结

本节学习了BCD码与其他进制的转化以及十进制转其他进制、其他进制转十进制实现等,在项目开发中BCD码使用非常广,后面来仔细说明,欢迎订阅公众号光城。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 光城 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一文攻破BCD码转换与各进制转换
    • 0.导语
      • 1.BCD码
        • 2.进制之间转换
          • 2.1 十进制转任意进制
          • 2.2 任意进制转十进制
          • 2.3 C/C++进制转换
        • 3.总结
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档