一行代码说清楚进制转换--转来转去

本文介绍如何将十六进制数值转换为BCD码,并提供了多种实现方式,包括直接操作位、宏定义和函数封装等。同时,还探讨了不同数据类型如u8和u16的处理方法。

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

一行代码如下:

int comm_bcd_to_bin(unsigned char bcd)
{
	return (bcd>>4)*10 + (bcd&0x0F);
}

可以测试下:

#include<stdio.h>

int main()
{
	char data=0x78;
	printf("%d\n",data );//120
	data=comm_bcd_to_bin(data);
	printf("%d\n",data );//78
}    

思路就是:暴力把数据分成两部分,一部分是高4位 A,一部分是低4位 B。

此后的事情就是 :

你要16进制的 我就给你A*16 +B   此时数据依旧客观正确

你要10进制的 我就给你A*10 +B   此时数据变化了0X78其实是120,数据转换后变成78

用以前的风格写一下:(不要在意函数的名字)

#include<stdio.h>

#define GetHBits(val_8)     ((val_8>>4)&0x0F)
#define GetLBits(val_8)     (val_8     &0x0F)

#define HEX2BCD(HEX)        ( GetHBits(HEX)*10 + GetLBits(HEX) )

int main()
{
	short data=0x12;
	printf("%d\n",data );//18
	printf("%d\n",HEX2BCD(data) );//12
} 

现在就是十六进制的0X12变成十进制的12,如果你希望十六进制变十六进制就定义为:

 #define HEX2BCD(HEX)        ( GetHBits(HEX)*16 + GetLBits(HEX) )

 

再看看u16的 :----其实完全没有意义了 u8才是绝配的0X12这样的数据就是u8的8个位置4个一捏4个一捏的。

#include<stdio.h>

#define GetHBits(val_8)     ((val_8>>8)&0xFF)
#define GetLBits(val_8)     (val_8     &0xFF)

#define HEX2BCD(HEX)        ( GetHBits(HEX)*16*16 + GetLBits(HEX) )

int main()
{
	short data=0x1234;
	printf("%d\n",data );//4660
	printf("%d\n",HEX2BCD(data) );//4660
}    
   

 

1此时十六进制转十六进制。用法上是没有意义的,我们是希望十进制转化成十六进制才有意义。

2#define HEX2BCD(HEX)     (GetHBits(HEX)<<8 | GetLBits(HEX))  可以!

3#define HEX2BCD(HEX)     (GetHBits(HEX)*10*10 | GetLBits(HEX))  不可以!

 

再看一个u8的二分的例子,按键开门,点击确认#以后的函数:

《充电桩用的记录密码的是arr[6]其实用arr[3]就可以了 因为你都是1 2 3 4 5 6 7 8 9 0呀所以你是0X01 0X02这样你可以挤一挤》

uint8_t *userPwd , *pairPwd;
uint8_t pwd[3];//6位的密码 用arr[3]即可
     
log(DEBUG,"校验固定密码\n");

pwd[0] = touchKey.buffer[0]<<4|touchKey.buffer[1];
pwd[1] = touchKey.buffer[2]<<4|touchKey.buffer[3];
pwd[2] = touchKey.buffer[4]<<4|touchKey.buffer[5];
config.read(CFG_PAIR_PWD , (void **)&pairPwd );
config.read(CFG_USER_PWD , (void **)&userPwd );

