zoukankan      html  css  js  c++  java
  • 浮点数相关

    一 用四个字节十六进制数表示单精度浮点数:即是所谓的IEEE754标准,这也是大多数硬件存储浮点数的标准。单精度浮点数占4个字节,表示范围为:在负数的时候是从 -3.402823E38 到 -1.401298E-45,而在正数的时候是从 1.401298E-45 到 3.402823E38,其C语言实现如下:

    void FloatToByte(float floatNum,unsigned char* byteArry)/*浮点数转16进制*/
    {
        char* pchar=(char*)&floatNum;
        for(int i=0;i<sizeof(float);i++)
        {
         *byteArry=*pchar;
         pchar++;
         byteArry++;
        }
    } 
    float ByteToFloat(unsigned char* byteArry)/*4字节数转浮点数*/
    {
      return *((float*)byteArry);
    }

    16进制转IEEE 32/64位浮点数(来自http://blog.csdn.net/zhuyunfei/article/details/50973531)

    1.IEEE 32位浮点数格式 
    这种格式的特点是:每个数由4字节组成,包括1位符号位,8位带符号阶码,23位尾数。 
    例如:我们收到一个数的格式是 BE 30 94 00,那么它的二进制格式是:

    这里写图片描述

    1 011 1110 0011 0000 1001 0100 0000 0000 
    这时我们就可以得到这些信息: 
    符号位1 (1表明这个数是个负数,0表明这个数是正数) 
    带符号的阶码011 1110 0 (转化为整数是124)/*指数=(阶码 -127),阶数<0最终对尾数左移|指数|位;否则右移*/
    尾数011 0000 1001 0100 0000 0000

    首先计算指数: 
    指数:阶码 - 127 = -3;表明最终对尾数要进行向左位移3位 
    同理假设算出的指数为5,表明要对尾数进行右移5位。

    然后对尾数进行处理:在尾数的最高位加上一个隐藏位1,形成如下二进制格式: 
    1 011 0000 1001 0100 0000 0000 
    其中小数点的位置就在刚加的隐藏位后,即: 
    1.011 0000 1001 0100 0000 0000 
    根据刚才计算的指数结果-3,小数点左移3位,不够补0,得到最终的浮点数二进制格式为: 
    0.0010 1100 0010 0101 0000 0000 
    计算此二进制格式为 
    0*(2^-1) + 0*(2^-2) + 1*(2^-3) + 0*(2^-4) + 1*(2^-5) + 1*(2^-6) + 0*(2^-7) + 0*(2^-8) + 0*(2^-9) + 0*(2^-10) + 1*(2^-11) + 0*(2^-12) +0*(2^-13) + 1*(2^-14) + 0*(2^-15) + 1*(2^-15) 
    计算后的十进制数0.17243958,根据前面的符号位可知,这是个负数,所以最终结果是-0.17243958

    C语言代码实现如下

    long long int getS(int e,int m)
    {
        long long int s=e;
        for (int i=1;i<m;i++)
        {
            s*=e;
        }
        return s;
    }
    
    float hex2float(unsigned char*p,float& result)
    {
        long long int a=0x00000000;
    
        a=a|p[0];
        a=(a<<8)|p[1];
        a=(a<<8)|p[2];
        a=(a<<8)|p[3];
    
        //获得符号位,1表示负数,0表示正数
        int s=(a>>31)&0xFF;
        int e=(a>>23)&0x0FF;
        //获得指数
        e=e-127;
        //获得底数
        long long int m=a&0x7FFFFF|0x800000;
        long long int c=0;
        float v = 0.0f, y = 1.0f;
        //向右移动
        if (e>0)
        {
            //获得整数的二进制
            c=(m>>(23-e))&0xFFFFFFF;
            long int b=0;
            for (int i=0;i<23-e;i++)
            {
                b=(b<<1)|0x01;
            }
            //获得小数的二进制
            b=b&m;
            int j=0;
            for (int i=23-e-1;i>=0;i--)
            {
                j++;
                y=(double)(((b>>i)&0x01)*getS(2,j));
                if (y>0.0)
                {
                    v+=1.0/y;
                }
            }
            v=c+v;
            if (s>0)
            {
                v=-v;
            }
        }
        else
        {
            //向左移动
            e=-e;
            c=m;
            int j=0;
            for (int i=23+e-1;i>=0;i--)
            {
                j++;
                y=(float)(((c>>i)&0x01)*getS(2,j));
                if (y>0.0)
                {
                    v+=1.0/y;
                }
            }
            if (s>0)
            {
                v=-v;
            }
        }
    
        result = v;
        return v;
    }

    2.IEEE 64位浮点数格式 
    这种格式的特点是:每个数由8字节组成,包括1位符号位,11位带符号阶码,52位尾数。 
    例如:我们收到一个数的格式是 3F F0 6F 80 00 00 00 00,那么它的二进制格式是: 
    这里写图片描述

    0011 1111 1111 0000 0110 1111 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 
    这时我们就可以得到这些信息: 
    符号位:0 (1表明这个数是个负数,0表明这个数是正数) 
    带符号的阶码:011 1111 1111 (转化为整数是1023) 
    尾数:0000 0110 1111 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000

    首先计算指数: 
    指数:阶码 - 1023 = 0;表明此尾数不需要移位

    然后对尾数进行处理:在尾数的最高位加上一个隐藏位1,形成如下二进制格式: 
    1 0000 0110 1111 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 
    其中小数点的位置就在刚加的隐藏位后,即: 
    1.0000 0110 1111 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 
    次数不用移位,故得到最终的浮点数二进制格式为: 
    1.0000 0110 1111 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 
    计算此二进制格式为 
    1*(2^-0) + 0*(2^-1) + 1*(2^-2)0*(2^-2) + 1*(2^-3) 1*(2^-4) + 0*(2^-5) + 1*(2^-6) + 1*(2^-7) + 0*(2^-8) + 1*(2^-9) + 1*(2^-10) +1*(2^-11) + 1*(2^-12) + 1*(2^-13) + 0*(2^-14)+ …. + 0*(2^-52) 
    计算后的十进制数1.02722168,根据前面的符号位可知,这是个正数,所以最终结果是1.02722168

    C语言实现代码

    long long int getS(int e,int m)
    {
        long long int s=e;
        for (int i=1;i<m;i++)
        {
            s*=e;
        }
        return s;
    }
    double hex2double(unsigned char*p,double& result)
    {
        long long int a=0x0000000000000000;
        a=a|p[0];
        a=(a<<8)|p[1];
        a=(a<<8)|p[2];
        a=(a<<8)|p[3];
        a=(a<<8)|p[4];
        a=(a<<8)|p[5];
        a=(a<<8)|p[6];
        a=(a<<8)|p[7];
        int s=(a>>63)&0xFF;//获得符号位,1表示负数,0表示正数
        int e=(a>>52)&0x7FF;
        e=e-1023;//获得指数
        long long int m=a&0xFFFFFFFFFFFFF|0x10000000000000;//获得底数
        //cout<<setiosflags(ios::uppercase)<<hex<<m<<endl;
        long long int c=0;
        double v=0.0,y=1.0;
        if (e>=0)//向右移动
        {
            c=(m>>(52-e))&0xFFFFFFFFFFFFFFFF;//获得整数的二进制
            long long int b=0;
            for (int i=0;i<52-e;i++)
            {
                b=(b<<1)|0x01;
            }
            b=b&m;//获得小数的二进制
            int j=0;
            for (int i=52-e-1;i>=0;i--)
            {
                j++;
                y=(double)(((b>>i)&0x01)*getS(2,j));
                if (y>0.0)
                {
                    v+=1.0/y;
                }
            }
            v=c+v;
            if (s>0)
            {
                v=-v;
            }
        }
        else//向左移动
        {
            e=-e;
            c=m;
            int j=0;
            for (int i=52+e-1;i>=0;i--)
            {
                j++;
                y=(float)(((c>>i)&0x01)*getS(2,j));
                if (y>0.0)
                {
                    v+=1.0/y;
                }
            }
            if (s>0)
            {
                v=-v;
            }
        }
        result = v;
        return v;
    }

    3.4)浮点数:32位,4个字节,依次为P,SMH,MM,ML,用F(Float)表示;

       其中:单精度二进制浮点数为:FloatData = ±0.MH-MM-ML*2P

       P 为阶码,1个字节,以十六进制补码的形式表示;

       SMH 为尾数的高字节,1个字节,最高位(第7位)为符号位S,S=1 表示数据为负,

            S=0 则数据为正;其余7位为浮点数尾数的高7位,第0到6位;

       MM 为尾数的中间字节,1个字节,第7到14位;;

       MM 为尾数的低字节,1个字节,第15到23位;;

    3.4.1 累积量采用6个字节的浮点数表示:依次为P,SMH,MM,ML,ML1,ML2,用F(Float)表示; FloatData = ±0.MH-MM-ML-ML1-ML2*2P

     
  • 相关阅读:
    TI CC2541的整体目标
    TI CC2541的GPIO引脚设置.
    E2PROM与Flash的引脚图
    TI BLE CC2541的通讯协议.
    TI BLE CC2541的I2C主模式
    Charles如何抓取电脑上的请求的https数据包
    Charles如何抓取手机上的请求的https数据包
    谷歌浏览器chrome调试H5页面 如果添加cookie?
    Unity 好坑的Save Scene
    Unity 官网教程 -- Multiplayer Networking
  • 原文地址:https://www.cnblogs.com/jieruishu/p/5541543.html
Copyright © 2011-2022 走看看