购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.1 数的表示

3.1.1 莱布尼茨与二进制

在德国图林根州著名的郭塔王宫图书馆(Schlossbiliothke zu Gotha)保存着一份弥足珍贵的手稿,其标题为“1与0,一切数字的神奇渊源,这是造物主的秘密美妙的典范,因为,一切无非都来自上帝。”这是德国通才大师莱布尼茨(Gottfried Wilhelm Leibniz,1646—1716,见图3-1)的手迹。但是,关于这个神奇美妙的数字系统,莱布尼茨只有几页异常精练的描述。用现代人熟悉的表达方式,我们可以对二进制进行以下解释。

图3-1 莱布尼茨(1646—1716)

2的0次方=1

2的1次方=2

2的2次方=4

2的3次方=8

2的4次方=16

2的5次方=32

2的6次方=64

2的7次方=128

……

以此类推,把等号右边的数字相加,就可以获得任意一个自然数,或者说任意一个自然数均可以采用这种方式进行分解。我们只需要说明的是采用了2的几次方,而舍掉了2的几次方。二进制的表述序列都从右边开始,第一位是2的0次方,第二位是2的1次方,第三位是2的2次方,……,以此类推。采用2的次方的位置,我们就用“1”来标志,舍掉2的次方的位置,我们就用“0”来标志。例如,对于二进制数11100101,根据上述表示方法,可以很容易推算出序列所表示的数值。

在这个例子中,十进制数229就可以表述为二进制数11100101。任何一个二进制数的最左边的一位都是1。通过这个方法,用1~9和0这十个数字表述的自然数都可用0和1这两个数字来代替。0和1这两个数字很容易被电子化:有电流就是1,没有电流就是0。这就是整个现代计算机技术的根本秘密所在。

1679年,莱布尼茨写了题为“二进制算术”的论文,对二进制进行了充分的讨论,并建立了二进制的表示及运算。随着电子计算机的广泛应用,二进制进一步大显身手,因为电子计算机是用电子元件的不同状态来表示不同数码的。如果要用十进制就要求元件能准确地变化出10种状态,这在技术上是非常难实现的。二进制只有两个数码,只需要两种状态就能实现,这正如一个开关只有“开”和“关”两种状态。如果用“开”表示0,“关”表示1,那么一个开关的两种状态就可以表示一位二进制数。由此我们不难想象,5个开关就可以表示5位二进制数,这样运算起来非常方便。

3.1.2 定点数表示法

1.定点数的定义

几乎所有的数字计算机,包括FPGA在内的数字信号处理器件,数字和信号变量都是用二进制数来表示的。数字使用符号0和1来表示,其中,二进制数的小数点将数字的整数和小数部分分开。为了与十进制数的小数点区别,本书使用 Δ 来表示二进制数的小数点位置。例如,十进制数11.625可表示为1011 Δ 101。二进制数的小数点左边的四位1011表示整数部分,小数点右边的三位101表示小数部分。对于任意一个二进制数来说,均可由 B 个整数位和 b 个小数位组成,如式(3-1)所示。

其对应的十进制数大小 D

给出,其中, a i 的值均为1或0。最左端的位 a B -1 称为最高位(Most Significant Bit,MSB),最右端的位 a -b 称为最低位(Least Significant Bit,LSB)。

表示一个数的一组数字称为字,而一个字包含的位的数目称为字长。字长的典型值是一个为2的幂的正整数,如8、16、32等。字的大小经常用字节(Byte)来表示,一个字节有8个位。

定点数是指小数点在数中的位置是固定不变的二进制数。如果用 N 个比特表示正小数 η ,则正小数 η 的取值范围为

在给定 N 的情况下,正小数 η 的取值范围是固定的。

在数字处理中,定点数通常把数限制为-1~1,把小数点规定在符号位和数据位之间,而把整数位作为符号位,分别用0、1来表示正、负,数的本身只有小数部分,即尾数。这是由于经过定点数的乘法后,所得结果的小数点位置是不确定的,除非两个乘数都是小数或整数。对于加法运算来说,小数点的位置是固定的。这样,定点数 x 可表示为

