C语言-BCD码转换为十进制的测试和说明

一、BCD码转换为十进制

BCD码转换为十进制,以 BCD码(0x1234)为例。

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

// 方法1: 通用循环法(适配任意长度 BCD 码),将BCD码直接解析为十进制数
unsigned int bcd_to_decimal_direct(unsigned int bcd) 
{
    unsigned int decimal = 0;
    unsigned int multiplier = 1;
    
    while (bcd > 0) 
	{
        decimal += (bcd & 0xF) * multiplier;
        bcd >>= 4;  // 右移4位,处理下一个BCD数字
        multiplier *= 10;
    }
    return decimal;
    //或者
    /*
    unsigned int decimal = 0;
    int position = 0;
    
    while (bcd > 0) 
	{
        unsigned int digit = bcd % 16;  // 取十六进制的最后一位
        unsigned int power = 1;
        
        // 计算10的position次方
        for (int i = 0; i < position; i++) 
		{
            power *= 10;
        }
        
        decimal += digit * power;
        bcd /= 16;  // 去掉已处理的最后一位
        position++;
    }
    
    return decimal;
		*/
    
    
}

// 方法2: 数学运算提取法:纯除法/取模,无位运算
unsigned int bcd_to_decimal_math(unsigned int bcd) 
{
    // 按十六进制位拆分(0x1234 = 1*0x1000 + 2*0x100 + 3*0x10 +4)
    unsigned char d1 = (bcd / 0x1000) % 0x10; // 千位:0x1234/0x1000=1 → %0x10=1
    unsigned char d2 = (bcd / 0x100) % 0x10;  // 百位:0x1234/0x100=18 → %0x10=2
    unsigned char d3 = (bcd / 0x10) % 0x10;   // 十位:0x1234/0x10=291 → %0x10=3
    unsigned char d4 = bcd % 0x10;            // 个位:0x1234%0x10=4
    return d1 * 1000 + d2 * 100 + d3 * 10 + d4;
}

// 方法3: 查表法(空间换时间)
// 查表法:预定义BCD位→十进制映射表(仅0-9有效,10-15置0,避免无效BCD值)
const unsigned char bcd_table[16] = {0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0};
unsigned int bcd_to_decimal_formatted(unsigned int bcd) 
{
    // 拆分BCD段并查表
    unsigned char d1 = bcd_table[(bcd >> 12) & 0x0F];
    unsigned char  d2 = bcd_table[(bcd >> 8)  & 0x0F];
    unsigned char d3 = bcd_table[(bcd >> 4)  & 0x0F];
    unsigned char d4 = bcd_table[bcd & 0x0F];
    // 位权计算
    return d1 * 1000 + d2 * 100 + d3 * 10 + d4;
}

// 方法4: 简洁的方法,适合固定4位BCD码
unsigned int bcd_to_decimal_simple(unsigned int bcd) 
{
    return ( ((bcd >> 12) & 0xF) * 1000 +  // 千位
           	 ((bcd >> 8) & 0xF) * 100 +    // 百位
             ((bcd >> 4) & 0xF) * 10 +     // 十位
             (bcd & 0xF) );                  // 个位
}

