定点表示让我们可以在低功耗的整型计算硬件上使用小数。
在低功耗的DSP硬件上表示小数
为了降低设计与实现时的成本,许多数字信号处理器只设计与实现了在整型上的算术运算操作。为了在此类处理器上表示小数,我们可以使用一个隐含的二进制小数点
比如,8位的字符 表示十进制的 当它被解析成一个整数时;然而,我们可以想象a有一个隐含的二进制的小数点(implied binary point),从而将a解析成一个小数
假设这个二进制的小数点在第4位和第5位中间,即 .则可解析成小数:
在上例中,我们用前4位表示整数部分,用后4位表示小数部分。
可以看出,二进制小数点右边第一个bit拥有0.5(2的-1次方)的权重,右边第二个bit拥有0.25(2的-2次方)的权重,依次类推。要注意的是,这个隐式的二进制小数点并没有存储在硬件里。因此,程序员需要设计一个正确的缩放因子(scaling factor)来获得最后想要的结果。在上例中,硬件使用8个存储单元去表示8位的字符。如果程序员希望用这个a表示浮点数5.375,则缩放因子应设置为, 即。
如果将隐式的二进制小数点放在第5位和第6位中间,则, 对应的十进制浮点数为.
The Q Format
根据小数点位置的不同,一个给定的二进制数可以表示不同的十进制浮点数。一般来说,为了编程方便,在整个算法内,我们会使用固定的小数点位置。为了简便地表示多少个位表示整数部分,多少个位表示小数部分,我们使用一种叫Q Format的记法。如果我们使用3位数表示整数部分,4位数表示小数部分,我们会说这个数使用Q3.4的格式。
另一个可能的记法是只单独指明小数部分的位数。前提是我们知道某个特定处理器的字符长度。比如,一个字符长度为16位的处理器,我们使用Q15格式作定点表示的话,实际意味着使用Q1.15格式。
二进制小数点的位置选择
需要考虑两个主要因素:
- 在给定的算法中,我们可能用到的最大的数值
- 能承受的量化误差范围
前一个因素决定了需要用多少位来表示整数部分,后一个因素决定了需要多少位来表示小数部分。
除了需要使用隐式的缩放因子,Q format与普通的在计算机中的数值表示没有区别。所以,我们还可以使用Q format来表示有符号的补码(signed two's complement)。在这种情况下,我们只需要把符号位分配给most significant bit(MSB, 即最左边一位),如果该数是负数则用补码的形式进行表示即可。
Examples of Q Format
Example 1
假设某个使用了浮点运算的算法,在数上有相关操作。现在我们满意该算法在浮点运算上的表现,希望移植到一个低功耗的拥有16位字宽的定点处理器上;则在这个处理器上,该用怎样的Q Format来表示a呢?
因为a的整数部分是在[8, 16], 所以我们需要至少4个位来表示a的整数部分。如果a是有符号数,则还需要在最左边加上一个符号位。所以我们可以用Q5.11的格式来表示a.
在这个格式下,得到的二进制表示解析时需要用到缩放因子. 也就是说,没有隐含二进制小数点的a的Q5.11表示等于a乘以。 因此,获得a的Q5.11表示,只需要乘以,并四舍五入为整数,再将该整数转换为二进制形式。如:
因为a是正数,所以我们只需要将符号位置0。所以该数的Q5.11 format为 . 如果a为负数,则需要先找到a的绝对值并转换为对应的补码表示,再将符号位置1.
Example 2
假设是一个有符号数的Q2.2 format表示。则对应的a的十进制数值是什么?
由于符号位为1, 对应的十进制数值是a补码表示的补码即, 则
符号位扩展
当对两个有符号数做加法时,两个数可能拥有不同的长度。 这时需要把较短的数的符号位进行扩展,否则得到的结果是不对的。
比如,把的符号位扩展两位,则得到. 为什么这样扩展是正确的呢?我们知道在正数的左边添加0不会影响该数的数值,负数情况下呢?
为了理解负数情况的符号位扩展不会改变数值本身,我们需要记得,在补码表示里,一个负数的定义是跟补码常数息息相关的。K bits的数,补码表示的补码常数是.
比如,4比特位的数,补码常数为. 而一个4比特位的数b的补码为. 让我们看下怎么用6比特位来表示这个有符号的4比特位数。
为了用6比特位表示b的补码,补码常数为.则6比特位和4比特位表示之间的差异为 . 所以为了得到6比特位的表示,只需要将4比特位的表示加上 ,或者,等价的,把4比特位的符号位扩展两位。
扩展数的符号位,我们可以只改变补码常数而不改变数值本身。
Q Format加法
对两个Q Format的数作加法,需要首先对齐两个数的小数点位置,再对整数部分更短的数进行符号位扩展,再相加。
Example 3
计算 ; (的补码表示为). (补码表示为).可以看到,a和b为两个有符号数,分别用Q2.2和Q3.3表示。
按照上述规则,a+b:
不考虑隐含的缩放因子,上述加法和两个数的补码表示的加法一样。由于补码表示是基于模M运算的,所以超出符号位的位需要被丢弃。所以,和十进制结果保持一致。需要注意的是,如果没有符号位扩展,得到的结果是不对的。
当我们使用定点表示去进行数值运算时,需要时刻注意给定的Q Format格式所能表示的数值范围。比如,假设我们把用格式的a加上用格式的b.和上述例子类似,我们可以对整数部分更短的数进行符号位的扩展,把相加的结果用表示。 nc=maximum{na,nb}, mc=maximum{ma,mb}.
然后,我们需要知道,这里存在数值溢出的可能。因为两个N-bits的数相加,可能得到(N+1)-bits的结果。用用表示结果,我们需要保证数值溢出没有发生。下面例子描述了这种情况的情形。
Example 4
计算 ; (的补码表示为). (补码表示为).可以看到,a和b为两个有符号数,分别用Q2.2和Q3.3表示。
按照上述规则,a+b:
如果我们丢弃整数部分的第4位,得到 .然而,a和b为两个负数,相加结果却为正数,很明显发生了数值溢出。这是因为Q3.3format能表示的最小数为, 然而上述a+b的结果比还小。
为了回避数值溢出,我们可以把a和b的整数部分都符号位扩展到4比特位。因为两个N-bits的数相加,可能得到(N+1)-bits的结果,所以Q4.3format的结果表示可以避免两个Q3.3format数相加的数值溢出。
Example 5
计算 ; (的补码表示为). (补码表示为).可以看到,a和b为两个有符号数,分别用Q2.2和Q3.3表示。假设加法器可以处理Q4.3format的数值运算。
首先我们需要对齐小数点,因为a和b的整数部分都小于4比特位,我们需要将a和b进行符号位扩展到Q4.3format再进行相加,如下:
丢弃符号位前面的位,得到
用Guard Bits避免溢出
很多数字信号处理器的加法器,输出寄存器的位数会比输入寄存器的位数大几个比特位。这些多出来的比特位称为Guard Bits. Guard Bits允许程序员在不作为的情况下避免数值溢出。可以很容易地证明,拥有n个Guard Bits的加法器,可以保证进行次的加法而不发生溢出。
但是,我们无法无限制地扩大字宽。因此,在我们的计算过程中,我们需要截断或四舍五入我们的结果来满足更短的位宽。这意味着我们需要分配更多的比特位给整数部分来放大我们可以表示的数值范围。换句话说,即时调整二进制小数点的位置。
总结
- 定点表示让我们可以在低功耗的整型硬件上使用小数
- 为了降低设计与实现时的成本,许多数字信号处理器只设计与实现了在整型上的算术运算操作。为了在此类处理器上表示小数,我们可以使用一个隐含的二进制小数点
- 如果我们使用n位数表示整数部分,m位数表示小数部分,我们会说这个数使用Qn.m的格式。
- 当对两个有符号数做加法时,两个数可能拥有不同的长度。 这时需要把较短的数的符号位进行扩展,否则得到的结果是不对的
- 对两个Q Format的数作加法,需要首先对齐两个数的小数点位置,再对整数部分更短的数进行符号位扩展,再相加。
- 当我们使用定点表示去进行数值运算时,需要时刻注意给定的Q Format格式所能表示的数值范围。