0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

定点数和浮点数的概念 浮点数二进制序列与指数表达式之间的转化

CHANBAEK 来源:工程实验室 作者:工程实验室 2023-08-22 16:06 次阅读

1、定点数和浮点数的概念

定点数,小数点位置固定不变,参与运算的数据其小数点固定的位于所有数字中间的某个位置,比如货币的表达,规定了使用2位整数位+2位小数表示的模式,具体数据如99.00、10.55、68.66等。定点数的缺点:由于小数点位置固定不变,定点数所表示的数的范围非常有限,不能同时表达特别大或特别小的数,所以才出现了浮点数,以此来扩充数的范围,同时浮点数也广泛应用于精度要求高的场合。简单的理解浮点数:首先浮点数小数点位置不固定,小数点是浮动的,其次浮点数提供了一种高效的数据表达方法,这种表示方法既可以表达很小的数据比如:3.14159、0.06789,也可以表达很大的数据比如:8.99910^20、510^25。

数据在计算机中的存储分为整型(char(8bit)、short(16bit)、int(32bit)、long(32bit)、long long(64bit))和浮点型(float(32bit)、double(64bit)),计算机中不可能存储“无穷大”的数,也不能存放循环小数。(注:循环小数按照浮点数的规则存储),例如C程序中计算和输出1/3:

printf("%f",1/3.0);

得到的结果是:0.333333,只能得到6位小数,而不是理论计算的无穷位的小数。

查看我们在C语言课本上学习过的知识点:

图片

图1-1、C语言中的浮点数数据类型

2、浮点数的结构

通过图1-1,我们知道单精度浮点数(float)的取值范围为:-3.4E38 - -3.4E38,双精度浮点数(double)的取值范围是:-1.7E308 - 1.7E308,精度再高一些表示为:-1.79E308 - 1.79E308。C语言中定义相应的浮点数float和double变量以后,在编译器的帮助下即可参与相应的运算,那么浮点数的内部结构又是如何呢?下文将详细讲解。

float   a = 4.5;
double  b = 3.5e2,c;
c =  a*b;

在IEEE754标准中规定了浮点数的表达方式,浮点数的存储方式是以2为底数的表达方式。浮点数的表达中将数据表达的二进制序列分为符号位,指数位和小数位三个区域。浮点数的指数表达式如下:

x =-1^s *1.m* 2^e;
表达32bit的浮点数时e = E-127;表达64bit的浮点数时e = E-1023,这里的1271023称为偏移量。
公式中:
s表示符号位:正数为0,负数为1e表示指数位:存储指数加上偏移量,偏移量是为了表达负数而设计的;
m表示小数部分:存储小数部分的准确值或者接近的值;
注:类比科学计数法,以10为底数的表示方法中前面的系数都是小于10 的系数比如:8.bb*10^(x);以2为底数的表示方法,前面的系数都是小于2的系数,比如:1.bb*2^(x),前面还要符号位(-1)^s

浮点数的二进制序列表达式中特定宽度的区域划分如下:

图片

图2-1、不同精度浮点数特定宽度区域划分

3、浮点数二进制序列与指数表达式之间的转化

比如10进制表示的小数0.085(我们常说的小数在计算机存储系统中就是浮点数),其指数表达式为1.36*2^-4,其小数部分0.36使用了23位来表示。

图片

图3-1、10进制小数与指数表达式的关系

Matlab中,将浮点数转化为16进制序列

>> a=single(0.085)
a =
  single
    0.0850
 >> num2hex(a)
ans =
3dae147b

将十六进制序列 3dae147b(H)转化为二进制序列

001111011010111000010100011110(32bit:1位符号位+8位指数位+23位小数位)

符号位:0,表示正数;

指数部分:01111011,12^0+12^1+02^2+12^3+12^4+12^5+1*2^6 = 123;

小数部分:010111000010100011110,通过表3-1来拆分每个比特位所表达的数值。

第n位2的幂次:2^(-n)10进制表示求和
11/2-2^(-1)0*2^(-1)=00
21/4-2^-21*0.250.25
41/161*0.06250.3125
51/321*0.031250.34375
61/641*0.0156250.359375
111/20481*0.00048828125......
131/8192............
171/131072............
181/262144............
191/524288............
201/1048576............
221/4194304............
231/8388608......0.36000001430512

表3-1、小数部分二进制序列拆分

综上:单精度浮点数0.085,使用指数表示的结果为:

(-1)^01.362^-4=1.36*2^-4,其中指数部分 e=123-127= -4,小数部分的0.36是23位二进制序列所表达的数值之和。

3.1、数据转化举例:

问题1: 十进制表达的小数0.1254,(1)、求64bit双精度浮点数的标准16进制序列,(2)、用指数形式表示。

>>  a=double(0.1254)
a =
    0.1254
 >>  num2hex(a)
