用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 小时前
66_C语言与微控制器底层开发
linux·c语言·网络·数据结构·算法·机器人·个人开发
HABuo1 小时前
【linux网络基础(二)】理解端口号&UDP、TCP协议&网络字节序
linux·服务器·c语言·网络·c++·ubuntu·centos
qeen873 小时前
【算法笔记】二分查找与二分答案
c语言·c++·笔记·学习·算法·二分
SDAU20053 小时前
Arduino编程CH552
c语言·开发语言·单片机
明飞19874 小时前
C输出打印格式占位符
c语言
Rabitebla4 小时前
【数据结构】实现通讯录:基于C语言动态顺序表
c语言·开发语言·数据结构·算法
hhb_6184 小时前
C Shell脚本编程与系统管理技术实践指南
java·c语言·开发语言
棋子入局4 小时前
C语言制作消消乐游戏(3)
c语言·开发语言·游戏
.千余5 小时前
【Linux】开发工具1
linux·运维·服务器·c语言·学习
nianniannnn5 小时前
HNU计算机系统期中题库详解(四)C语言与程序运行(数据类型、指针、内存、编译链接)
c语言·计算机系统