用C语言把BCD编码的数字转换成普通16进制

背景

之前跟FPGA同事讨论版本号的编码时,为了方便在16进制下查看,决定选择BCD编码,效果大概这样:

0x25121801

25表示25年,12表示12月,18表示18号,01表示当日的第一版,很方便,但是上位机对版本号的要求是像IP地址那样的编码,所以上面的那串BCD数字就要转换成

0x190c1201

19表示十六进制的25年,0c表示十六进制的12月,12表示十六进制的18号,01表示十六进制的当日第一版

思路

BCD是用4bit编码一个十进制数位,而IP地址其实就是用8bit编码一个字段,既然2个BCD数位对应一个版本号的字段,因此可以简单的2:1转换:

为了避免移位运算,考虑用联合体来实现既能直接操作每个8bit,又能将转换结果按32bit整型返回的效果,而且还不用管CPU到底是大端还是小端。

C语言代码

c 复制代码
#include <stdio.h>
#include <stdint.h>

union bcd {
    uint8_t field[4];
    uint32_t reg;
};

uint32_t bcd_to_hex(uint32_t reg)
{
    union bcd d;

    d.reg = reg;
    for (int i = 0; i < 4; i++) {
        d.field[i] = (d.field[i] >> 4) * 10 + (d.field[i] & 0xf);
    }
    return d.reg;
}

int main()
{
    uint32_t reg = 0x25121801;

    printf("ori 0x%08x\n", reg);
    printf("convert 0x%08x\n", bcd_to_hex(reg));
    return 0;
}

运行效果:

复制代码
ori 0x25121801
convert 0x190c1201

后记

可惜C语言没有内置niche类型,否则联合体里再定义个niche_t sub_feild[8];,上述代码就不用做任何位运算了。

相关推荐
楼田莉子2 小时前
Linux学习之磁盘与Ext系列文件
linux·运维·服务器·c语言·学习
StandbyTime2 小时前
C语言学习-菜鸟教程C经典100例-练习27
c语言
青小莫4 小时前
C语言vsC++中的动态内存管理(内含底层实现讲解!)
java·c语言·c++
一路往蓝-Anbo8 小时前
【第42期】调试进阶(一):IDE中的Register与Memory窗口
c语言·开发语言·ide·stm32·单片机·嵌入式硬件
sycmancia10 小时前
C语言学习05——字符数组与字符串
c语言
智码未来学堂10 小时前
C语言指针:打开通往内存世界的大门
c语言·开发语言
黎雁·泠崖10 小时前
Java分支循环与数组核心知识总结篇
java·c语言·开发语言
@good_good_study11 小时前
STM32 C语言链表
c语言·stm32·链表
卷毛迷你猪11 小时前
小肥柴慢慢手写数据结构(C篇)(2.1.1 动态数组(ArrayList))
c语言·数据结构
StandbyTime11 小时前
C语言学习-菜鸟教程C经典100例-练习28
c语言