ans =
    '3fc00c435bd31c33'

双精度浮点数16进制序列为:64’h3fc00c435bd31c33

将16进制数展开后,可得二进制数格式为

0011 1111 1100 0000 0000 1100 0100 0011 0101 1011 1101 0011 0001 1100 0011 0011

符号位: bit[63] ------1位-----0---正数

指数部分: bit[62]-[52]------11位--011 1111 1100

指数部分求解十进制结果:

> > 1*2^9+1*2^8+1*2^7+1*2^6+1*2^5+1*2^4+1*2^3+1*2^2
ans =
        1020
1020-1023=-3,浮点数的指数部分数值-减去偏移量,得到实际指数表达式中的指数为-3。

小数部分:bit[51]-[0] - 共52bit:

0000 0000 1100 0100 0011 0101 1011 1101 0011 0001 1100 0011 0011

求53bit二进制序列所表示的小数:

1*2^(-9)+1*2^(-10)+1*2^(-14)+1*2^(-19)+1*2^(-20)+1*2^(-22)+1*2^(-24)+1*2^(-25)+1*2^(-27)+1*2^(-28)+1*2^(-29)+1*2^(-30)+1*2^(-32)+1*2^(-35)+1*2^(-36)+1*2^(-40)+1*2^(-41)+1*2^(-42)+1*2^(-47)+1*2^(-48)+1*2^(-51)+1*2^(-52)
> > 1*2^(-9)+1*2^(-10)+1*2^(-14)+1*2^(-19)+1*2^(-20)+1*2^(-22)+1*2^(-24)+1*2^(-25)+1*2^(-27)+1*2^(-28)+1*2^(-29)+1*2^(-30)+1*2^(-32)+1*2^(-35)+1*2^(-36)+1*2^(-40)+1*2^(-41)+1*2^(-42)+1*2^(-47)+1*2^(-48)+1*2^(-51)+1*2^(-52)
ans =
    0.0030

得到浮点数的指数表达式:1.0030*2^(-3)。

验证计算结果如下:

>> 1.0030*2^(-3)
ans =
    0.1254

Matlab中浮点数转为十进制数:

>> a='3fc00c435bd31c33'
a =
'3fc00c435bd31c33'
 >> hex2num(a)
ans =
    0.1254

问题2十进制表达的整数-5,(1)、求32bit单精度浮点数的标准16进制序列,(2)、用指数形式表示。

>> a=single(-5)
a =
  single
    -5
 >> num2hex(a)
ans =
c0a00000

-5的浮点数表示为:

1100 0000 1010 0000000000000000000000

符号位:bit[31] --1位--1--负数

指数位:bit[30]-[23]--8位--10000001

>> 1*2^7+1*2^0
ans =
   129
指数数值-减去偏移量,得到指数为:129-127=2

小数位:bit[22]-[0]-23位:

0100000000000000000000000,

>> 0*2^-1+1*2^-2
ans =
    0.2500

所以-5的指数表达式为:(-1)1.252^2。

验证计算结果如下:

>> -1*1.25*2^2
ans =
    -5

4、小数转化为定点数

FPGA 设计开发的过程中,如果需要使用小数参与相关运算,这个时候就需要将小数转化为定点数,因为FPGA内部只能处理定点数,不能处理小数,小数转定点数的过程需要考虑符号位-整数位宽-小数位位宽。

假设将小数2.918量化为16bit的定点数,包含1bit符号位,3bit整数位,12bit小数位。16位数据能够表示的最大正数为32767(2^15-1),能够表示的最小负数为-32768。

图片

图4-1、C语言中部分数据类型对应的取值范围

