用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];,上述代码就不用做任何位运算了。

相关推荐
我叫洋洋1 小时前
[Proteus 和 stm32f103c8t6]的使用控制OLED篇]
c语言·stm32·单片机·嵌入式硬件·蓝桥杯·proteus
Book思议-2 小时前
【数据结构】栈与队列全方位对比 + C 语言完整实现
c语言·数据结构·算法··队列
IT方大同5 小时前
(实时操作系统)线程管理
c语言·开发语言·嵌入式硬件
老约家的可汗6 小时前
list 容器详解:基本介绍与常见使用
c语言·数据结构·c++·list
爱编码的小八嘎7 小时前
C语言完美演绎6-10
c语言
3壹8 小时前
STM32按键检测与上拉电阻详解
c语言·stm32·嵌入式硬件
AI+程序员在路上8 小时前
新手进入嵌入式行业方法与方向选择
c语言·开发语言·单片机·嵌入式硬件
always_TT8 小时前
栈内存 vs 堆内存:区别与使用场景
c语言
水饺编程9 小时前
第4章,[标签 Win32] :SysMets3 程序讲解01
c语言·c++·windows·visual studio
Lenyiin9 小时前
深度剖析 C 语言标准IO库:stdio 实现原理与实战指南
c语言·开发语言