定点数与浮点数的相互转换

时间:2022-05-22 17:49:24

      最近要写段数字运算的程序,因为从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语言代码实现如下:


/*<FUNC>***********************************************************************
* 函数名称: 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)<<(ucType + ucInteger + ucdecimal))-1));
    if(0 == llfix)
    {
        *pdbRet = 0.0;
    }
    if(lltemp & (((UINT64)(1)<<(ucInteger + ucdecimal)))) /* 有符号数并且是负数 */
    {
        *pdbRet = -(DOUBLE)(((UINT64)(1)<<(ucType + ucInteger + ucdecimal)) - lltemp)/(DOUBLE)((UINT64)(1)<<ucdecimal);    
    }
    else                                         /* 无符号数或者有符号数的正数*/
    {
        *pdbRet = (DOUBLE)((DOUBLE)lltemp/(DOUBLE)((UINT64)1<<ucdecimal));
    }
}


/*<FUNC>***********************************************************************
* 函数名称: 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<<ucdecimal));
        *pllfix = (UINT64)((UINT64)(1)<<(ucType + ucInteger + ucdecimal)) -    lltemp;    
    }
    else if(dbtemp > 0)   /* 有符号负数 */
        {
            *pllfix = (UINT64)(dbDou * (1<<ucdecimal));
        }
        else
        {
            *pllfix = 0;
        }
}