有关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
|
阅读(13401) | 评论(0) | 转发(0) |