几种码制转换 BCD TO HEX,HEX TO BCD ,BIN TO HEX

该博客主要展示了C语言代码,包含宏定义及函数实现。定义了将十六进制转换为二进制的宏,还实现了HEX与BCD码相互转换的函数,如BCD2HEX和HEX2BCD,并在main函数中进行了调用测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include
#include
#include
#include
/*****/
#define LongToBin(n) /
(/
((n >> 21) & 0x80) | /
((n >> 18) & 0x40) | /
((n >> 15) & 0x20) | /
((n >> 12) & 0x10) | /
((n >> 9) & 0x08) | /
((n >> 6) & 0x04) | /
((n >> 3) & 0x02) | /
((n ) & 0x01) /
)

#define Bin(n) LongToBin(0x##n##l)

/********** HEX转BCD******/
/***bcd_data(<0x255,>0)***/
unsigned char BCD2HEX(unsigned int bcd_data)
{
unsigned char temp;
temp=((bcd_data>>8)*100)|((bcd_data>>4)*10)|(bcd_data&0x0f);
return temp;
}
/********** HEX转BCD******/
/***hex_data(<0xff,>0)****/
unsigned int HEX2BCD(unsigned char hex_data)
{
unsigned int bcd_data;
unsigned char temp;
temp=hex_data%100;
bcd_data=((unsigned int)hex_data)/100<<8;
bcd_data=bcd_data|temp/10<<4;
bcd_data=bcd_data|temp%10;
return bcd_data;
}