if((aiot_strcmp(pwd , pairPwd , 3) == TRUE )||(aiot_strcmp(pwd , userPwd , 3) == TRUE ))
{
   open_door();
..




/* 
 *  设备默认配对密码
 */
-DDEFAULT_PAIR_PWD="{0X12,0x34,0x56}"


/* 
 *  设备默认开门密码
 */
-DDEFAULT_OPEN_PWD="{0X12,0x34,0x56}"

 

 

 

模块函数



//压缩一半

//方法1
//完成'4'-->4  ‘A’-->10
//传入参数不是ASCII的 就返回-1
unsigned char ASCII2INT(unsigned char dData)
{
	unsigned char rst=0;
	if((dData >= '0')&& (dData <= '9'))
				rst = dData-'0';
	else if((dData >= 'A')&&(dData <= 'F'))
				rst =  dData+10-'A';
	else if((dData >= 'a')&&(dData <= 'f'))
				rst =  dData+10-'a';
	else rst = -1;
			
	return rst;
}


//完成"10"--->0x10  "1234"--->0X12,0X34 
//len标识传入的strlen(strings)
//返回值是len的一半
char G_strsTobytes(void* Strings,void* Bytes,char len)
{
	unsigned char* strings=(unsigned char *)Strings;
	unsigned char* bytes  =(unsigned char *)Bytes;
	unsigned char i = 0,j=0,lowbits=0,highbits=0;
	if(len%2)return 0;//禁止奇数
	for (i = 0; i < len; i+=2)
	{           
		highbits = ASCII2INT(strings[i]  );
		lowbits  = ASCII2INT(strings[i+1]);
		bytes[j++] =( highbits << 4)|lowbits;//可以自己切换十进制 十六进制
	}
	return j;
}




//方法2
//完成"10"--->0x10  "1234"--->0X12,0X34 
//功能和上面一样 这个是机智云源码
void G_strsTohexs(char *pbSrc,char *pbDest,int32_t nLen)
{
    char h1,h2;
    char s1,s2;
    int32_t i;

    for (i=0; i<nLen; i++)
    {
        h1 = pbSrc[2*i];
        h2 = pbSrc[2*i+1];

        s1 = toupper(h1) - 0x30;//技巧1 直接减去0X30也就是减去‘0’
        if (s1 > 9)             //技巧2 toupper直接把char变成大写 也就避免了小写的case 
            s1 -= 7;            //技巧3 如果是ABC字符的话在-0x30的基础上再-7 7怎么来的?ASCII表A--65 9--57

        s2 = toupper(h2) - 0x30;
        if (s2 > 9)
            s2 -= 7;

        pbDest[i] = s1*16 + s2;//不如前面的思路写为s1<<4 | s2 //可以自己切换十进制 十六进制
    }
}


//方法3
//"1234"--->0X12,0X34 
void BAIDUhex_to_decimal(const char *hex_string, unsigned char *arr, size_t arr_len)
{
    const char *pos = hex_string;
    int count;

    for (count = 0; count < arr_len; count++) {
        sscanf(pos, "%2hhx", &arr[count]);//可以自己切换十进制 十六进制
        pos += 2;
    }
}





//0XAB-->"AB" 0XABCD-->"ABCD"  长度会扩大一倍!注意:没有结束符\0
void G_1byteTo2str(unsigned char* strings,unsigned char* bytes,unsigned char len)
{
    unsigned char const StrRefer[]="0123456789abcdef";//"0123456789ABCDEF";
    #define GET_MSB_STR(x) (StrRefer[((x>>4)&0x0f)])
    #define GET_LSB_STR(x) (StrRefer[(x&0x0f)])
    for(char i=0,j=0;i<len;i++,j+=2)
    {
        strings[j]  =GET_MSB_STR(bytes[i]);
        strings[j+1]=GET_LSB_STR(bytes[i]);
    }

}

//方法2是机智云版本:
//最后出来的Str的长度是进去的hex的2倍+1 注意:有结束符\0
void  G_hex2Str(unsigned char *pbDest, unsigned char *pbSrc, int32_t nLen)
{
    char    ddl,ddh;
    int32_t i;

    for (i=0; i<nLen; i++) 
	{
        ddh = 0x30 + pbSrc[i] / 16;
        ddl = 0x30 + pbSrc[i] % 16;
        if (ddh > 0x39) ddh = ddh + 7;
        if (ddl > 0x39) ddl = ddl + 7;
        pbDest[i*2]   = ddh;
        pbDest[i*2+1] = ddl;
    }

    pbDest[nLen*2] = '\0';
}




//0XABCD1234-->AB CD 12 34 保证正确!优快云
void u32toArr4(uint32_t U,uint8_t *Arr)
{
	Arr[0] = (U&0XFF000000)>>24;
	Arr[1] = (U&0X00FF0000)>>16;
	Arr[2] = (U&0X0000FF00)>>8;
	Arr[3] = (U&0X000000FF)>>0; 
}






/**
 * htons unsigned short -> Network byte order
 * ntohs Network byte order -> unsigned short
 */
 //0XABCD-->0XCDAB 优快云
//为什么需要这个?你看0906 ble_Analysis_Rxdata 过来【0X00】【0X1B】
//如果直接读的话你是拿到了0X1B00 因为我们STM32的读是XX字节序 和读内存一样
//所以要反一下
uint16_t  exchangeBytes(uint16_t value)
{

    uint16_t tmp_value = 0;
    uint8_t *index_1, *index_2;

    index_1 = (uint8_t *)&tmp_value;
    index_2 = (uint8_t *)&value;

    *index_1     = *(index_2+1);
    *(index_1+1) = *index_2;

    return tmp_value;

}

 //0XABCD1234-->0X3412CDAB 优快云
uint32_t exchangeWord(uint32_t value)
{
	uint32_t tmp_value = 0;
    uint8_t *index_1, *index_2;

    index_1 = (uint8_t *)&tmp_value;
    index_2 = (uint8_t *)&value;

    *(index_1+0) = *(index_2+3);
    *(index_1+1) = *(index_2+2);
    *(index_1+2) = *(index_2+1);
    *(index_1+3) = *(index_2+0);
    return tmp_value;

}

 

&lt;think&gt;首先,用户要求用中文回答问题。用户的问题是:&ldquo;写一个将16进制转换为2进制的代码&rdquo;。所以,我需要提供一个代码,将十六进制转换为二进制。 关键点是:回答完问题后,必须提出3-5个相关问题。这些问题必须以&ldquo;&sect;&sect;相关问题&sect;&sect;&rdquo;开头,并且不能换行分散。也就是,第一行必须是完整的&ldquo;&sect;&sect;相关问题&sect;&sect;&rdquo;,然后列出问题,每个问题用数字点号如&ldquo;1. &middot;&middot;&middot;&rdquo;表示。 示例格式显示,回答包括代码(用代码块表示),然后相关问题。 所以,我的回答结构应该是: 1. 提供将十六进制转换为二进制的代码。 2. 在代码之后,立即输出&ldquo;&sect;&sect;相关问题&sect;&sect;&rdquo;。 3. 然后列出3-5个相关问题。 现在,关于代码:我需要写一个函数或代码片段,将十六进制字符串转换为二进制字符串。在Python中,这很简单,因为Python有内置函数来处理进制转换。 例如: - 使用`int(hex_string, 16)`将十六进制字符串转换为整数。 - 然后使用`bin(int_value)`将整数转换为二进制字符串。`bin()`函数返回一个以&quot;0b&quot;开头的字符串,所以我需要去除前缀。 代码示例: ```python def hex_to_bin(hex_str): # 将十六进制字符串转换为整数 num = int(hex_str, 16) # 将整数转换为二进制字符串,并去除&#39;0b&#39;前缀 bin_str = bin(num)[2:] return bin_str ``` 或者,更简洁地写为: ```python def hex_to_bin(hex_str): return bin(int(hex_str, 16))[2:] ``` 我应该确保代码完整且可运行。用户可能期望一个完整的函数。 现在,回答需要用中文,所以我应该用中文解释代码或提供注释。 但用户没有要求解释,只要求写代码。所以,我可以直接提供代码块,然后相关问题。 在回答中,我需要确保所有内容符合规则。回答完问题后提出相关问题。 相关问题必须基于用户的问题和我的回答。用户的问题是写一个十六进制转二进制的代码。 所以,相关问题可以围绕进制转换代码优化、其他进制转换等。 例如: 1. 如何处理无效的十六进制输入? 2. 如何将这个代码扩展到其他进制转换? 3. 二进制输出是否需要补零到一定长度? 4. 在Python中,是否有其他方法实现这个转换? 5. 这个代码的时间复杂度是多少? 我需要3-5个相关问题。 最后,输出时,第一行必须是&ldquo;&sect;&sect;相关问题&sect;&sect;&rdquo;,然后列出问题。 完整回答结构: - 先提供代码(用代码块)。 - 然后输出&ldquo;&sect;&sect;相关问题&sect;&sect;&rdquo;。 - 然后列出问题,如&ldquo;1. ...\n2. ...\n3. ...&rdquo; 确保没有换行分散,意思是相关问题部分要紧凑。 现在,写代码: 我将写一个Python函数。 ```python def hex_to_binary(hex_str): # 将十六进制字符串转换为整数 num = int(hex_str, 16) # 将整数转换为二进制字符串并去掉前缀 binary_str = bin(num)[2:] return binary_str ``` 为了更健壮,我可以添加输入验证,但用户没有指定,所以简单点。 现在,相关问题: 1. 如果输入的十六进制字符串包含非十六进制字符,代码会如何处理? 2. 如何修改代码以使二进制输出固定长度(例如,补零)? 3. 能否写一个通用的函数,将任意进制转换为二进制? 4. 在Python中,除了使用int和bin,还有其他方法进行进制转换吗? 5. 这个转换过程在计算机科学中有哪些应用? 我需要确保有3-5个。 列出: 1. 如何处理无效的十六进制输入? 2. 如何使二进制输出对齐到字节边界(例如,补零到8的倍数)? 3. 如何将二进制转换回十六进制? 4. 这个转换算法的时间复杂度是多少? 5. 在其他编程语言中,如何实现类似的转换? 选择3-5个。我选4个吧。 最终回答: - 代码- &quot;&sect;&sect;相关问题&sect;&sect;&quot; - 1. ... 2. ... 3. ... 4. ... 用中文写相关问题,因为用户要求用中文回答问题。 用户&ldquo;请使用中文回答问题&rdquo;,所以整个回答应该用中文。 所以: - 代码注释可以用英文或中文,但为了统一,我可以用中文注释。 - 相关问题用中文。 代码注释: ```python def hex_to_binary(hex_str): # 将十六进制字符串转换为整数 num = int(hex_str, 16) # 将整数转换为二进制字符串并去掉&#39;0b&#39;前缀 binary_str = bin(num)[2:] return binary_str ``` 相关问题: 1. 如果输入的十六进制字符串无效(如包含非十六进制字符),代码会报错吗?如何处理? 2. 如何修改代码使二进制输出固定长度,例如补零到8位? 3. 能否扩展这个函数以支持任意进制到二进制的转换? 4. 在Python中,除了使用int()和bin(),还有其他方法将十六进制转换为二进制吗? 好的。&lt;/think&gt;以下是一个将十六进制转换为二进制的Python代码。该代码使用内置函数`int()`和`bin()`实现转换,并去除二进制字符串的前缀&quot;0b&quot;: ```python def hex_to_binary(hex_str): # 将十六进制字符串转换为整数 num = int(hex_str, 16) # 将整数转换为二进制字符串并去掉&#39;0b&#39;前缀 binary_str = bin(num)[2:] return binary_str # 示例用法 hex_input = &quot;1A&quot; # 十六进制输入 binary_output = hex_to_binary(hex_input) print(f&quot;十六进制 &#39;{hex_input}&#39; 的二进制表示为: {binary_output}&quot;) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值