• C语言单精度浮点型转换算法


    文章来源:http://blog.csdn.NET/educast/article/details/8522818

    感谢原作者。

    关于16进制浮点数
    对于大小为32-bit的浮点数(32-bit为单精度,64-bit浮点数为双精度,80-bit为扩展精度浮点数), 
    1、其第31 bit为符号位,为0则表示正数,反之为复数,其读数值用s表示; 
    2、第30~23 bit为幂数,其读数值用e表示; 
    3、第22~0 bit共23 bit作为系数,视为二进制纯小数,假定该小数的十进制值为x;

    则按照规定,该浮点数的值用十进制表示为: 
    = (-1)^s * (1 + x) * 2^(e - 127)

    对于49E48E68来说, 
    1、其第31 bit为0,即s = 0 
    2、第30~23 bit依次为100 1001 1,读成十进制就是147,即e = 147。 
    3、第22~0 bit依次为110 0100 1000 1110 0110 1000,也就是二进制的纯小数0.110 0100 1000 1110 0110 1000,其十进制形式为0.78559589385986328125,即x = 0.78559589385986328125。

    这样,该浮点数的十进制表示 
    = (-1)^s * (1 + x) * 2^(e - 127) 
    = (-1)^0 * (1+ 0.78559589385986328125) * 2^(147-127) 
    = 1872333

    以上内容为IEEE的标准,现在有个问题,假设我有两台设备在通讯,一个设备向另外一个设备发送数据,这个数据是浮点数,那么我怎么来发送这个数据呢?怎么让接受方知道发送来的是个浮点数呢?而且发送数据要尽量短,最好还要固定长度,也许有人会怎么做:A发送数据3.7586给B,A先将这个浮点数乘以10000变成整型37586,然后将这个整数发送给B,这样使用的弊端是:1、B要事先知道A将这个数字放大了多少倍。2、A需要做一次浮点数的乘法运算,而B要做一次浮点数的除法运算,这对于单片机来说是个负担。3、这样使用会多占用发送数据。因为事先没人知道这个浮点数到底多大。

    想了半天,觉得使用IEEE的浮点数规则来发送是最可靠的,因为任何浮点数都被表示成4个字节,这对发送和接收双方都是个好消息,只要双方都知道要进行浮点数的发送就可以了。而且IEEE格式浮点数的转换是机器内部执行的,我们不再需要任何的转换,不增加运算量,不增加代码量。
    按照这个原则,编写了测试代码如下:
    发送方A:
    float fSend; //A需要发送的浮点数据
    char chSend[4]; //发送缓冲,经过转换后的浮点数据,变成一个字符型数组。
    //以下为转换
    chSend[0] = *((char *)(&fSend));
    chSend[1] = *((char *)(&fSend) + 1);
    chSend[2] = *((char *)(&fSend) + 2);
    chSend[3] = *((char *)(&fSend) + 3);

    此时A就可以将这个数字发送给B了,B接收到的是4个字节表示的一个浮点数,但需要经过如下转换使用:

    float fReceive; //接收到的浮点数
    char chReceive[4];//接收缓冲。B将接收到的4个字节保存在这里。
    //以下为转换
    *((char *)(&fReceive)) = chReceive[0];
    *((char *)(&fReceive) + 1) = chReceive[1];
    *((char *)(&fReceive) + 2) = chReceive[2];
    *((char *)(&fReceive) + 3) = chReceive[3];

    好了,此时的B已经得到了一个浮点数fReceive;

  • 相关阅读:
    nginx
    mysql
    intelij maven
    redis命令大全
    绑定touch事件后click无效,vue项目解决棒法
    新的用法
    img
    vuedragable
    自己总结
    vuex的项目在id中不能运行
  • 原文地址:https://www.cnblogs.com/zhangbing12304/p/7027965.html
Copyright © 2020-2023  润新知