void main(void)
{
unsigned int c;

c= Bin(10101001); // then c = 0xA9
c=BCD2HEX(0x255); //255 转成HEX为0xff
c=HEX2BCD(0xff); //0xff 转成BCD码为 255
}
<think>我们编写两个函数:一个用于将16进字符串转换BCD(二进的十进),另一个用于将BCD转换为16进字符串。注意:BCD通常用4位二进表示一个十进数字(0-9)。对于16进,我们通常处理的是字节(8位)或更多。1.16进BCD:例如,16进数0x23(即十进的35)转换BCD应该是0x35(因为3的BCD是0011,5的BCD是0101,所以组合起来是00110101,即0x35)。但是,注意BCD不能直接表示超过9的单个数字,所以我们需要将16进数先转换为十进数,然后逐位转换BCD。步骤:a.将16进字符串转换为整数(十进表示)。b.将这个整数逐位分解(十进位),然后将每一位用4位二进表示,组合起来。但是,注意:如果数字的位数是奇数,我们可能需要在高位补0(或者不补,取决于BCD的存储方式,通常我们按字节对齐,所以可以补0到偶数位,但也可以不补,因为BCD是按4位一组)。2.BCD转16进:例如,BCD0x35(即00110101)分解为两个4位:0011(3)和0101(5),所以对应的十进数是35,然后转换为16进就是0x23(35的十六进)。步骤:a.将BCD(整数形式或字节形式)分解为每4位一组(注意高位可能补0)。b.将每一组4位二进转换为十进数字(0-9),然后组合成一个十进数。c.将这个十进转换为16进字符串。注意:我们假设输入的16进字符串是正常的(不含0x前缀),输出BCD时,我们以整数列表(每4位一个整数)或字节数组形式?这里我们为了简单,可以输出为整数(但整数可能很大,所以我们可以输出为十六进字符串形式的BCD表示,或者直接输出整数形式的BCD?)但是,题目要求互转程序,我们设计两个函数:-hex_to_bcd(hex_str):输入16进字符串,返回一个整数(这个整数就是BCD的整数表示)或者也可以返回BCD的十六进字符串?但注意,BCD的整数表示可能很大,而且可能以0开头,所以用整数表示可能会丢失高位的0。因此,我们可以返回一个字符串(每个字符代表4位,即一个BCD数字)或者返回一个字节数组。这里我们返回一个字符串,表示BCD的十六进形式(这样每个字符就是4位)。另一种思路:BCD通常用字节表示两个十进数字(压缩BCD)。所以我们可以这样:hex_to_bcd:将16进字符串转换为整数,然后将整数转换为字符串(即十进表示),然后将这个字符串的每一位数字转换为其4位二进表示(即0->0000,1->0001,...,9->1001),然后把这些二进拼接起来,再转换为十六进字符串(这样每4位二进就对应一个十六进字符)。注意,这样得到的十六进字符串就是BCD的表示。但是,注意:BCD没有A-F,所以每一位十六进字符都在0-9之间。例如:16进字符串"2B"(即43)->整数43 ->字符串"43" ->4的二进0100,3的二进0011 ->拼接为01000011 ->十六进字符串"43"(注意,这个十六进字符串的每个字符都是0-9,所以它实际上就是BCD的表示)。所以,我们可以这样实现:defhex_to_bcd(hex_str):num= int(hex_str,16)#将16进字符串转换为整数#将整数转换为十进字符串dec_str= str(num)#将十进字符串的每一位转换为4位二进字符串,然后拼接bcd_bin =''ford indec_str:#将每个数字转换为4位二进,去掉前面的'0b'bin_d=bin(int(d))[2:]#补齐4位bin_d =bin_d.zfill(4)bcd_bin+= bin_d#现在bcd_bin是一个二进字符串,我们可以将其转换为整数,再转换为十六进字符串,但注意这样得到的十六进字符串可能包含字母,而BCD的十六进表示只包含0-9,所以我们可以直接按每4位转换成十六进数字,但这里我们实际上已经保证了每4位是一个0-9的数字的BCD,所以整个二进字符串转换成整数后再用十六进表示,但注意这个整数对应的十六进字符串中每个字符恰好对应两个二进位(因为4位二进最大是9,所以不会出现A-F)?不对,4位二进最大是15,所以如果BCD的二进串中出现了1010(10)到1111(15)是不合法的,因为我们只用了0-9。#实际上,我们上面生成的bcd_bin的每4位都在0000到1001之间,所以当我们将其转换为整数后,再转换为十六进字符串,这个十六进字符串的每一位数字都在0-9之间,因此我们可以直接返回这个十六进字符串(它看起来和十进字符串一样,但实际上是BCD的十六进表示)。#将二进字符串转换为整数,再转换为十六进字符串,并去掉开头的'0x'bcd_hex= hex(int(bcd_bin,2))[2:]#注意:如果原始数字是0,那么dec_str是"0",那么bcd_bin是"0000",转换为整数0,再转十六进是"0",所以我们需要考虑位数对齐?但是BCD通常要求4的倍数位,所以我们可以高位补0,但这里我们生成的字符串长度已经是4的倍数了(因为每个数字用4位),所以没问题。#但是,我们也可以直接返回bcd_hex,不过要注意,它可能比原始数据长(因为一个字节的16进数可能变成两个BCD数字,即一个字节的BCD,而原来一个字节的16进数可能只需要两个BCD数字,即一个字节的BCD,所以长度是两倍?不对,比如0x2B(43)变成两个BCD数字,即一个字节(0x43),所以这里我们返回的字符串长度是原来十进字符串的长度,而原来16进字符串的长度和转换后的BCD字符串长度没有直接关系。#但是,我们返回的是BCD的十六进字符串表示,所以每个字符代表4位,即两个字符代表一个字节。所以返回的字符串长度是偶数吗?因为每个BCD数字用4位,所以字符串长度应该是4的倍数?不对,字符串长度是二进字符串除以4,所以长度是任意的。不过我们不需要特别处理。returnbcd_hex.upper()#转换为大写,保持习惯但是,上面的方法有一个问题:当输入的16进数很大时,转换为整数再转换为字符串可能会受到整数范围的限(虽然Python整数可以很大,但效率可能不高)。另外,如果输入的16进字符串表示的是负数,我们也没有处理。所以我们需要约定输入为非负整数。另一种更高效的方法:不使用字符串转换,而是用数学方法逐位处理。但这里我们按照上面的方法实现,因为简单。2. BCD转16进:defbcd_to_hex(bcd_str):#输入是一个BCD的十六进字符串(即只包含0-9的字符串)#首先,我们将这个字符串转换为二进字符串(每4位一组,因为每个字符对应4位二进bin_str= ''forcin bcd_str:#将每个字符转换为4位二进字符串#注意:这里c是0-9的字符,所以转换为整数后不会超过9n =int(c,16)#实际上就是c对应的数字bin_char= bin(n)[2:].zfill(4)bin_str +=bin_char#现在bin_str是一个二进字符串,每4位表示一个BCD数字。我们需要将这些BCD数字组合成原来的十进数。#但是注意,这个二进字符串的长度应该是4的倍数,我们按4位分组groups= [bin_str[i:i+4] fori inrange(0,len(bin_str),4)]#将每个4位二进转换为整数,然后组合成十进字符串dec_str =''for groupin groups:#将二进字符串转换为整数digit= int(group,2)if digit>9:#如果出现大于9,说明输入BCD无效raiseValueError("Invalid BCD digit: {}".format(digit))dec_str +=str(digit)#然后将这个十进字符串转换为整数,再转换为十六进字符串num =int(dec_str)hex_str= hex(num)[2:].upper()return hex_str但是,这里有一个问题:BCD的十六进字符串可能包含奇数个字符吗?例如,表示3个BCD数字(12位)需要3个十六进字符(因为每个十六进字符4位,3个字符就是12位)。但是,我们上面的转换中,输入bcd_str的每个字符对应4位,所以长度是任意的。所以分组是每4位一组,没有问题。但是,注意:BCD的存储通常以字节为单位,所以长度通常是偶数个字符(因为一个字节两个BCD数字)。但我们的函数也支持奇数个字符(即高位有一个0,比如'0'表示0000,然后下一个字符表示一个完整的BCD数字,但这样可能高位补0)。所以我们的函数是通用的。然而,上面的方法同样可能遇到大整数问题,但Python可以处理大整数。但是,我们也可以优化:在bcd_to_hex中,我们不需要先转换为二进字符串,可以直接将每个字符转换为4位二进字符串,然后拼接,再分组。但这样是可行的。另外,我们也可以直接对bcd_str的每一位进行处理:每两个字符可以组合成一个字节(即两个BCD数字),然后转换为一个十进数(十位和个位)。但是,由于可能有奇数位,所以需要单独处理。不过我们上面的方法是通用的。我们按照上面的方法编写代。但是,注意:上面的hex_to_bcd函数在输入为0时,会返回'0'(因为str(0)='0',然后转换为二进'0000',再转换为十六进'0')。而bcd_to_hex输入'0'时,会得到二进字符串'0000',然后分组为['0000'],然后转换为十进字符串'0',再转换为十六进'0'。所以是匹配的。测试:输入"2B"(十六进43)->hex_to_bcd("2B")应该返回"43"(字符串)。然后bcd_to_hex("43")应该返回"2B"(注意,我们返回的是十六进字符串,所以"2B"和"2b"我们统一转换为大写,所以返回"2B")。但是,注意:十六进字符串中,字母我们通常用大写,所以统一用大写。另外,我们也可以考虑输入有空格或0x前缀?根据需求,我们假设输入是纯16进字符串(不含0x前缀,也不含空格)。下面我们编写代,并注意处理空字符串。另外,如果输入不是有效的16进字符串(对于hex_to_bcd)或不是有效的BCD十六进字符串(即包含A-F,对于bcd_to_hex),我们可能会出错,这里我们不做额外的检查,因为题目要求互转。代实现:我们写两个函数:hex_to_bcd(hex_str:str)-> strbcd_to_hex(bcd_str: str) ->str注意:hex_to_bcd输入的hex_str可以是任意非负整数的十六进字符串,输出是BCD的十六进字符串(只包含0-9)。而bcd_to_hex输入是BCD的十六进字符串(只包含0-9),输出是原始的十六进字符串(可能包含A-F,但用大写字母)。我们按照上述逻辑编写。但是,我们也可以考虑另一种情况:当输入的十六进转换为整数后,其十进表示有奇数个数字,那么生成的BCD的二进字符串长度是4的倍数,所以转换为十六进字符串后,长度是偶数吗?不一定,因为每4位二进转换为1个十六进字符,所以总长度就是二进字符串长度除以4,所以是整数,所以没有问题。例如:十进数123,有3位,则二进字符串长度为12,转换为十六进字符串长度为3(12/4=3个十六进字符)。所以返回的字符串长度等于十进数的位数。下面我们编写代,并测试。但是,我们也可以考虑更高效的实现(避免使用大整数和字符串操作),但这里为了清晰,我们使用字符串操作。开始编写:</think>以下是16进BCD互转的Python程序实现: ```python def hex_to_bcd(hex_str): """将16进字符串转换BCD字符串""" # 将16进字符串转换为整数 num = int(hex_str, 16) # 将整数转换BCD bcd_str = "" while num: num, digit = divmod(num, 10) # 将每个十进数字转换为4位BCD bcd_digit = bin(digit)[2:].zfill(4) bcd_str = bcd_digit + bcd_str return bcd_str or "0000" # 处理0的情况 def bcd_to_hex(bcd_str): """将BCD字符串转换为16进字符串""" # 验证BCD有效性 if len(bcd_str) % 4 != 0: raise ValueError("BCD长度必须是4的倍数") # 每4位为一组处理 num = 0 for i in range(0, len(bcd_str), 4): group = bcd_str[i:i+4] digit = int(group, 2) if digit > 9: raise ValueError(f"无效BCD组: {group}") num = num * 10 + digit # 转换为16进并去除前缀 return hex(num)[2:].upper() # 测试示例 if __name__ == "__main__": # 16进BCD测试 hex_val = "1F3" # 499的十六进 bcd_result = hex_to_bcd(hex_val) print(f"16进 {hex_val} -> BCD: {bcd_result}") # 应输出010010011001 # BCD转16进测试 bcd_val = "010010011001" # 499的BCD hex_result = bcd_to_hex(bcd_val) print(f"BCD {bcd_val} -> 16进: {hex_result}") # 应输出1F3 ``` ### 程序说明: 1. **hex_to_bcd函数**: - 输入:16进字符串(如"1A3") - 处理:将16进转为整数→逐位分解十进数字→每个数字转为4位二进 - 输出:BCD字符串(如"000110100011") 2. **bcd_to_hex函数**: - 输入:BCD字符串(长度需为4的倍数) - 处理:每4位一组→转为十进数字→组合成整数→转为16进 - 输出:16进字符串(大写) 3. **特殊处理**: - 自动处理前导零(如0的BCD返回"0000") - 验证BCD有效性(每组必须在0000-1001范围内)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值