int main(void) 
{
    unsigned int bcd_value = 0x1234;  // BCD码: 0x1234
    
    printf("BCD码 (十六进制): 0x%X\n", bcd_value);
    printf("方法1 (直接解析): %u\n", bcd_to_decimal_direct(bcd_value));
    printf("方法2 (数学方法): %u\n", bcd_to_decimal_math(bcd_value));
    printf("方法3 (格式转换): %u\n", bcd_to_decimal_formatted(bcd_value));
    printf("方法4 (简洁方法): %u\n", bcd_to_decimal_simple(bcd_value));
    
    // 验证结果
    printf("\n验证:\n");
    printf("BCD码 0x1234 的各位数字:\n");
    printf("  千位: %u\n", (bcd_value >> 12) & 0xF);
    printf("  百位: %u\n", (bcd_value >> 8) & 0xF);
    printf("  十位: %u\n", (bcd_value >> 4) & 0xF);
    printf("  个位: %u\n", bcd_value & 0xF);
    printf("转换为十进制: %u千 + %u百 + %u十 + %u = %u\n",
           (bcd_value >> 12) & 0xF,
           (bcd_value >> 8) & 0xF,
           (bcd_value >> 4) & 0xF,
           bcd_value & 0xF,
           bcd_to_decimal_simple(bcd_value));
    
    // 示例
    printf("\n更多BCD码转换示例:\n");
    unsigned int test_cases[] = {0x0, 0x9, 0x10, 0x99, 0x100, 0x999, 0x9999};
    int num_cases = sizeof(test_cases) / sizeof(test_cases[0]);
    
    for (int i = 0; i < num_cases; i++) 
	{
        printf("BCD: 0x%04X -> 十进制: %u\n", 
               test_cases[i], 
               bcd_to_decimal_simple(test_cases[i]));
    }
    
    return 0;
}

二、说明

  1. BCD码原理

    • BCD码使用4位二进制表示一个十进制数字
    • 0x1234 表示:1(千位) 2(百位) 3(十位) 4(个位)
    • 直接计算:1×1000 + 2×100 + 3×10 + 4 = 1234
  2. 四种转换方法

    • 方法1:通过移位和掩码逐个提取BCD数字
    • 方法2:数学运算提取法:纯除法/取模,无位运算
    • 方法3:查表法(空间换时间)
    • 方法4:简洁的固定4位BCD码转换(推荐用于4位BCD码)
  3. 关键操作

    • (bcd_value >> 12) & 0xF:获取千位数字
    • (bcd_value >> 8) & 0xF:获取百位数字
    • (bcd_value >> 4) & 0xF:获取十位数字
    • bcd_value & 0xF:获取个位数字

三、 测试结果

复制代码
BCD码 (十六进制): 0x1234
方法1 (直接解析): 1234
方法2 (数学方法): 1234
方法3 (格式转换): 1234
方法4 (简洁方法): 1234

验证:
BCD码 0x1234 的各位数字:
  千位: 1
  百位: 2
  十位: 3
  个位: 4
转换为十进制: 1千 + 2百 + 3十 + 4 = 1234

更多BCD码转换示例:
BCD: 0x0000 -> 十进制: 0
BCD: 0x0009 -> 十进制: 9
BCD: 0x0010 -> 十进制: 10
BCD: 0x0099 -> 十进制: 99
BCD: 0x0100 -> 十进制: 100
BCD: 0x0999 -> 十进制: 999
BCD: 0x9999 -> 十进制: 9999

处理固定长度的BCD码,方法4是最直接和高效的。对于变长BCD码,可以使用方法1进行通用转换。

相关推荐
喵了meme14 小时前
C语言实战4
c语言·开发语言
智者知已应修善业15 小时前
【求中位数】2024-1-23
c语言·c++·经验分享·笔记·算法
程序员zgh18 小时前
Linux系统常用命令集合
linux·运维·服务器·c语言·开发语言·c++
Bigan(安)19 小时前
【奶茶Beta专项】【LVGL9.4源码分析】09-core-obj_class对象类系统
linux·c语言·mcu·arm·unix
程序员zgh19 小时前
常用通信协议介绍(CAN、RS232、RS485、IIC、SPI、TCP/IP)
c语言·网络·c++
Bigan(安)20 小时前
【奶茶Beta专项】【LVGL9.4源码分析】08-theme主题管理
linux·c语言·mcu·arm·unix
了一梨20 小时前
外设与接口:按键输入 (libgpiod)
linux·c语言
昔时扬尘处21 小时前
【Files Content Replace】文件夹文件内容批量替换自动化测试脚本
c语言·python·pytest·adi
芯联智造1 天前
【stm32简单外设篇】- 28BYJ-48 步进电机(配 ULN2003 驱动板)
c语言·stm32·单片机·嵌入式硬件