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

相关推荐
LuminousCPP4 分钟前
数据结构-二叉树(三):堆复杂度证明与 Top-K 问题|错位相减推导 + 海量数据内存优化
c语言·数据结构·笔记·排序算法
qq_5896660517 小时前
C语言、C++与C#的区别详解
c语言·c++·c#
昌原的儿子LEO20 小时前
Linux进程知识点总结
linux·服务器·c语言·数据库
多弗朗皮卡丘1 天前
C语言梦开始的地方16:结构体
c语言·开发语言·windows
2401_862880821 天前
Linux应用层开发 --- 多任务
linux·服务器·c语言
心仪久了会沦陷1 天前
数据结构入门系列——顺序表详解:概念、分类与动态实现
c语言·数据结构·经验分享·笔记·开源
witton1 天前
xmake中将proto文件生成C/C++文件然后再编译链接进项目
c语言·c++·mingw·protobuf·xmake·protobuf-c·protoc-gen-c
dear_bi_MyOnly1 天前
C语言控制语句与循环逻辑精讲
c语言·开发语言·学习·分类
M78佐菲1 天前
c语言学习笔记:排序与查找方法整理
linux·c语言·笔记·学习·算法
wWYy.1 天前
C++与C的区别
c语言·c++