Q格式数据(定点小数)

本文介绍Q格式数据,也叫定点小数相关知识。

Q格式数据在MCU,FPGA,定点DSP经常出现,因为这些场合受限于速度,性能,运算能力都不适合做浮点数运算,但有时又会涉及到小数的运算,这时就需要用到Q格式数据,也就是经过缩放的小数,即定点小数。

1.原理

定点小数其实就是用整数来表示按比例缩放后的小数。和我们通常为了用整数表示0.123,进行放大10^2倍,用123这个整数来进行表示是一个道理,只是在计算机中数据通常采用二进制,这里的缩放是2^n而已。

通常我们用Qn来表示定点小数,n代表小数的个数,如Q15,Q8,Q10,分别表示有15个bit,8个bti,10个bit来表示小数,相应的缩放比例分别为:32768,256,1024。如果我们用的是int32_t的数据来表示的话,那么相应的整数部分(补码)就包括:17个bit,24个bit,22个bit。

另外,也有其他资料用Qm.n来对定点小数进行表示,其中m表示整数的个数(不包含符号位),n表示小数的个数,共需要m+n+1位来表示这个数据,多的1位用来表示符号位。如:Q0.15,Q11.20。

注意:

1)小数的位数决定了分辨率,而整数部分位数决定了数据的表示范围

2)如果表示的数据是无符号数,整数部分表示的范围会有所不同

2.范围

这里为了计算方便,我们用n来表示Q格式数据的总位数,m来表示小数的位数。这样,

整数部分位数:n-m

小数部分位数:m

1)有符号数

整数部分范围:-2^(n-m-1) to 2^(n-m-1)-1

小数部分范围:0 to 1-2^(-m)

这样,总的范围为:

-2^(n-m-1) to 2^(n-m-1)-2^(-m)

2)无符号数

整数部分范围:0 to 2^(n-m)-1

小数部分范围:0 to 1-2^(-m)

这样,总的范围为:

0 to 2^(n-m)-2^(-m)

3.分辨率

分辨率与小数的位数有关,分辨率为(m为小数个数):1/2^m

分辨率需要综合考虑整数的表示范围及实际情况(数据精度)进行设定。

例:

Q8格式数据分辨率为:1/2^8=0.003

Q10格式数据分辨率为:1/2^10=0.001

Q20格式数据分辨率为:1/2^20=0.000001

4.运算

1)加法:需转换成相同的Q格式才能相加,如2个Q7格式才可以相加

2)减法:需转换成相同的Q格式才能相减,如2个Q7格式才可以相减

3)乘法:不同Q格式的数据相乘,相当于Q值相加,即Q7数据乘以Q6数据后的结果为Q13格式的数据,如果赋值给一个Q10格式的数据则需要右移2位

4)除法:不同Q格式的数据相除,相当于Q值相减

5)左移:相当于Q值增加

6)右移:相当于Q值减少

5.溢出与舍入

在进行运算时需要考虑溢出,即2个数据运算后的大小有没有超过赋予的变量值。舍入需要考虑进行缩放后的数据是直接截断还是四舍五入。

6.技巧

1)对于运算过程中溢出问题,如相乘,相除,可以考虑将数据归1化(除以最大值),并采用最多小数位数的Q格式进行表示,因2个数都小于1,相乘,除都不会导致数据溢出。

2)数据在Q格式化过程中可以巧妙的利用移位操作,加快运算速度。如1.234,用Q16格式数据进行表示为:80871/65536,也可以:80871 >> 16。

7.例子

1)2个数据相加:

y=a+b

其中:a=1.358,b=12.386

y=1.358+12.386=13.744

采用int16_t的Q10数据进行处理:

a'=1.358*2^10=1391(这里进行四舍五入)

b'=12.386*2^10=12683(这里进行四舍五入)

y'=1391+12683=14074

y'的实际值需要除以2^10,为:14074/2^10=13.7441

可见,运算过程中其实是有一定的误差的

2)2个数据乘:

y=a*b

其中:a=1.358,b=12.386

y=1.358*12.386=16.820188

采用int16_t的Q10数据进行处理:

a'=1.358*2^10=1391(这里进行四舍五入)

b'=12.386*2^10=12683(这里进行四舍五入)

y'=1391*12683/2^10=17229(这里进行四舍五入)

y'的实际值需要除以2^10,为:17229/2^10=16.825

总结,本文介绍Q格式数据及相关运算。

你可能感兴趣的:(MCU,mcu,fpga)