软件知识储备04_C语言实现十六进制转BCD码

在实际应用中需要转换超过255的十六进制数转换为BCD码,如0x123456,但是我找了半天没找到解决问题的方式,找到了也有很多问题,所以自己在理解这些代码后自己写一个。
先来一个我之前找到的一个版本,这个版本的问题在于,超过99后,转换的BCD码就乱了,出现0->99->0->99->0->55->100->199->100->199->100->155->200…以此类推的这样的循环。后面看代码发现这个限制,0<hex_data<255,离谱,离了个大谱就。说明:下面这段代码是CSDN上找到最多的,但是,但是这段代码它转换超过0x63的数据后向前进的那一位就给省略了,这段代码有问题的是。

/*十六进制转换为bcd码
功能:将十六进制转换为bcd码
说明:转换的十六进制数的范围: 0<hex_data<0xff
*/
uint32_t hex2bcd(unsigned char hex_data)
{
	unsigned int bcd_data;
	unsigned char temp;
	temp = hex_data % 100;
	bcd_data = ((unsigned int)hex_data) / 100 << 8;
	bcd_data = bcd_data | ((temp / 10) << 4);
	bcd_data = bcd_data | (temp % 10);
	return bcd_data;
}

然后我就自己写了第一个版本,支持四个字节的BCD码显示,能转换的十六进制数据范围为:0~ 0x99999999,对应十进制数范围为0~2576980377,返回值为32位的BCD码。代码如下:

/*十六进制转换为BCD码
功能:将十六进制转换为BCD码
传入参数:unsigned char类型的数组,数组最大只能有4个字节
说明:可转换的十进制数范围为:0~2576980377,即BCD码的99 99 99 99;
因为我这里使用的是四个字节表示BCD码,数据再大就需要再增加BCD码字节数了
因为定义的unsigned int类型的取值范围为:0~4294967295,理论上应该也是能达到这么大的,如果BCD码有5个字节显示的话
*/
uint32_t HEX2BCD(unsigned char *HEX_Table)
{
		unsigned int temp_data,bcd_data;
		unsigned char temp,temp1;
		temp_data = (HEX_Table[0] << 24) | (HEX_Table[1] << 16)	//这里将四个字节的十六进制数组合为一个32位的数,方便接下来的处理
					| (HEX_Table[2] << 8) | HEX_Table[3];

		temp = temp_data / 1000000;
		temp1 = temp % 100;
		bcd_data = ((unsigned int)temp) / 100 << 28;		//这个值再向前进位无意义,但是这里左移32位会提示警告,所以左移28位消除警告,接下来会被下面的数替代
		bcd_data = bcd_data | ((temp1 / 10) << 28);			//这里
		bcd_data = bcd_data | (temp1 % 10)<<24;
		BCD_Table[0] = bcd_data >> 24;

		temp = (temp_data % 1000000) / 10000;
		temp1 = temp % 100;
		bcd_data = bcd_data | ((unsigned int)temp) / 100 << 24;
		bcd_data = bcd_data | ((temp1 / 10) << 20);
		bcd_data = bcd_data | (temp1 % 10) << 16;

		temp = (temp_data % 10000) / 100;
		temp1 = temp % 100;
		bcd_data = bcd_data | ((unsigned int)temp) / 100 << 16;
		bcd_data = bcd_data | ((temp1 / 10) << 12);
		bcd_data = bcd_data | (temp1 % 10) << 8;

		temp = temp_data % 100;
		temp1 = temp % 100;
		bcd_data = bcd_data | ((unsigned int)temp) / 100 << 8;
		bcd_data = bcd_data | ((temp1 / 10) << 4);
		bcd_data = bcd_data | (temp1 % 10);
		return bcd_data;
}

这段代码经过测试BCD码是正常一次递增的。
在这里插入图片描述
至此,如果是在嵌入式开发中使用,这个数据长度是够用的了。然后我在想在完善下写个支持范围更宽的版本。

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mi_Story

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值