1、定點(diǎn)數(shù)和浮點(diǎn)數(shù)的概念
定點(diǎn)數(shù),小數(shù)點(diǎn)位置固定不變,參與運(yùn)算的數(shù)據(jù)其小數(shù)點(diǎn)固定的位于所有數(shù)字中間的某個(gè)位置,比如貨幣的表達(dá),規(guī)定了使用2位整數(shù)位+2位小數(shù)表示的模式,具體數(shù)據(jù)如99.00、10.55、68.66等。定點(diǎn)數(shù)的缺點(diǎn):由于小數(shù)點(diǎn)位置固定不變,定點(diǎn)數(shù)所表示的數(shù)的范圍非常有限,不能同時(shí)表達(dá)特別大或特別小的數(shù),所以才出現(xiàn)了浮點(diǎn)數(shù),以此來擴(kuò)充數(shù)的范圍,同時(shí)浮點(diǎn)數(shù)也廣泛應(yīng)用于精度要求高的場(chǎng)合。簡(jiǎn)單的理解浮點(diǎn)數(shù):首先浮點(diǎn)數(shù)小數(shù)點(diǎn)位置不固定,小數(shù)點(diǎn)是浮動(dòng)的,其次浮點(diǎn)數(shù)提供了一種高效的數(shù)據(jù)表達(dá)方法,這種表示方法既可以表達(dá)很小的數(shù)據(jù)比如:3.14159、0.06789,也可以表達(dá)很大的數(shù)據(jù)比如:8.99910^20、510^25。
數(shù)據(jù)在計(jì)算機(jī)中的存儲(chǔ)分為整型(char(8bit)、short(16bit)、int(32bit)、long(32bit)、long long(64bit))和浮點(diǎn)型(float(32bit)、double(64bit)),計(jì)算機(jī)中不可能存儲(chǔ)“無窮大”的數(shù),也不能存放循環(huán)小數(shù)。(注:循環(huán)小數(shù)按照浮點(diǎn)數(shù)的規(guī)則存儲(chǔ)),例如C程序中計(jì)算和輸出1/3:
printf("%f",1/3.0);
得到的結(jié)果是:0.333333,只能得到6位小數(shù),而不是理論計(jì)算的無窮位的小數(shù)。
查看我們?cè)?a href="http://www.socialnewsupdate.com/soft/data/21-24/" target="_blank">C語言課本上學(xué)習(xí)過的知識(shí)點(diǎn):
圖1-1、C語言中的浮點(diǎn)數(shù)數(shù)據(jù)類型
2、浮點(diǎn)數(shù)的結(jié)構(gòu)
通過圖1-1,我們知道單精度浮點(diǎn)數(shù)(float)的取值范圍為:-3.4E38 - -3.4E38,雙精度浮點(diǎn)數(shù)(double)的取值范圍是:-1.7E308 - 1.7E308,精度再高一些表示為:-1.79E308 - 1.79E308。C語言中定義相應(yīng)的浮點(diǎn)數(shù)float和double變量以后,在編譯器的幫助下即可參與相應(yīng)的運(yùn)算,那么浮點(diǎn)數(shù)的內(nèi)部結(jié)構(gòu)又是如何呢?下文將詳細(xì)講解。
float a = 4.5;
double b = 3.5e2,c;
c = a*b;
在IEEE754標(biāo)準(zhǔn)中規(guī)定了浮點(diǎn)數(shù)的表達(dá)方式,浮點(diǎn)數(shù)的存儲(chǔ)方式是以2為底數(shù)的表達(dá)方式。浮點(diǎn)數(shù)的表達(dá)中將數(shù)據(jù)表達(dá)的二進(jìn)制序列分為符號(hào)位,指數(shù)位和小數(shù)位三個(gè)區(qū)域。浮點(diǎn)數(shù)的指數(shù)表達(dá)式如下:
x = (-1) ^s *(1.m)* 2^e;
表達(dá)32bit的浮點(diǎn)數(shù)時(shí)e = E-127;表達(dá)64bit的浮點(diǎn)數(shù)時(shí)e = E-1023,這里的127和1023稱為偏移量。
公式中:
s表示符號(hào)位:正數(shù)為0,負(fù)數(shù)為1;
e表示指數(shù)位:存儲(chǔ)指數(shù)加上偏移量,偏移量是為了表達(dá)負(fù)數(shù)而設(shè)計(jì)的;
m表示小數(shù)部分:存儲(chǔ)小數(shù)部分的準(zhǔn)確值或者接近的值;
注:類比科學(xué)計(jì)數(shù)法,以10為底數(shù)的表示方法中前面的系數(shù)都是小于10 的系數(shù)比如:8.bb*10^(x);以2為底數(shù)的表示方法,前面的系數(shù)都是小于2的系數(shù),比如:1.bb*2^(x),前面還要符號(hào)位(-1)^s。
浮點(diǎn)數(shù)的二進(jìn)制序列表達(dá)式中特定寬度的區(qū)域劃分如下:
圖2-1、不同精度浮點(diǎn)數(shù)特定寬度區(qū)域劃分
3、浮點(diǎn)數(shù)二進(jìn)制序列與指數(shù)表達(dá)式之間的轉(zhuǎn)化
比如10進(jìn)制表示的小數(shù)0.085(我們常說的小數(shù)在計(jì)算機(jī)存儲(chǔ)系統(tǒng)中就是浮點(diǎn)數(shù)),其指數(shù)表達(dá)式為1.36*2^-4,其小數(shù)部分0.36使用了23位來表示。
圖3-1、10進(jìn)制小數(shù)與指數(shù)表達(dá)式的關(guān)系
在Matlab中,將浮點(diǎn)數(shù)轉(zhuǎn)化為16進(jìn)制序列
>> a=single(0.085)
a =
single
0.0850
>> num2hex(a)
ans =
3dae147b
將十六進(jìn)制序列 3dae147b(H)轉(zhuǎn)化為二進(jìn)制序列
001111011010111000010100011110(32bit:1位符號(hào)位+8位指數(shù)位+23位小數(shù)位)
符號(hào)位:0,表示正數(shù);
指數(shù)部分:01111011,12^0+12^1+02^2+12^3+12^4+12^5+1*2^6 = 123;
小數(shù)部分:010111000010100011110,通過表3-1來拆分每個(gè)比特位所表達(dá)的數(shù)值。
第n位 | 2的冪次:2^(-n) | 10進(jìn)制表示 | 求和 |
---|---|---|---|
1 | 1/2-2^(-1) | 0*2^(-1)=0 | 0 |
2 | 1/4-2^-2 | 1*0.25 | 0.25 |
4 | 1/16 | 1*0.0625 | 0.3125 |
5 | 1/32 | 1*0.03125 | 0.34375 |
6 | 1/64 | 1*0.015625 | 0.359375 |
11 | 1/2048 | 1*0.00048828125 | ...... |
13 | 1/8192 | ...... | ...... |
17 | 1/131072 | ...... | ...... |
18 | 1/262144 | ...... | ...... |
19 | 1/524288 | ...... | ...... |
20 | 1/1048576 | ...... | ...... |
22 | 1/4194304 | ...... | ...... |
23 | 1/8388608 | ...... | 0.36000001430512 |
表3-1、小數(shù)部分二進(jìn)制序列拆分
綜上:?jiǎn)尉雀↑c(diǎn)數(shù)0.085,使用指數(shù)表示的結(jié)果為:
(-1)^01.362^-4=1.36*2^-4,其中指數(shù)部分 e=123-127= -4,小數(shù)部分的0.36是23位二進(jìn)制序列所表達(dá)的數(shù)值之和。
3.1、數(shù)據(jù)轉(zhuǎn)化舉例:
問題1: 十進(jìn)制表達(dá)的小數(shù)0.1254,(1)、求64bit雙精度浮點(diǎn)數(shù)的標(biāo)準(zhǔn)16進(jìn)制序列,(2)、用指數(shù)形式表示。
>> a=double(0.1254)
a =
0.1254
>> num2hex(a)
ans =
'3fc00c435bd31c33'
雙精度浮點(diǎn)數(shù)16進(jìn)制序列為:64’h3fc00c435bd31c33
將16進(jìn)制數(shù)展開后,可得二進(jìn)制數(shù)格式為
0011 1111 1100 0000 0000 1100 0100 0011 0101 1011 1101 0011 0001 1100 0011 0011
符號(hào)位: bit[63] ------1位-----0---正數(shù)
指數(shù)部分: bit[62]-[52]------11位--011 1111 1100
指數(shù)部分求解十進(jìn)制結(jié)果:
> > 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,浮點(diǎn)數(shù)的指數(shù)部分?jǐn)?shù)值-減去偏移量,得到實(shí)際指數(shù)表達(dá)式中的指數(shù)為-3。
小數(shù)部分:bit[51]-[0] - 共52bit:
0000 0000 1100 0100 0011 0101 1011 1101 0011 0001 1100 0011 0011
求53bit二進(jìn)制序列所表示的小數(shù):
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
得到浮點(diǎn)數(shù)的指數(shù)表達(dá)式:1.0030*2^(-3)。
驗(yàn)證計(jì)算結(jié)果如下:
>> 1.0030*2^(-3)
ans =
0.1254
Matlab中浮點(diǎn)數(shù)轉(zhuǎn)為十進(jìn)制數(shù):
>> a='3fc00c435bd31c33'
a =
'3fc00c435bd31c33'
>> hex2num(a)
ans =
0.1254
問題2十進(jìn)制表達(dá)的整數(shù)-5,(1)、求32bit單精度浮點(diǎn)數(shù)的標(biāo)準(zhǔn)16進(jìn)制序列,(2)、用指數(shù)形式表示。
>> a=single(-5)
a =
single
-5
>> num2hex(a)
ans =
c0a00000
-5的浮點(diǎn)數(shù)表示為:
1100 0000 1010 0000000000000000000000
符號(hào)位:bit[31] --1位--1--負(fù)數(shù)
指數(shù)位:bit[30]-[23]--8位--10000001
>> 1*2^7+1*2^0
ans =
129
指數(shù)數(shù)值-減去偏移量,得到指數(shù)為:129-127=2
小數(shù)位:bit[22]-[0]-23位:
0100000000000000000000000,
>> 0*2^-1+1*2^-2
ans =
0.2500
所以-5的指數(shù)表達(dá)式為:(-1)1.252^2。
驗(yàn)證計(jì)算結(jié)果如下:
>> -1*1.25*2^2
ans =
-5
4、小數(shù)轉(zhuǎn)化為定點(diǎn)數(shù)
在FPGA 設(shè)計(jì)開發(fā)的過程中,如果需要使用小數(shù)參與相關(guān)運(yùn)算,這個(gè)時(shí)候就需要將小數(shù)轉(zhuǎn)化為定點(diǎn)數(shù),因?yàn)镕PGA內(nèi)部只能處理定點(diǎn)數(shù),不能處理小數(shù),小數(shù)轉(zhuǎn)定點(diǎn)數(shù)的過程需要考慮符號(hào)位-整數(shù)位寬-小數(shù)位位寬。
假設(shè)將小數(shù)2.918量化為16bit的定點(diǎn)數(shù),包含1bit符號(hào)位,3bit整數(shù)位,12bit小數(shù)位。16位數(shù)據(jù)能夠表示的最大正數(shù)為32767(2^15-1),能夠表示的最小負(fù)數(shù)為-32768。
圖4-1、C語言中部分?jǐn)?shù)據(jù)類型對(duì)應(yīng)的取值范圍
3bit整數(shù)位能夠表示的最大整數(shù)是7(3'b111),12位小數(shù)位能夠表示的數(shù)據(jù)的最小精度為:1/(2^12)=0.00024414,也就是說12位小數(shù)位只能表示0.00024414的整數(shù)倍,12位小數(shù)位能夠表達(dá)的最大小數(shù)為:
>> (2^12-1)*0.00024414
ans =
0.9998
可以發(fā)現(xiàn)表示小數(shù)的位數(shù)越多,可以表示的小數(shù)范圍越大,表示的也越精準(zhǔn)。(小數(shù)定點(diǎn)量化過程中使用位寬的大小和數(shù)據(jù)精度的關(guān)系),表示小數(shù)部分0.918,需要的十進(jìn)制數(shù)值為:
>> 0.918/0.00024414
ans =
3.7601e+03
也可以使用Matlab中的函數(shù)完成小數(shù)部分的量化。
>> dec2bin(round(0.918*2^12),12)
ans =
111010110000
>> bin2dec('111010110000')
ans =
3760
所以小數(shù)2.918量化為16bit的定點(diǎn)數(shù)結(jié)果為:16'b0100111010110000
問題 :將浮點(diǎn)數(shù)-3.125量化為8bit的定點(diǎn)數(shù),包含1bit符號(hào)位,4bit整數(shù)位,3bit小數(shù)位。
方法1 :針對(duì)負(fù)數(shù)-3.125,首先考慮其絕對(duì)值3.125,其符號(hào)位和整數(shù)部分5bit數(shù)據(jù)為:5'b00011,小數(shù)部分為0.125量化的結(jié)果為:
>> dec2bin(round(0.125*2^3),3)
ans =
001
所以,絕對(duì)值3.125量化8bit的結(jié)果為:8'b00011001
因?yàn)槭秦?fù)數(shù),需要求其補(bǔ)碼,求補(bǔ)碼:按位取反再加1,
得到:8'b11100111,
方法2 :8bit能夠表示的最大的數(shù)據(jù)是2^8,量化后的二進(jìn)制數(shù)據(jù)中包含3位小數(shù)位,計(jì)算過程中需要修正,使用公式如下:
> > dec2bin(round(2^8-abs(-3.125)*2^3),8)
ans =
11100111
得到量化后的結(jié)果為:8'b11100111。
5、ISE中使用float-point 核
將32bit的整數(shù)1234567890轉(zhuǎn)化為雙精度的浮點(diǎn)數(shù)。
調(diào)用floating-point-IP核并配置參數(shù);
輸入的定點(diǎn)數(shù)據(jù)選擇自定義模式;設(shè)置為32bit整數(shù)位 - 0bit小數(shù)位,表明輸入數(shù)據(jù)只要整數(shù)位沒有小數(shù)位。
設(shè)置轉(zhuǎn)化后的浮點(diǎn)數(shù)為double 型;
后面的設(shè)置- 保持默認(rèn) -- 點(diǎn)擊 Generate。
verilog代碼實(shí)現(xiàn)如下:
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 核信號(hào)
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信號(hào)有效時(shí)--觸發(fā)data_in_tvalid-開始啟動(dòng)計(jì)算
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 - 信號(hào)由IP核輸出--當(dāng)檢測(cè)到result_dout_tvalid 有效以后,用戶端的ready信號(hào)再拉高
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 信號(hào) 和 result_dout_tvalid 信號(hào)都有效,開始讀取數(shù)據(jù)。
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
仿真結(jié)果展示:
驗(yàn)證結(jié)果:
>> a=double(1234567890)
a =
1.2346e+09
>> num2hex(a)
ans =
41d26580b4800000
在Matlab中,將定點(diǎn)數(shù)轉(zhuǎn)化為浮點(diǎn)數(shù)的結(jié)果和ISE中調(diào)用IP核計(jì)算的結(jié)果一致。
-
二進(jìn)制
+關(guān)注
關(guān)注
2文章
807瀏覽量
42315 -
C語言
+關(guān)注
關(guān)注
180文章
7632瀏覽量
141620 -
十進(jìn)制
+關(guān)注
關(guān)注
0文章
67瀏覽量
13545 -
浮點(diǎn)數(shù)
+關(guān)注
關(guān)注
0文章
61瀏覽量
16127 -
數(shù)據(jù)類型
+關(guān)注
關(guān)注
0文章
237瀏覽量
13894
發(fā)布評(píng)論請(qǐng)先 登錄
浮點(diǎn)數(shù)與定點(diǎn)數(shù)
【安富萊——DSP教程】第7章 DSP定點(diǎn)數(shù)和浮點(diǎn)數(shù)(重要)
第7章 DSP定點(diǎn)數(shù)和浮點(diǎn)數(shù)
定點(diǎn)數(shù)和浮點(diǎn)數(shù)的區(qū)別是什么
浮點(diǎn)數(shù)的表示方法

在FPGA里浮點(diǎn)數(shù)與定點(diǎn)數(shù)表示法原理展示

單片機(jī)浮點(diǎn)數(shù)運(yùn)算的源碼設(shè)計(jì)

Xilinx怎么定點(diǎn)數(shù)轉(zhuǎn)浮點(diǎn)數(shù)

浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)

定點(diǎn)數(shù)和浮點(diǎn)數(shù)在STM32單片機(jī)中使用傅里葉(FFT)變換的理解

什么是浮點(diǎn)數(shù)
PLC中浮點(diǎn)數(shù)的二進(jìn)制表示

單精度和雙精度浮點(diǎn)數(shù)的區(qū)別
modbus浮點(diǎn)數(shù)怎么讀取
一文帶你秒懂IEEE 754浮點(diǎn)數(shù)

評(píng)論