C语⾔函数库定点数浮点数转换,定点数与浮点数的相互转换最近要写段数字运算的程序,因为从FPGA获取到的是定点数,15位数,最⾼位bit14是符号位,bit13是整数位,后⾯13位是⼩数位; ⽽我的运算过程都是⽤的浮点数,通过⼀系列计算后,还需要将计算的结果以定点数的形式写⼊寄存器,所以⾸先需要写⼀个定点数和浮点数相互转换的函数。
⾸先明确⼀下定点数和浮点数的概念:
定点数
定点数是⼩数点固定的数。在计算机中没有专门表⽰⼩数点的位,⼩数点的位置是约定默认的。⼀般固定在机器数的最低位之后,或是固定在符号位之后。前者称为定点纯整数,后者称为定点纯⼩数。
例题:⽤8位原码表⽰定点整数(100)10
(100)10 = (1100100)2
定点整数表⽰为
例题:⽤8位原码表⽰定点纯⼩数(-0.6875)10
(-0.6875)10 = (-0.1011)2
定点纯⼩数表⽰为
定点数表⽰法简单直观,但是数值表⽰的范围太⼩,运算时容易产⽣溢出。
浮点数
浮点数是⼩数点的位置可以变动的数。为增⼤数值表⽰范围,防⽌溢出,采⽤浮点数表⽰法。浮点表⽰法类似于⼗进制中的科学计数法。
在计算机中通常把浮点数分成阶码和尾数两部分来表⽰,其中阶码⼀般⽤补码定点整数表⽰,尾数⼀般⽤补码或原码定点⼩数表⽰。为保证不损失有效数字,对尾数进⾏规格化处理,也就是平时所说的科学记数法,即保证尾数的最⾼位为1,实际数值通过阶码进⾏调整。
⼀般浮点数在机器中的格式为:
阶符表⽰指数的符号位、阶码表⽰幂次、数符表⽰尾数的符号位、尾数表⽰规格化后的⼩数值。
N = 尾数×基数阶码(指数)
例题:⼆进制数-110101101.01101可以写成:-0.11010110101101×21001
这个数在机器中的格式为(阶码⽤8为表⽰,尾数⽤24位表⽰)
C语⾔代码实现如下:
/************************************************************************
* 函数名称: BspFixToDou
* 功能描述: 将指定的定点数 转化为 浮点数
* 算法描述: ⽆
* 输⼊参数: ucType 0表⽰⽆符号 1表⽰有符号
*          ucInteger 表⽰整数占⼏个bit
*          ucdecimal 表⽰⼩数占⼏个bit
*          llfix 为待转化的定点数
* 输出参数: ⽆
* 返 回 值: ⽆
************************************************************************/
VOID BspFixToDou(UCHAR ucType, UCHAR ucInteger, UCHAR ucdecimal, UINT64 llfix, DOUBLE *pdbRet) {
UINT64 lltemp = llfix & ((((UINT64)(1)<
if(0 == llfix)
{
*pdbRet = 0.0;
}
if(lltemp & (((UINT64)(1)<
{
*pdbRet = -(DOUBLE)(((UINT64)(1)<
}
else                                        /* ⽆符号数或者有符号数的正数*/
{
*pdbRet = (DOUBLE)((DOUBLE)lltemp/(DOUBLE)((UINT64)1<
}
}
/************************************************************************
* 函数名称: BspDouToFix
* 功能描述: 将指定的浮点数 转化为 定点数
* 算法描述: ⽆
* 输⼊参数:  ucType 0表⽰⽆符号 1表⽰有符号
*          ucInteger 表⽰整数占⼏个bit
*          ucdecimal 表⽰⼩数占⼏个bit
*          dbDou 为待转化的浮点数
* 输出参数: ⽆
支持小数点的进制转换器* 返 回 值: 转化后的定点数
************************************************************************/
VOID BspDouToFix(UCHAR ucType, UCHAR ucInteger, UCHAR ucdecimal, DOUBLE dbDou, UINT64 *pllfix) {
UINT64 lltemp = 0;
DOUBLE dbtemp = 0;
dbtemp = dbDou;
if(dbtemp < 0) /* 有符号正数 或者 ⽆符号数 */ {
lltemp = (UINT64)(-dbDou*(1<
*pllfix = (UINT64)((UINT64)(1)<
}
else if(dbtemp > 0)  /* 有符号负数 */
{
*pllfix = (UINT64)(dbDou * (1<
}
else
{
*pllfix = 0;
}
}