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

相关推荐
Escalating_xu12 小时前
【C 语言】深入理解指针(4):回调函数、qsort、void * 与泛型排序的模拟实现
java·c语言·开发语言
吠品12 小时前
GitHub 周榜拆解:决策小模型扎堆上位
c语言·开发语言·算法
小师兄吃牛肉13 小时前
C语言篇:内联函数
c语言·开发语言
白山编程大哥14 小时前
C语言篇:语法进阶
c语言·数据结构·算法
Logic10114 小时前
C语言/数据结构动态规划题解:爬楼梯(含坏台阶)——避开障碍物的路径计数
c语言·数据结构·动态规划·时间复杂度·空间复杂度·算法题·爬楼梯
山下梅子酒22515 小时前
洛谷-入门-B2081
c语言
wuminyu15 小时前
Virtual Thread重投递至ForkJoinPool任务队列过程解析
java·linux·c语言·jvm·c++
Navigator_Z16 小时前
LeetCode //C - 1281. Subtract the Product and Sum of Digits of an Integer
c语言·算法·leetcode
iCxhust16 小时前
51单片机电力载波应用开发(七)广播通讯
c语言·开发语言·单片机·嵌入式硬件·51单片机
Hi2024021716 小时前
同一个 NMS 算子,两种语言实现:CUDA C 与 Rust 生成 LLVM IR 和 Vortex 汇编的差异
c语言·汇编·rust·gpgpu·vortex·cudac