DSP数的表示:定点小数Q 格式表示和加法
本文翻译自
https://www.allaboutcircuits.com/technical-articles/fixed-point-representation-the-q-format-and-addition-examples/
定点表示是的我们可以在低开销的整数硬件上使用小数运算。本文首先介绍小数表示方法Q格式,然后给一些定点加法的例子。
在低开销DSP上表示小数
为了降低开销,很多数字信号处理器都设计成只能进行整数算术运算。为了在这些处理器上表示小数,我们可以使用
隐含小数点。
例如,8bit字
a=010101102" role="presentation" style="position: relative;">a=010101102,单被当做整数时表示
8610" role="presentation" style="position: relative;">8610。然而,我们可以假设存在一个隐含的小数点,并把该数理解为一个小数。假设小数点在第4和第5个bit之间,例如,
a=0101.01102" role="presentation" style="position: relative;">a=0101.01102。我们可以通过以下公式得到该数等价的十进制的值:
a=0×23+1×22+0×21+1×20+0×2−1+1×2−2+1×2−3+0×2−4=5.375" role="presentation" style="position: relative;">a=0×23+1×22+0×21+1×20+0×2−1+1×2−2+1×2−3+0×2−4=5.375
在这个例子中,我们用4bit表示整数部分,4bit表示小数部分。
从这个例子我们可以看到,小数点右边第一个bit的系数为0.5,第二个为0.25,以此类推。
需要注意这个隐含的小数点并没有在硬件上表达,程序猿需要假设一个合适的缩放因子来正确的解释计算结果。在上面的例子中,硬件上只存储8bit数
a=010101102" role="presentation" style="position: relative;">a=010101102。如果程序员想要用a表示5.375,就需要记住使用a进行的任何运算结果,都需要乘以一个缩放因子
2−4" role="presentation" style="position: relative;">2−4。
Q格式
小数点位置不同,同一个二进制数可以表示不同的值。为了编程方便,我们通常在同一算法中使用固定的小数点位置。Q格式是用来表达一个二进制数中整数、小数分别有多少bit的一种表示格式。例如,我们用3bit表述整数部分,4bit表示小数部分,则这个数的格式为Q3.4格式。
对于一个字长固定的处理器,另一种可行的表示格式是只表示小数部分。例如,当我们使用一个字长为16bit的处理器的时候,我们可以简单是说我们是使用Q15格式来表示小数。这里的Q15表示小数点右边有15bit,左边有1bit。同时Q15也等效于Q1.15。
小数点位置选择
小数点位置的选取需要考虑两个方面:
第一个方面决定了整数部分需要的bit数,第二个方面决定了小数部分的bit数。
需要注意的是,除了隐含的缩放因子,Q格式的小数与计算机上整数的表示没有任何区别。我们也可以使用Q格式来表示二进制补码。
Q格式举例
例一
假设算法需要用到浮点数
a=9.21695743609119810" role="presentation" style="position: relative;">a=9.21695743609119810。现在该值在浮点表示时算法表现良好。假设我们要用16bit字长的定点硬件来实现该算法,最合适的表示a的Q格式是什么?
因为a的整数部分在8和16之间,因此我们至少需要4bit来表示整数部分。假设我们使用有符号数,那么符号位需要占用以为,即小数点左边有5bit。因此我们使用Q5.11格式。
改格式表示的数的缩放因子为
2−11" role="presentation" style="position: relative;">2−11。也就是说Q5.11形式表示的a对应的去掉小数点后的值等于Q5.11表示的数乘以
211" role="presentation" style="position: relative;">211。因此,为了将a表示为Q5.11格式,我们先将a乘以
211" role="presentation" style="position: relative;">211,对其四舍五入到最接近的整数,然后在将四舍五入结果转换为二进制:
a×211=18876.3288≈18876=100100110111100(2)" role="presentation" style="position: relative;">a×211=18876.3288≈18876=100100110111100(2)
因为a是正数,因此符号位为0,a的Q5.11格式表示为01001.00110111100。对于负数,我们需要首先找到其绝对值的Q格式表示,然后转换为二进制补码,再加上符号位。
例二
假设
a=10.012" role="presentation" style="position: relative;">a=10.012为Q2.2格式的有符号数,其对应的十进制整数是什么?
因为是有符号数,所以十进制数为-1乘以a的二进制补码对应的十进制数。a的二进制补码为
01.112" role="presentation" style="position: relative;">01.112。因此
a=−1.7510" role="presentation" style="position: relative;">a=−1.7510。
符号扩展
在做有符号数加法的时候,加数与被加数长度可能不同,这是,我们需要将较短的数进行符号位扩展。
例如,将
10112" role="presentation" style="position: relative;">10112扩展两位,得到
1110112" role="presentation" style="position: relative;">1110112。对于正数来说,符号位为0,符号扩展即填零,这不会改变数的大小。
对于负数来说,在补码表示中,
一个负数是依据一个互补的常数定义的。kbit的数,这个互补常数为
M=2k" role="presentation" style="position: relative;">M=2k。
对于一个4bit的数,互补常数为
M=24" role="presentation" style="position: relative;">M=24,这时,一个4bit正数b对应的负数-b可以表示为M-b。下面解释如何用6bit表示这个4bit有符号数。
对于6bit数,互补常数为
M′=26" role="presentation" style="position: relative;">M′=26,-b可以表示为
M′−b" role="presentation" style="position: relative;">M′−b。因此,-b的6bit表示和4bit表示的差为:
(M′−b)−(M−b)=M′−M=26−24=01100002" role="presentation" style="position: relative;">(M′−b)−(M−b)=M