目标:写一个函数,实现将float型变量转换为字符串的功能。
概念:
科学计数法的形式为a*(n^m),前面的小数部分称为尾数,后面n^m中n称为底数,m称为阶数或指数
系统库指的是通常情况下编程环境默认提供的C标准库和STL
格式:
函数头定义如下。
C/C++ code
int ftostr( char *pBuf, int nSize, float fNum )
pBuf用来存放转换后的字符串,nSize为用户指定的pBuf的大小(以字节为单位),fNum是待转换的浮点数。
返回值为转换后的字符串长度。空间不足或出错时返回0。
要求:
* 用C或C++语言实现,可以使用系统库,但不得使用任何其它辅助函数或类。
* 不得使用系统库中已提供的相关转换函数或类。
* 以十进制的科学计数法表示,形式为:-3.354e-44,表示-3.354*(10^-44)。尾数的区间为(10,-10);
* 当pBuf的空间不足时,可适当截短尾数的精度。当pBuf的空间不够存放符号或阶数时,返回0;
提示:
C\C++语言中的浮点数是以IEEE745标准的格式存放的。float为32位,倒字节序存储。最高位为符号,1表示负。30-23位为阶数,转为十进制后减127可得到原阶数,以m表示。22-1位为尾数,以An表示第n位尾数:A22 * (1/2) + A21 * (1/4) + …… + A1 * (1/(2^22))可得到十进制的纯小数。纯小数加1成为1.xxxx的形式,然后乘以(2^m)即得到原浮点数。
评判标准:
* 有思路简介,代码有注释
* 算法准确,稳定,无异常
* 效率较高
附:
一个分析浮点型变量二进制数据的例程:
C/C++ code
float fTest = 54345.3435f;
unsigned char *pData = (unsigned char*)&fTest;
float fRes = 1.0f; // 表示1.xxx
// 提取尾数
for ( unsigned int i = 0; i < 23; ++i )
{
// 确定尾数所在的字节,并计算当前的位在字节中的位置
unsigned char nBit = pData[ 2 - ( i + 1 ) / 8 ] << ( i + 1 ) % 8;
nBit >>= 7;
fRes += (float)nBit / ( 2 << i ); // 2<<i相当于2^i
}
// 提取阶码,阶码位于第30位到第23位
unsigned char nExp = pData[3];
nExp <<= 1; // 除掉附号位
nExp |= ( pData[2] >> 7 ); // 与下个字节的首位合并,组成阶码
nExp -= 0x7F; // 减127得到原阶数
fRes *= pow( 2.0f, (float)*(char*)&nExp );
// 提取符号位,位于最高位,第31位
if ( pData[3] & 0x80 )
{ // 最高位为1则为负,为0则为正
fRes = -fRes;
}
cout << setprecision(10) << fTest << "->" << fRes;
原贴请见 http://www.myexception.cn/cpp/292234.html
上面例程仅供参考,目的是为了解释浮点数编码,不保证运行结果的正确性。
具体的浮点数编码格式以IEEE745为准,见:
http://www.psc.edu/general/software/packages/ieee/ieee.php
此题的题面描述难免有错漏之处,敬请提醒斧正! |