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


一文攻破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。

/**
* 任意进制转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,递归终止,不断弹出栈即可。

/**
* 十进制转任意进制 递归法
* @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');
  }
}

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

/**
* 十进制转任意进制 非递归法
* @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之间,然后高位乘以进制再加上最低位。

/**
* 任意进制转十进制
* @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()

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

C++实现

// 十进制转十六进制
stringstream ss;
ss<<hex<<de;
string s = ss.str();
cout<<s<<endl;
// 十六进制转十进制
int raw;
ss>>hex>>raw;
cout<<raw<<endl;

3.总结

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

640?wx_fmt=png



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值