#include <stdio.h>

float Hex_To_Decimal(unsigned char *Byte,int num)//十六进制到浮点数

{

//   char cByte[4];//方法一

//     for (int i=0;i<num;i++)

//     {

//  cByte[i] = Byte[i];

//     }

//     

//  float pfValue=*(float*)&cByte;

//return  pfValue;

 

  return *((float*)Byte);//方法二

 

}

long FloatTohex(float HEX)//浮点数到十六进制转换1

{

 return *( long *)&HEX;

}

 

void FloatToByte(float floatNum,unsigned char* byteArry)浮点数到十六进制转换2

{

    char* pchar=(char*)&floatNum;

    for(int i=0;i<sizeof(float);i++)

    {

  *byteArry=*pchar;

  pchar++;

  byteArry++;

 

    }

}

void main()

{

    unsigned char floatToHex[4];

    unsigned    char hexbyte[4]={0xcd,0xCC,0xCC,0x3D};//传输数据为3d cc cc cd

 float Hdecimal=0.0;

 float flh=0.4;

//     int num=sizeof(hexbyte);

//  printf("num= %d\n",num);

    Hdecimal=Hex_To_Decimal(hexbyte,sizeof(hexbyte));//十六进制转换为浮点数

 printf("\n 浮点数为:\n %f\n",Hdecimal);

 

 long hX=FloatTohex(Hdecimal);//浮点数转换为十六进制一

 printf("\n正序十六进制值:\n %f=%X \n",Hdecimal,hX);//正序显示

 FloatToByte(Hdecimal,floatToHex);//浮点数转为十六进制二

 

    printf("\n倒序十六进制:\n%f=%x %x %x %x\n",Hdecimal,floatToHex[0],floatToHex[1],floatToHex[2],floatToHex[3] );//倒序显示

 

 FloatToByte(flh,floatToHex);//浮点数转为十六进制二

    printf("\n倒序十六进制:\n%f=%x %x %x %x\n",flh,floatToHex[0],floatToHex[1],floatToHex[2],floatToHex[3] );//低位在前

 FloatToByte(flh,floatToHex);//浮点数转为十六进制二

 

    printf("\n正序十六进制:\n%f=%x %x %x %x\n",flh,floatToHex[3],floatToHex[2],floatToHex[1],floatToHex[0] );//高位在前

 

 

}

 

 

float存储格式及FPU:

 

float存储格式及FPU  

浮点数用科学计数法的形式存储, 即分成符号位, 底数位和指数位

如 10.0 的二进制表示为 1010.0, 科学表示法表示为: 1.01exp110, 即 (1+0*1/2+1*1/4)*2^3. 小数点每左移一位指数要加1, 每右移一位指数要减1.

其存储格式符合IEEE标准, 即

数据格式        符号位     底数位     指数位

单精度 float     1        23          8

双精度 double    1        52         11

扩展精度         1        64         15

存储顺序为: 符号位 指数位 底数位, 由于底数的个位必为1, 因此个位和小数点就不存储. 指数位的高位也是符号位, 不过为1表示正, 0表示负.

float 因有 8 bits, 所以能表示的有 2 的 256 次方,

      但因為指數應可正可負,

      所以 IEEE 規定, 此處算出的次方須減去 127 才是真的指數,

      所以 float 的指數可從-126 到 128.

      double 型態有 11 bits, 算出的值須減去 1023,

      所以double 的指數可從 -1022 到 1024.

      底数   (mantissa):      

    〈特例〉0   不能以 2 的次方表示

      float : 00 00 00 00

      double: 00 00 00 00 00 00 00 00

由此可推断浮点数的精度. 单精度的底数只存储23位, 即最小一位为 1/2^23, 故精度为 1/2^23 = 1.19209e-7, 可精确到小数点后6位; 双精度的底数存储52位, 最小位为 1/2^52, 精度为 1/2^52 = 2.22045e-16, 能精确到小数点后15位.

双精度的最大值约为 2*2^(2^10-1), 约为1.79e308

关于FPU:

(gdb) list 1,80

1        #include <stdio.h>

2        int main(int argc,char **argv)

3        {

4        float val = 1000;

5        int   ival = val;

6        printf("%f\n",val);

7        printf("%d\n",ival);

8        }

(gdb) display/i $pc

(gdb) break main

Breakpoint 1 at 0x8048365: file float.c, line 4.

(gdb) r

Starting program: /home/lsm1982/float

Breakpoint 1, main () at float.c:4

4        float val = 1000;

1: x/i $pc   0x8048365 <main+17>:         mov     $0x447a0000,�x

(gdb) si

0x0804836a       4        float val = 1000;

1: x/i $pc   0x804836a <main+22>:         mov     �x,0xfffffff4(�p)

(gdb)

5        int   ival = val;

1: x/i $pc   0x804836d <main+25>:         flds    0xfffffff4(�p)

(gdb)

0x08048370       5        int   ival = val;

1: x/i $pc   0x8048370 <main+28>:         fnstcw 0xffffffea(�p)

(gdb)

0x08048373       5        int   ival = val;

1: x/i $pc   0x8048373 <main+31>:         movzwl 0xffffffea(�p),�x

(gdb)

0x08048377       5        int   ival = val;

1: x/i $pc   0x8048377 <main+35>:         mov     $0xc,%ah

(gdb)

0x08048379       5        int   ival = val;

1: x/i $pc   0x8048379 <main+37>:         mov     %ax,0xffffffe8(�p)

(gdb)

0x0804837d       5        int   ival = val;

1: x/i $pc   0x804837d <main+41>:         fldcw   0xffffffe8(�p)

(gdb)

0x08048380       5        int   ival = val;

1: x/i $pc   0x8048380 <main+44>:         fistpl 0xfffffff8(�p)

(gdb)

0x08048383       5        int   ival = val;

1: x/i $pc