Chinaunix首页 | 论坛 | 博客
  • 博客访问: 665812
  • 博文数量: 111
  • 博客积分: 5010
  • 博客等级: 大校
  • 技术积分: 1461
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-08 14:40
文章分类

全部博文(111)

文章存档

2010年(10)

2009年(70)

2008年(31)

我的朋友

分类: C/C++

2008-06-15 18:55:48

有关fixed point number和floating point number的问题

fixed   point   number:存贮是按下图所示:  
  |8       7       6       5       4       3       2       1|  
  |X8     X9     X10   X11   X12                     |第一字节  
  |S       X1     X2     X3     X4     X5     X6   X7|第二字节  
 

  其中S为符号位,X1...X12表示2的负1次方到负12次方,剩余几位是别的用途。这样表示数的范围是-1   ...   1-(2的负12次方),当符号位为1表示负数,此时如果X1到X13都为零,那么表示数是-1。  
  我现在的问题是,如果写一个函数来把这两个字节中的数转化为float型数直接可以用。或者给你一个float型的数,写一个函数把它存储到两个字节的空间去,我花了不少时间仍想不出一种比较简便快捷的方法,如果有人能给出一个比较完美的算法,我不会吝啬分数的。呵呵,多谢了!

按照上面所说的方式存放到一个字节数组里去,在数组里面占连续的两个元素。还有就是一个相反的过程。

nSign   =   (short)uFixed   >   0;   写错了,应该是   nSign   =   (short)uFixed   <   0;   重贴一下:  
   
