C语言实现双精度十六进制浮点数和long类型之间的转换

本文介绍了在处理RTMP包时遇到的双精度十六进制转换问题,作者提供了从16进制字符串转long类型以及long转16进制字符串的代码实现,这些代码适用于不超过long类型的数字范围,并附带了一个测试用例来验证转换的正确性。
摘要由CSDN通过智能技术生成

最近笔者在做rtmp包时发现,其对应的包整数1转成十六进制是0x3ff000……(12个0),这方面特地搜了一下发现是双精度十六进制数,和普通的转换成十六进制不太相同(百度的几个结果都是在matlab上发现的)。于是笔者花时间调了一下相互转换的代码以便组包,不超过long类型的数字范围都可使用,供各位同仁参考。

16进制字符串转long类型输出:

long makeFloatHexToLong(unsigned char* _str)
{
	short __realExNum = ((((long)_str[0]) << 0x04) | ((((long)_str[1]) >> 0x04)&0x0f))-1023;
	short __arrayIndex = (__realExNum+12) / 8+(((__realExNum+12)%8)?1:0)-1;
	if(__arrayIndex==1)
	{
		short __dMov=(8-((__realExNum + 12) % 8));
		long __res=(((long)_str[1])>>__dMov)&0x0f;
		printf("%d\n",(0x01<<__realExNum));
		__res|=(0x01<<__realExNum);
		return __res;
	}
	short __dMov=(8-((__realExNum + 12) % 8));
	long __res=0;
	if(__dMov<8)
		__res |= (((long)_str[__arrayIndex])>>__dMov);
	else
		__res |= ((long)_str[__arrayIndex]);
	for (short __i = __arrayIndex - 1; __i > 1; --__i)
		__res |= ((long)_str[__i] << (8*(__arrayIndex-__i)-__dMov));
	__res |=((((long)_str[1])&0x0f)<<(__realExNum-4));
	__res|=(0x01<<(__realExNum));
	return __res;
}

long转成16进制字符串传输:

void makeFloatHexNum2(long _DecNum,unsigned char* _str)
{
	long __DecNum = _DecNum;
	short __len = 0;
	long __TmpBit =0;
	memset(_str, 0, sizeof(_str));
	while (__DecNum != 0)
	{
		__DecNum = __DecNum >> 1;
		++__len;
	}
	--__len;
	short __realDataLen = __len;
	int __Index = 1023 + __len;
	while (__Index != 0)
	{
		__Index = __Index >> 1;
		++__len;
	}
	++__len;
	short __exLen = 11;
	unsigned char* __ptr = _str;
	__DecNum = 1023+__realDataLen;
	bool __BecomeRealDataBit = false;
	short __resever = 8;
	long __tmpData = 0;
	while (__DecNum != 0||__BecomeRealDataBit==false)
	{
		if (__DecNum == 0 && __BecomeRealDataBit == false&&__exLen==-1)
		{
			__BecomeRealDataBit = true;
			__DecNum = _DecNum&(~(0x01<<__realDataLen--));
			if(__DecNum==0)
				break;
		}

		if (__BecomeRealDataBit == false)
		{
			__TmpBit = __DecNum & (0x01 << __exLen);
			if(__TmpBit!=0)
				__tmpData |= (0x01 << --__resever);	
			else
				--__resever;
			__DecNum = __DecNum & (~(0x01 << __exLen--));
		}
		else
		{
			__TmpBit = __DecNum & (0x01<<__realDataLen);
			if(__TmpBit!=0)
				__tmpData |= (0x01 << --__resever);
			else
				--__resever;
			__DecNum = __DecNum & (~(0x01 << __realDataLen--));
		}
		
		if (__resever == 0)
		{
			*__ptr = __tmpData;
			++__ptr;
			__tmpData = 0;
			__resever = 8;
		}
	}

	*__ptr = __tmpData;
	
}

测试代码:

int main(int argc, const char * argv[]) {
    
	unsigned char str[100]={0};
	cout <<endl;
	makeFloatHexNum2(1030000000,str);
	for(int i=0;i<8;++i)
		printf("%x ",str[i]);
	cout <<endl;
    printf("%ld",makeFloatHexToLong(str));

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值