浮点数传输与保存的方法

浮点数传输与保存的方法

  浮点数在软件设计中是一种非常常用的数据类型,但是浮点数的传输是一个麻烦的事情,本文旨在介绍一种浮点数的存储和传输的方式

  • 本文约定浮点数在内存中存储使用的是4个字节的形式和int类型一致,注意不同操作系统可能不相同

1、方案说明


话不多说直接上代码

#include <stdio.h>

int main()
{
    float a=1.2,b=0;
    unsigned int c=0,d=0;
    unsigned char buf[4]={0};

    /* 发送方 */
    c=*(unsigned int *)(&a);
    buf[0]=c>>24;
    buf[1]=c>>16;
    buf[2]=c>>8;
    buf[3]=c>>0;

    /* 接受方 */
    d=(((unsigned int)buf[0])<<24 | ((unsigned int)buf[1])<<16 |
		((unsigned int)buf[2])<<8 | ((unsigned int)buf[3])<<0);
    b=*(float *)(&d);

    printf("a=%f a_int=%d c=%d b=%f",a,a,c,b);

    return 0;
}

方案描述:

  • 发送方:首先将float浮点数转化为unsigned int无符号整数读取,之后将unsigned int无符号整数拆分为四个字节的unsigned char无符号字符型数据,之后便可以拿着这四个字节的数据进行存储和传输了
  • 接受方:接受到四个字符型的数据或者读取到这四个字符型数据之后,按照对应的大小端顺序组合成unsigned int无符号整数,之后再把unsigned int无符号整数转化为float浮点数读取使用

2、方案验证


使用以下代码将一个任意的浮点数转化得到四个无符号字符型数据

#include <stdio.h>

int main()
{
    float a=2.67809,b=0;
    unsigned int c=0,d=0;
    unsigned char buf[4]={0};

    c=*(unsigned int *)(&a);
    buf[0]=c>>24;
    buf[1]=c>>16;
    buf[2]=c>>8;
    buf[3]=c>>0;

    d=((unsigned int)buf[0])<<24 | ((unsigned int)buf[1])<<16 |
		((unsigned int)buf[2])<<8 | ((unsigned int)buf[3])<<0;

    b=*(float *)(&d);

    printf("a=%f a_int=%x\n c=%x b=%f\n",a,a,c,b);
    printf("buf[0]=%x buf[1]=%x buf[2]=%x buf[3]=%x\n",buf[0],buf[1],buf[2],buf[3]);

    return 0;
}

运行结果

a=2.678090 a_int=402b65d4
 c=402b65d4 b=2.678090
buf[0]=40 buf[1]=2b buf[2]=65 buf[3]=d4

得到的四个字符存储在buf数组中,之后再编写以下接受程序将字符型型数据转化为浮点数

#include <stdio.h>

int main()
{
    float b=0;
    unsigned int d=0;
    unsigned char buf[4]={0x40,0x2b,0x65,0xd4};
	
    d=(((unsigned int)buf[0])<<24 | ((unsigned int)buf[1])<<16 |
		((unsigned int)buf[2])<<8 | ((unsigned int)buf[3])<<0);
    b=*(float *)(&d);
    printf("d=%d b=%f",d,b);

    return 0;
}

运行结果

d=1076585940 b=2.678090

运行结果显示得到的浮点数是正常的,验证此方法成功可用!

3、踩过的坑


在将字符型数据组合成整数的时候出现了一个离奇的现象,|<<+之间的不可描述的关系,见代码

#include <stdio.h>

int main()
{
    float b=0;
    unsigned int d=0;
    unsigned char buf[4]={0x40,0x2b,0x65,0xd4};
    
    d=(((unsigned int)buf[0])<<24 + ((unsigned int)buf[1])<<16 +
		((unsigned int)buf[2])<<8 + ((unsigned int)buf[3])<<0);
    b=*(float *)(&d);
    
    printf("d=%d b=%f",d,b);
    return 0;
}

运行结果为

d=0 b=0.000000

d的结果为0!很离奇,移位操作结果出现了问题,更换一种方法先把移位的值保存起来再移位试一下

#include <stdio.h>

int main()
{
    float b=0;
    unsigned int d=0;
    unsigned char buf[4]={0x40,0x2b,0x65,0xd4};
	unsigned int x[4]={0};
	
	x[0]=((unsigned int)buf[0])<<24;
	x[1]=((unsigned int)buf[1])<<16;
	x[2]=((unsigned int)buf[2])<<8;
	x[3]=((unsigned int)buf[3])<<0;
	
    d=((((unsigned int)buf[0])<<24) + (((unsigned int)buf[1])<<16) +
		(((unsigned int)buf[2])<<8) + (((unsigned int)buf[3])<<0));
//	d=x[0]+x[1]+x[2]+x[3];
    b=*(float *)(&d);
    printf("d=%d b=%f",d,b);

    return 0;
}

运行结果

d=1076585940 b=2.678090

这样是可以的,这就奇怪了,之后把+换成|测试

#include <stdio.h>

int main()
{
    float b=0;
    unsigned int d=0;
    unsigned char buf[4]={0x40,0x2b,0x65,0xd4};
    
    d=(((unsigned int)buf[0])<<24 | ((unsigned int)buf[1])<<16 |
		((unsigned int)buf[2])<<8 | ((unsigned int)buf[3])<<0);
    b=*(float *)(&d);
    
    printf("d=%d b=%f",d,b);
    return 0;
}

运行结果为

d=1076585940 b=2.678090

+换成|测试是可以的,后来仔细查找原因才发现|<<+之间的不可描述的关系
在这里插入图片描述
猝死在运算符的优先级!
下次长记性了,没事多加个()~

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱出名的狗腿子

你的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值