分别用位域和移位来实现,这样写是为了让你看清楚float的构成,还提供了最简单的方法

 

  #include "stdafx.h"
  #include <stdio.h>
  #include <assert.h>
  #include <math.h>
    
    
  typedef struct
  {
          unsigned short uSpare : 3; // 为了对齐

          unsigned short uSignificand : 12;
          short nSign : 1;
  }FIXED_BIT;
    
  typedef union
  {
          unsigned short uFixed;
          FIXED_BIT tFixedBit;
  }FIXED;
    
  typedef struct
  {
          unsigned int uSignificand : 23;
          int nExponent : 8;
          int nSign : 1;
  }FLOAT_BIT;
    
  typedef union
  {
          float fFloat;
          FLOAT_BIT tFloatBit;
          unsigned int uFloat;
  }FLOAT;
    
  unsigned short FloatToFixed( float fFloat ); // 部分用位域实现

  float FixedToFloat( unsigned short uFixed ); // 部分用位域实现

    
  unsigned short FloatToFixedEx( float fFloat ); // 全部用移位实现

  float FixedToFloatEx( unsigned short uFixed ); // 全部用移位实现

    
  unsigned short FloatToFixedSimple( float fFloat ); // 最简单实现

  float FixedToFloatSimple( unsigned short uFixed ); // 最简单实现

    
    
  int main()
  {
          float x = (float)-0.175;
          unsigned short y;
    
          printf( "x = %f\n",x );
          y = FloatToFixed( x );
          printf( "fixed = 0x%x\n",y );
          printf( "float = %f\n",FixedToFloat(y) );
    
          y = FloatToFixedEx( x );
          printf( "fixed = 0x%x\n",y );
          printf( "float = %f\n",FixedToFloatEx(y) );
    
          y = FloatToFixedSimple( x );
          printf( "fixed = 0x%x\n",y );
          printf( "float = %f\n",FixedToFloatSimple(y) );
    
          return 0;
  }
    
  unsigned short FloatToFixed( float fFloat )
  {
          FLOAT unFloat;
          FIXED unFixed;
          int nExponent;
    
          unFloat.fFloat = fFloat;
            
          nExponent = (int)unFloat.tFloatBit.nExponent - 0x7f;
    
          // float的significand表示1~2之间的数,expoent=0x7f表示指数0

              
          // 不太清楚你对溢出有什么要求

    
          // 指数是否溢出

          assert( (nExponent >= -12) && (nExponent <= 0) );
    
          unFixed.tFixedBit.uSpare = 0;
    
          unFixed.tFixedBit.nSign = unFloat.tFloatBit.nSign;
    
          unFixed.tFixedBit.uSignificand = ((int)unFloat.tFloatBit.uSignificand + 0x800000)
                                                                            >> (11 - nExponent);
            
          return unFixed.uFixed;
  }
    
  float FixedToFloat( unsigned short uFixed )
  {
          FLOAT unFloat;
          FIXED unFixed;
            
          unsigned int uSignificand;
    
          unFixed.uFixed = uFixed;
          uSignificand = unFixed.tFixedBit.uSignificand << 11;
    
          unFloat.tFloatBit.nExponent = 0x7f;
    
          while( (uSignificand & 0x800000)==0 )
          {
                  uSignificand <<= 1;
                  unFloat.tFloatBit.nExponent--;
          }
          uSignificand -= 0x800000;
    
          unFloat.tFloatBit.uSignificand = uSignificand;
          unFloat.tFloatBit.nSign = unFixed.tFixedBit.nSign;
    
          return unFloat.fFloat;
  }
    
  unsigned short FloatToFixedEx( float fFloat )
  {
          FLOAT unFloat;
          unsigned int uFloat;
          int nSign;
          int nExponent;
          int nSignificand;
    
          unFloat.fFloat = fFloat;
          uFloat = unFloat.uFloat;
            
          nSign = (int)uFloat < 0;
          nExponent = ((uFloat & 0x7fffffff) >> 23) - 0x7f;
          nSignificand = (uFloat & 0x7fffff) + 0x800000;
    
          // float的significand表示1~2之间的数,expoent=0x7f表示指数0

              
          // 不太清楚你对溢出有什么要求

    
          // 指数是否溢出

          assert( (nExponent >= -12) && (nExponent <= 0) );
    
          nSignificand >>= (8 - nExponent);
          nSignificand &= 0xfffff8; // 清除低3位

            
          if( nSign==0 )
          {
                  return (unsigned short)nSignificand;
          }
          else
          {
                  return (unsigned short)nSignificand | 0x8000;
          }
          //return (unsigned short)( (nSign << 15) | nSignificand );

  }
      
  float FixedToFloatEx( unsigned short uFixed )
  {
          FLOAT unFloat;
          int nSign;
          int nExponent;
          int nSignificand;
            
          nSign = (short)uFixed < 0;
          nExponent = 0x7f;
          nSignificand = (uFixed & 0x7fff) << 8;
            
          while( (nSignificand & 0x800000)==0 )
          {
                  nSignificand <<= 1;
                  nExponent--;
          }
          nSignificand -= 0x800000;
            
          unFloat.uFloat = (nSign << 31) | (nExponent << 23) | nSignificand;
    
          return unFloat.fFloat;
  }
    
  unsigned short FloatToFixedSimple( float fFloat )
  {
          int nSign = fFloat<0.0;
          int nSignificand;
            
          if( nSign==0 )
          {
                  nSignificand = (int)(fFloat * 4096);
                  assert( nSignificand<4096 );
                  return (unsigned short)(nSignificand << 3);
          }
          else
          {
                  nSignificand = (int)(-fFloat * 4096);
                  assert( nSignificand<4096 );
                  return (unsigned short)(nSignificand << 3) | 0x8000;
          }
            
  }
    
  float FixedToFloatSimple( unsigned short uFixed )
  {
          int nSign;
          int nSignificand;
            
          nSign = (short)uFixed < 0;
          nSignificand = ( (int)uFixed & 0x7fff) >> 3;
    
          if( nSign==0 )
          {
                  return (float)(nSignificand/4096.0);
          }
          else
          {
                  return -(float)(nSignificand/4096.0);
          }
  }
    
  运行结果:
    
  x = -0.175000
  fixed = 0x9660
  float = -0.174805
  fixed = 0x9660
  float = -0.174805
  fixed = 0x9660
  float = -0.174805
  Press any key to continue

阅读(13471) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~