3bit整数位能够表示的最大整数是7(3'b111),12位小数位能够表示的数据的最小精度为:1/(2^12)=0.00024414,也就是说12位小数位只能表示0.00024414的整数倍,12位小数位能够表达的最大小数为:

>> (2^12-1)*0.00024414
ans =
    0.9998

可以发现表示小数的位数越多,可以表示的小数范围越大,表示的也越精准。(小数定点量化过程中使用位宽的大小和数据精度的关系),表示小数部分0.918,需要的十进制数值为:

>> 0.918/0.00024414
ans =
   3.7601e+03

也可以使用Matlab中的函数完成小数部分的量化。

>>  dec2bin(round(0.918*2^12),12)
ans =
111010110000
 >> bin2dec('111010110000')
ans =
        3760

所以小数2.918量化为16bit的定点数结果为:16'b0100111010110000

问题 :将浮点数-3.125量化为8bit的定点数,包含1bit符号位,4bit整数位,3bit小数位。

方法1 :针对负数-3.125,首先考虑其绝对值3.125,其符号位和整数部分5bit数据为:5'b00011,小数部分为0.125量化的结果为:

>> dec2bin(round(0.125*2^3),3)
ans =
001

所以,绝对值3.125量化8bit的结果为:8'b00011001

因为是负数,需要求其补码,求补码:按位取反再加1,

得到:8'b11100111,

方法2 :8bit能够表示的最大的数据是2^8,量化后的二进制数据中包含3位小数位,计算过程中需要修正,使用公式如下:

> > dec2bin(round(2^8-abs(-3.125)*2^3),8)
ans =
11100111

得到量化后的结果为:8'b11100111。

5、ISE中使用float-point 核

将32bit的整数1234567890转化为双精度的浮点数。

调用floating-point-IP核并配置参数

图片

输入的定点数据选择自定义模式;设置为32bit整数位 - 0bit小数位,表明输入数据只要整数位没有小数位。图片

设置转化后的浮点数为double 型;

图片

后面的设置- 保持默认 -- 点击 Generate图片

verilog代码实现如下:

module signed_2_floating(
input      wire                     sclk,
input      wire                     rst_n,
input     signed  [31:0]            data_in,
input      wire                     valid_in,
output     wire  [63:0]             floating_data,
output     wire                     valid_out


  );
reg  signed [63:0]                  floating_data_temp;
reg                                 valid_out_tmp;
// IP 核信号      
reg               data_in_tvalid;
wire              data_in_tready;
wire              result_dout_tvalid;


reg               result_dout_tready;
wire  [63:0]      result_dout_tdata;  
assign     floating_data      =      floating_data_temp;
assign      valid_out         =      valid_out_tmp ;
// data_in_tready 由IP核拉高---valid_in信号有效时--触发data_in_tvalid-开始启动计算 
always@(posedge sclk or negedge rst_n)                 
begin
  if(~rst_n)  begin
     data_in_tvalid    <=   1'b0;
  end
  else if(data_in_tready  &&  valid_in )  begin     
     data_in_tvalid   <=    1'b1;            
  end    
  else
  begin
     data_in_tvalid    <=   1'b0;
  end
end
// result_dout_tvalid - 信号由IP核输出--当检测到result_dout_tvalid 有效以后,用户端的ready信号再拉高
always@(posedge sclk or negedge rst_n)
begin
  if(~rst_n)
  begin
    result_dout_tready   <=  1'b0;
  end
  else if(result_dout_tvalid)           
  begin
    result_dout_tready   <=  1'b1;         
  end
  else
  begin
    result_dout_tready   <=  1'b0;           
  end
end
 // result_dout_tready 信号 和 result_dout_tvalid 信号都有效,开始读取数据。
always@(posedge sclk or negedge rst_n)
begin
  if(~rst_n)
  begin
    floating_data_temp    <=   64'd0;
    valid_out_tmp         <=   1'b0;    
  end
  else if(result_dout_tready && result_dout_tvalid)      
  begin
    floating_data_temp    <=    result_dout_tdata;
    valid_out_tmp         <=    1'b1;    
  end
  else
  begin
    floating_data_temp    <=    floating_data_temp;
    valid_out_tmp         <=     1'b0;        
  end
end


fixed_2_floating       floating_instance_name (
  .aclk(sclk),                                                // input aclk
  .s_axis_a_tvalid(data_in_tvalid),                           // input s_axis_a_tvalid
  .s_axis_a_tready( data_in_tready ),                         // output s_axis_a_tready
  .s_axis_a_tdata(data_in ),                                  // input [31 : 0] s_axis_a_tdata
  .m_axis_result_tvalid(result_dout_tvalid),                  // output m_axis_result_tvalid
  .m_axis_result_tready(result_dout_tready),                  // input m_axis_result_tready
  .m_axis_result_tdata(result_dout_tdata)                     // output [63 : 0] m_axis_result_tdata
);
endmodule

仿真结果展示:

图片

验证结果:

>> a=double(1234567890)
a =
   1.2346e+09
 >> num2hex(a)
ans =
41d26580b4800000

在Matlab中,将定点数转化为浮点数的结果和ISE中调用IP核计算的结果一致。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 二进制
    +关注

    关注

    2

    文章

    705

    浏览量

    41250
  • C语言
    +关注

    关注

    180

    文章

    7530

    浏览量

    128618
  • 十进制
    +关注

    关注

    0

    文章

    62

    浏览量

    13028
  • 浮点数
    +关注

    关注

    0

    文章

    58

    浏览量

    15792
  • 数据类型
    +关注

    关注

    0

    文章

    227

    浏览量

    13496
收藏 人收藏

    评论

    相关推荐

    浮点数定点数

    本帖最后由 gk320830 于 2015-3-5 23:17 编辑 数制,浮点数定点数的文档,上数电时老师给的。有兴趣的同学可以来看看
    发表于 03-27 21:31

    【安富莱——DSP教程】第7章 DSP定点数浮点数(重要)

    第7章DSP定点数浮点数(重要) 本期教程主要跟大家讲解一下定点数浮点数的基础知识,了解这些基础知识对于后面学习ARM官方的DSP库大有裨益。特别是初学的一定要理解这些基础知识。
    发表于 06-03 11:47

    第7章 DSP定点数浮点数

    表达是基于二进制的。从上面的表达式,我们可以知道,二进制数同样可以有小数点,也同样具有类似于十进制表达
    发表于 09-22 13:02

    功能函数中的浮点数转换为定点数

    第16章 DSP功能函数-数据拷贝,数据填充和浮点定点本期教程主要讲解功能函数中的数据拷贝,数据填充和浮点数转换为定点数。目录第16章 DSP功能函数-数据拷贝,数据填充和
    发表于 08-17 07:37

    定点数浮点数的区别是什么

    的傅里叶变换后的数据,那么,选择正确的处理方式时,首先要解决的是定点数浮点数的问题。如果使用过单片机的同学,一定会知道定点运算和浮点运算两个概念
    发表于 02-21 07:22

    功能:双字节十六进制定点数转换成格式化浮点数

    功能:双字节十六进制定点数转换成格式化浮点数 入口条件:双字节定点数的绝对值在[R0]中,数符在位1FH中,整数部分的位数在A中。
    发表于 01-19 22:45 2938次阅读

    在FPGA里浮点数定点数表示法原理展示

    浮点数定点数表示法是我们在计算机中常用的表示方法 所以必须要弄懂原理,特别是在FPGA里面,由于FPGA不能像在MCU一样直接用乘除法。 首先说一下简单的定点数定点数是克服整
    发表于 11-18 02:15 8450次阅读
    在FPGA里<b class='flag-5'>浮点数</b>与<b class='flag-5'>定点数表</b>示法原理展示

    单片机浮点数运算的源码设计

    单片机执行程序的过程,实际上就是执行我们所编制程序的过程。即逐条指令的过程。本文详细介绍了浮点数在单片机中的表示方式和汇编子程序,浮点数定点数加减法要困难,但是克服了定点数表示范围小
    的头像 发表于 03-07 15:19 9542次阅读
    单片机<b class='flag-5'>浮点数</b>运算的源码设计

    Xilinx怎么定点数浮点数

    转化为的浮点数可以是单精度也可以是双精度。
    发表于 07-05 08:09 3736次阅读
    Xilinx怎么<b class='flag-5'>定点数</b>转<b class='flag-5'>浮点数</b>

    浮点数在内存中的存储

    浮点数在内存中的存储和整数不同,因为整数都可以转换为一一对应的二进制数据。而浮点数的存储是由符号位 (sign) + 指数位 (exponent) + 小数位 (fraction) 组
    的头像 发表于 09-20 10:52 3754次阅读
    <b class='flag-5'>浮点数</b>在内存中的存储

    定点数浮点数在STM32单片机中使用傅里叶(FFT)变换的理解

    的傅里叶变换后的数据,那么,选择正确的处理方式时,首先要解决的是定点数浮点数的问题。如果使用过单片机的同学,一定会知道定点运算和浮点运算两个概念
    发表于 12-24 19:22 16次下载
    <b class='flag-5'>定点数</b>和<b class='flag-5'>浮点数</b>在STM32单片机中使用傅里叶(FFT)变换的理解

    PLC中浮点数二进制表示

    我们日常使用的各类数据,都是以二进制的方式存储的。以浮点数为例,在PLC中其表示方式使用了IEEE 754标准。许多编程语言中浮点数的实现也遵循该标准。
    的头像 发表于 03-23 13:50 3537次阅读
    PLC中<b class='flag-5'>浮点数</b>的<b class='flag-5'>二进制</b>表示

    单精度和双精度浮点数的区别

    。 单精度浮点数,也称为单精度浮点数格式,用于在计算机中表示32位二进制格式的浮点数。一个单精度浮点数由三个部分组成:符号位、
    的头像 发表于 12-15 10:25 2581次阅读

    modbus浮点数怎么读取

    常重要的。 首先,要理解Modbus浮点数的表示方式。在Modbus协议中,浮点数采用了IEEE 754标准进行编码和解码。IEEE 754标准定义了浮点数二进制表示方法,包括符号位
    的头像 发表于 12-28 14:38 1670次阅读

    一文带你秒懂IEEE 754浮点数

    一、简介1、常见的浮点数表示方式是IEEE754标准,它规定了浮点数的存储格式和运算规则,这个标准定义了两种浮点数表示:单精度和双精度。2、任何一个浮点数
    的头像 发表于 03-18 08:09 898次阅读
    一文带你秒懂IEEE 754<b class='flag-5'>浮点数</b>