式中, a B -1 为符号位; B 为数据的位宽,表示寄存器的长度为 B 位。定点数在整个运算过程中,要求所有运算结果的绝对值不超过1,否则会出现溢出。但在实际问题中,运算的中间变量或结果有可能超过1,为使运算正确,通常对运算过程中的各数乘以一个比例因子,以避免溢出现象的发生。

2.定点数的三种表示方法

定点数有原码、反码及补码三种表示方法,这三种表示方法在FPGA设计中使用得十分普遍,下面分别进行讨论。

1)原码表示法

原码表示法是指符号位加绝对值的表示法。如前所述,FPGA中的定点数通常取绝对值小于1,也就是说小数点通常位于符号位与尾数之间。符号位通常用0表示正号,用1表示负号。例如,二进制数( x 2 =0 Δ 110表示的是+0.75;( x 2 =1 Δ 110表示的是-0.75。如果已知原码各位的值,则它对应的十进制数可表示为

反过来讲,如果已知绝对值小于1的十进制数,那么应该如何转换成 B 比特的二进制数原码呢?利用MATLAB提供的十进制整数转换成二进制数的函数dec2bin()很容易获取转换结果。由于dec2bin()函数只能将正整数转换成二进制数,这时转换的二进制数的小数点位于最后,也就是说转换后的二进制数也为正整数,因此对绝对值小于1的十进制数用dec2bin()函数转换之前需要做一些简单的变换,即需要先将十进制小数乘以一个比例因子2 B -1 ,并进行四舍五入操作取整。转换函数的表达式为

需要说明的是,十进制整数转换成二进制数时存在量化误差,其误差大小由二进制数的位数决定,这也是3.2节将要详细阐述的问题。

2)反码表示法

正数的反码与原码相同。将负数的原码除符号位外的所有位取反,即可得到负数的反码。例如,十进制数-0.75的二进制原码表示为( x 2 =1 Δ 110,其反码为1 Δ 001。

3)补码表示法

正数的补码、反码及原码完全相同。负数的补码与反码之间有一个简单的换算关系,即补码等于反码在最低位加1。例如,十进制数-0.75的二进制原码为( x 2 =1 Δ 110,反码为1 Δ 001,其补码为1 Δ 010。值得一提的是,如果将二进制数的符号位定在最右边,即二进制数表示整数,则负数的补码与负数绝对值之间也有一个简单的运算关系,即将补码当成正整数,补码的整数值+原码绝对值的整数值=2 B 。还是上面相同的例子,十进制数-0.75的二进制原码为( x 2 =1 Δ 110,反码为1 Δ 001,其补码为1 Δ 010。补码1 Δ 010的符号位定在最末位,且当成正整数1010 Δ ,十进制数为10,原码1 Δ 110的符号位定在最末位,且取绝对值的整数0110 Δ ,十进制数为6,则10+6=16=2 4 。补码最重要的特性是可将减法用加法运算实现。同样,将十进制数转换成补码形式的二进制数也可以利用dec2bin()函数完成。转换函数的表达式为

原码的优点是乘除法运算方便,无论正负数,乘除法运算都一样,并以符号位决定结果的正负号;若做加法,则需要判断两个数的符号是否相同;若做减法,则还需要判断两个数的绝对值的大小,而后用大数减小数。补码的优点是加法运算方便,无论正负数均可直接相加,且符号位同样参与运算,如果符号位发生进位,那么把进位的1去掉,余下的即结果。

3.1.3 浮点数表示法

1.浮点数的定义及标准

浮点数是属于有理数中某特定子集的数的数字表示,在计算机中用来近似表示任意某个实数。具体来说,这个实数由一个整数或定点数(尾数)乘以某个基数的整数次幂得到,这种表示方法类似于基数为10的科学记数法。

一个浮点数 A 可由两个数 m e 来表示,即 A = m × b e 。在这种表示方法中,我们选择一个基数 b (记数系统的基)和精度 B (使用多少位来存储)。 m (尾数)是 B 位二进制数。如果 m 的第一位是非0整数,则 m 称为规格化后的数据。一些数据格式使用一个单独的符号位( s 代表“+”或“-”)来表示正负,这样 m 必须是正的。 e 在浮点数据中表示基的指数。这种设计可以在某个固定长度的存储空间内表示定点数无法表示的更大范围的数。此外,浮点数表示方法通常还包括一些特别的数值,如+∞和-∞(正、负无穷大),以及NaN(Not a Number)等,正(负)无穷大用于数太大(小)而无法表示的时候,NaN则表示非法操作或无法定义的结果。

大部分计算机采用二进制( b =2)的表示方法。位是衡量浮点数所需存储空间的单位,通常为32位或64位,分别被称为单精度和双精度。有一些计算机可提供更大的浮点数,如Intel公司的浮点运算单元Intel 8087协处理器,以及集成了该协处理器的其他产品,可提供80位的浮点数,用于存储浮点运算的中间结果;还有一些系统可提供128位的浮点数(通常用软件实现)。

在IEEE 754标准之前,业界并没有一个统一的浮点数标准。很多计算机制造商都设计了自己的浮点数规则及运算细节。当时,实现的速度和简易性比数字的精确性更受重视。这种情况给代码的可移植性造成了障碍。直到1985年,Intel公司打算为它的8086微处理器引进一种浮点数协处理器的时候,聘请了美国加州大学伯克利分校的William Kahan教授——最优秀的数值分析家之一,来为8087 FPU设计浮点数格式。William Kahan教授又找来了两个专家来协助他,于是就有了KCS组合(Kahn、Coonan and Stone),并共同完成了Intel的浮点数格式设计。

Intel的KCS浮点数格式如此出色,以致IEEE决定采用一个非常接近KCS的方案作为IEEE的标准浮点数格式。IEEE于1985年制定了二进制浮点数运算标准(Binary Floating-Point Arithmetic)IEEE 754,该标准限定指数的底数为2,同年被美国引用为ANSI标准。目前,几乎所有计算机都支持该标准,这大大改善了科学应用程序的可移植性。考虑到IBM System/370的影响,IEEE于1987年推出了与底数无关的二进制浮点数运算标准IEEE 854,同年该标准也被美国引用为ANSI标准。1989年,国际标准组织IEC批准IEEE 754/854为国际标准IEC 559:1989。后来经修订后,标准号改为IEC 60559。现在,几乎所有的浮点处理器完全或基本支持IEC 60559。

2.单精度浮点数据格式

IEEE 754标准定义了浮点数的存储格式,包括部分特殊值的表示(无穷大和NaN)。同时,IEEE 754标准给出了对这些数值进行浮点操作的规定,它也制定了4种取整模式和5种例外(Exception),包括何时会产生例外,以及具体的处理方法。

在IEEE 754标准中规定了4种浮点数的表示格式:单精度(32位浮点数)、双精度(64位浮点数)、单精度扩展(≥43位,不常用)、双精度扩展(≥79位,通常采用80位进行实现)。事实上,很多计算机语言都遵从了这个标准,包括可选部分。例如,C语言在IEEE 754标准发布之前就已存在,现在它能完美支持IEEE 754标准的单精度和双精度运算,虽然它早已有另外的浮点实现方式。

单精度(IEEE Single-Precision Std.754)浮点数据格式如图3-2所示。

图3-2 单精度浮点数据格式

符号位 s (Sign)占1bit,0代表正号,1代表负号;指数位 E (Exponent)占8bit,其取值范围为0~255(无符号整数),实际数值 e = E -127,有时 E 也称为移码,或者不恰当地称为阶码(阶码实际应为 e );尾数位 M (Mantissa)占23bit, M 也称为有效数字位(Significant)、系数位(Coefficient),甚至被称为小数。在一般情况下, m =(1. M 2 ,使得实际的作用范围为1≤尾数<2。为了对溢出进行处理,以及扩展对接近0的极小数值的处理能力,IEEE 754标准对 M 进行了一些额外规定。

0值:以指数位 E 、尾数位 M 全零来表示0值。当指数位 s 变化时,实际存在正0和负0两个内部表示,其值认为都等于0。

E =255、 M =0时,用作无穷大(或Infinity、∞)。根据符号不同,又有+∞、-∞。

NaN:当 E =255、 M 不为0时,用作NaN(Not a Number,不是数的意思)。

浮点数所表示的具体值可用下面的通式表示,即

式中,尾数1. M 中的1为隐藏位。

需要特别注意的是,虽然浮点数的表示范围及精度与定点数相比有很大的改善,但浮点数毕竟也是以有限的32bit来反映无限的实数集合的,因此大多数情况下都是一个近似值。表3-1所示为单精度浮点数据与实数之间的对应关系。

表3-1 单精度浮点数据与实数之间的对应关系

3.一种适合FPGA处理的浮点数格式

与定点数相比,浮点数虽然可以表示更大范围、更高精度的实数,但是在FPGA器件中实现时需要占用成倍的硬件资源。例如,加法运算,两个定点数直接相加即可,浮点数的加法却需要更为繁杂的运算步骤。

对阶操作:比较指数大小,对指数小的操作数的尾数进行移位,完成尾数的对阶操作。

尾数相加:对对阶后的尾数进行加(减)操作。

规格化:规格化有效位并根据移位的方向和位数修改最终的阶码。

这一系列操作不仅需要成倍地消耗FPGA内部的硬件资源,也会成倍地降低系统的运算速度。对于浮点数乘法操作来说,一般需要以下的操作步骤。

指数相加:完成两个操作数的指数相加运算。

尾数调整:将尾数 M 调整为1. M 的补码格式。

尾数相乘:完成两个操作数的尾数相乘运算。

规格化:根据尾数运算结果调整指数位,并对尾数进行舍入截位操作,规格化输出结果。

浮点数乘法器的运算速度主要由FPGA内部集成的硬件乘法器决定。如果将24位的尾数修改为18位的尾数,则可在尽量保证运算精度的前提下最大限度地提高浮点数乘法运算的速度,同时可大量减少所需的乘法器资源。大部分FPGA芯片内部的乘法器均为18bit×18bit,2个24位数的乘法操作需要占用4个18bit×18bit的乘法器,2个18位数的乘法操作只需要占用1个18bit×18bit的乘法器。IEEE标准中尾数设置的隐藏位主要是考虑节约寄存器资源,而FPGA内部具有丰富的寄存器资源,如果直接将尾数表示成18位的补码格式,那么可去除尾数调整的运算,也可以减少一级流水线操作。

根据FPGA内部的结构特点定义一种新的浮点数格式,如图3-3所示,其中 E 为8位有符号数(-128≤ E ≤127); M 为18位有符号小数(-1≤ f <1)。自定义浮点数所表示的具体值为

图3-3 一种适合FPGA实现的浮点数格式

为便于数据规格化输出及运算,规定数值1的表示方法为指数为0,尾数为01_1111_1111_1111_1111,数值0的表示方法为指数为-128,尾数为0。这种自定义的浮点数格式与单精度数格式的区别在于:自定义的浮点数格式将原来的符号位与尾数位合成18位补码格式的定点数,表示精度有所下降,却可大大节约乘法器资源(由4个18bit×18bit的乘法器减少到1个),并有效地减少运算步骤及提高运算速度(由二级18bit×18bit乘法运算减少到一级运算)。表3-2所示为自定义浮点数与实数之间的对应关系。

表3-2 自定义浮点数与实数之间的对应关系 PdSiiyqWhbzwaHFmkxjKhmsyPalBc/dN8F1o5KrU8RzHXCxSB5mN1oh+YXgvfPGv

点击中间区域
呼出菜单
上一章
目录
下一章
×