计算机处理的数值数据多数带有小数,小数点在计算机中通常有两种表示方法,一种是约定所有数值数据的小数点隐含在某一个固定位置上,称为定点表示法,简称定点数;另一种是小数点位置可以浮动,称为浮点表示法,简称浮点数。
1. 浮点数表示法
计算机中的浮点数(float)表示方法类似科学计数法,通过选取一定位数用来表示阶数,因此浮点数就由符号位,阶码和尾数组成。根据IEEE 754标准,计算机中半精度,单精度和双精度浮点数的尾数结构如下表:
浮点数类型 | 总位数 | 符号位 | 阶码 | 尾数 | 阶码标准值 |
半精度 | 16 | 1 | 5 | 10 | 15 |
单精度 | 32 | 1 | 8 | 23 | 127 |
双精度 | 64 | 1 | 11 | 52 | 1023 |
符号位0代表整数,1代表负数自然不必多说,需要注意的是浮点数不采用补码表示法。
由于科学计数法中有效位部分总位1.xxxxx所以IEEE 754规定,浮点类型的最高位总为1,既然总为1,自然可以省去不写,所以浮点数的有效位数比实际占用bit数大1,因此单精度浮点数可以保存24位有效数字,只不过最高位总是1.
对于阶码,情况就比较复杂,阶码表示的是指数部分,科学计数法中指数可以为正也可以为负,因此对阶码取一个中间值作为标准值,每次都与该值做差得到实际的指数,比如单精度浮点数中阶码为8位,表示范围为0-256,取127作为标准值。然后指数还有三种情况要分开考虑:
1. 阶码不全为0或不全为1。这时,浮点数就采用上面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。
2. 阶码全为0。这时,浮点数的指数E等于1-127(或者1-1023),有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。
3. 阶码全为1。这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s);如果有效数字M不全为0,表示这个数不是一个数(NaN)。
举个例子:9.0用float存储的二进制形式是怎样的?
首先,浮点数9.0等于二进制的1001.0,即1.001×2^3。
那么,第一位的符号位s=0,有效数字M等于001后面再加20个0,凑满23位,指数E等于3+127=130,即10000010。
所以,写成二进制形式,应该是s+E+M,即0 10000010 001 0000 0000 0000 0000 0000。
2. 定点数表示法
所谓定点格式,即约定机器中所有数据的小数点位置是固定不变的。在计算机中通常采用两种简单的约定:将小数点的位置固定在数据的最高位之前,或者是固定在最低位之后。一般常称前者为定点小数,后者为定点整数。
定点小数是纯小数,约定的小数点位置在符号位之后、有效数值部分最高位之前。若数据 x 的形式为 x = x0.x1x2…xn ( 其中x0为符号位,x1~xn是数值的有效部分,也称为尾数, x1为最高有效位 ),一般说来,如果最末位 xn = 1,前面各位都为 0 ,则数的绝对值最小,即 |x|min = 2-n 。如果各位均为 1,则数的绝对值最大,即 |x|max =1-2-n 。所以定点小数的表示范围是:
2- n ≤ | x | ≤ 1 - 2- n
定点整数是纯整数也就是计算机中的整形,约定的小数点位置在有效数值部分最低位之后。若数据 x 的形式为 x = x0 x1x2…xn ( 其中x0为符号位,x1~xn 是尾数, xn 为最低有效位 ),定点整数的表示范围是:
1≤ | x | ≤ 2n - 1
人们对定点数的需求还远不止定点整数和定点小数这两种情况,在一些嵌入式系统中还会约定更多的小数位置,和更灵活的定点数位宽,因此,当我们求解一个定点数的数值时,需要知道的数据就包括,定点位宽,有无符号,整数部分位宽。
3. 定浮点数转换
有一些DSP芯片中没有浮点数计算的硬件部分,有时还需要将浮点数与定点数进行相互转换。由于目前业务中仅涉及到浮点数转定点数,因此这里仅介绍浮点数与定点数的转换。
参考libfixmath采用一种相对简单的方法对浮点转定点进行了实现,假设目标定点数的定点位宽为w,整数位宽为f:
a. 由于c语言中没有半精度浮点型,对于半精度浮点型我们首先要根据符号位、阶码和尾数将其解析为单精度类型,对于单精度和双精度则可以直接处理。
b. 然后对得到的浮点数乘以2^(w-f),这样就可以将我们需要保留的小数位数转为整数部分,为了提高转换后的精度,对乘积结果需要进行四舍五入,对于乘积为正的直接加上0.5,乘积为负的减去0.5,然后再取整,这样就可以使我们转换后的结果误差最小。
c. 再将乘积强转为int就得到了我们需要的定点数的扩展形式,
d. 最后对强转后的结果取低(w-1)位,并补充符号位在其最高位,这样就得到了我们所需的定点数。