计算机中的浮点数(一)
这篇文章介绍了计算机系统中浮点数的正式定义,关于浮点数的介绍总共分两篇文章,这是第一篇。
计算机中的浮点数
浮点数的一般表示方式:N=(m,e)
在计算机中,一个以β为底(radix/base),以e为指数(exponent),有m个有效数字(significand/mantissa)的浮点数N用下面这种形式表示:
或者写成下面的形式:
例如,数12.345如果用以10为底,有效数字为5的浮点数来表示可以表示成下面这个样子:
其中:
β是底也叫进制,这个数由系统自身决定,例如上面的例子中就是以10为底的系统。但在计算机系统中则是以2为底。
e是指数,表示底的幂次。也就是浮点数小数点的位置,比如上面的例子,我在下面把“点”给画出来了
-3就表示只需把小数点往前移三位就能得到实际数N。
m是有效数字部分(有些地方叫“尾数”)。
因此,一但系统的进制被确定以后,例如,二进制系统,β=2,那么浮点数N只需通过(m,e)这两个参数就能表示。或者说,N是m和e这两个自变量的函数。
浮点数的正式定义(相对正式):N=(M,e)
一个有限长度的,按照下列方式定义的浮点数N,被4个整数所限定:
这四个数分别是:
1,底/基数(radix or base) 。
2,精度(precision) ,它表示的是小数点左边和右边有效位数字的总位数。
3,最小指数。
4,最大指数,一般而言。且,在IEEE-754标准中,。最小指数和最大指数被称为极限指数(extremal exponents)
其中:
1,M是一个小于的整数,被称为整数有效数字(integral significand)。
2,指数e是一个满足的整数。
相对于前面的一般表示方式,浮点数N只是由β一个整数所限定,一旦β确定后,浮点数就被另外两个参数e和m确定了,也就是上面提到过的用(m,e)来表示N。
在这里,在浮点数的正式定义中,浮点数N由4个整数β,p,emin和emax限定。一但这四个数被确定后(也是由于系统自身决定的),浮点数N就可以由M和e来表示了,在这里N变成了M和e的函数,即通过(M,e)来表示N。
浮点数的一般表示方式 | 浮点数的正式定义 | |
由系统所预先设置的整数 | β | β,p,e_min,e_max |
根据实际数自行调整的整数 | m,e | M,e |
By the way,如果把浮点数的正式定义改写成如下的形式:
这里的被称之为量子(quantum),他代表了一个单位浮点数能表示的最小变化,量子越小,浮点数能表示的数值变化就越精细。 q被称之为量子指数(quantum exponent)。
下面通过一个例子来看看浮点数的正式定义究竟是怎么回事?同样是用浮点数的标准定义来表示12.345这个数,分两种情况来讨论。
较高的精度,较窄的指数范围:
首先,把四个用于限定浮点数表示范围的数设置好β=10(还是用十进制来表示),p=10(12.345共5个数,因此,在不损失有效数字的情况下,精度至少要大于5),相当于是我在有效数字位数的基础上又多个给了5位精度,但指数e的范围给的很小e_min=-2,e_max=3。 M的范围是由p限制的,根据定义M的绝对值要小于等于。
表示方式1:
如果我们希望用M=12345来表示(12345<9999999999满足要求),可以先把N表示成如下形式:
这样一来-3=e-10+1,得到e=6,,不能满足对指数的要求,这说明M不能用这个值。
表示方式2:
如果用M=12345000<9999999999来表示,则:
这时,-6=e-10+1,得到e=3,,能满足对指数的要求,这也是当前指数范围内所能表示的最小的M了,即,M=12345000。
表示方式3:
如果我们希望用M=1234500000<9999999999来表示,则:
这时,-8=e-10+1,得到e=1,,能满足对指数的要求。这是该系统中,大M能够满足条件且指数e不超过限制的最大M了,即,M=1234500000。
在上面的例子中,我的精度给的比较高,指数范围比较窄。能够被正常表示的M从12345000(e=3)~1234500000(e=1),在表示12.345这个数的时候没丢失精度,且有较大的余量。可见,用(M,e)来表示浮点数的方式并不是唯一的。值得一提的是,由于M必须是整数,因此,这里我们不能让M=1.2345,虽然他也小于9999999999。就本例而言,在不损失有效数字的情况下,M至少也得是12345。这些多种多样的表示方式被称为同类(cohort)。
较低的精度,宽泛的指数范围:
p=6,只多给1位精度,指数e的范围e_min=-7,e_max=8。M的范围是由p限制的,根据定义M的绝对值要小于等于。
表示方式1:
如果我们希望用M=12345来表示(12345<999999满足要求),可以先把N表示成如下形式:
这样一来-3=e-6+1,得到e=2,,能满足对指数的要求。
表示方式2:
如果我们希望用M=12345000来表示(12345000>999999不满足要求)。
表示方式3:
如果我们希望用M=123450来表示(123450<999999满足要求),则:
这样一来-4=e-6+1,得到e=1,,能满足对指数的要求。
可见,在当前系统设定下,能够被正常表示的M只能从12345(e=2)~123450(e=1),小于上面的实验,且系统所给的较宽的指数范围也被浪费了。
比较好的精度和指数范围:
私以为,较好的精度和指数范围应该是能够充分利用指数范围的精度。因此,对于需要被表示的数,需要摸索以找到指数范围和精度之间的trade-off。在IEEE 754(2008)中就有明确的定义,应该说这一规定是很多科学家深思熟虑后的决定,具有里程碑式的意义:
浮点数正式定义的另一种表示: N=(s,m,e)
1,,他不再像M一样一定是一个整数,而是一个仅包含一个整数位和p-1个小数位的小数。其中,,m被称为正常有效数字(normal significand)。
2,,表示N的符号位
3,e仍然表示指数
例子:
还是用12.345来举例,对于前面提到的较高的精度,较窄的指数范围,β=10(还是用十进制来表示),p=10,e_min=-2,e_max=3,基于m的限制,12.345能表示成下面这个样子。
e=1,e在给定的指数范围内。
同样的,对于较低的精度,宽泛的指数范围,p=6,e_min=-7,e_max=8,12.345也能表示成下面这个样子:
e=1,也在给定的指数范围内。
这里我们注意到,m是一个大于等于0,同时小于10的数。因此,对于12.345实际上还存在另外一种表示方式:
对于p=10,e_min=-2,e_max=3,,12.345还能表示成下面这个样子。
e=2,e在给定的指数范围内。
对于p=6,e_min=-7,e_max=8,:
e=2,也在给定的指数范围内。
这说明在浮点数的正式定义中,不论是前面的(M,e)表示法,还是这里的(s,m,e)在表示数N的时候都不是唯一的。
常规数与相对少见的数normal and sub-normal numbers
在前面的正式定义中我们已经看到了,对于同一个数而言,既存在不同的(M,e)表示,也存在不同的(s,m,e)表示。这就是表示的多样性与不唯一性,即,同类(cohort)问题。为了让有限个浮点数的表示都是唯一的(这也是人们希望看到的),人们发明/定义了下面这种表示方式,这种表示也被称作标准化表示(normalized representation):
1,把m的范围由之前的调整为,满足这一条件的浮点数表示N被称为常规数(normal number)。
2,如果不是正规数,那么,且指数e必须等于,这样的N被称为相对少见的数(sub-normal number)。sub-normal number常被用于表示一些非常小的数,例如所需表示的数的指数e小于的情况。例如在一个系统中,要表示一个e=-128的数。
如此一来N的表示就被唯一确定了!
在基数为2的系数中,由于m被限制在之间,normal number有效数字的第一个位一定是1。因此,normal number的有效数字总是具有如下形式:
而subnormal number有效数字的第一个位只能是 0,他的m被限制在。而subnormal number的有效数字总是具有如下形式:
这两种表示方式的共有部分---数字序列“”被称为有效数字的尾数(trailing significand),在有的地方也被称为小数部分(fraction)。此外,如果我们能够找到一种方法(这种方法通常在指数部分实现),可以告诉我们一个数是常规数normal number还是相对少见的数sub-normal number,就不需要存储其有效数字的第一位。这种不保存有效数字第一位的方法被称为隐含位约定(leading bit convention/implicit bit convention/hidden bit convention)。
到此为止,我通过一些例子来回顾一下上面提到正规数表示和非正规表示。在一个标准化2进制系统中,精度p=24,和。
例一,用常规数normal number的表示方式来表示:
1,符号位
是一个正数,所以符号位s=0。
2,化分数为小数
3,把十进制小数转换为二进制小数
将小数部分不断地乘以 2 依次得到:
0.3333333333...x2=0.6666666666...,取出整数部分 0,得到二进制小数部分的第一个数。
0.6666666666...x2=1.3333333333...,取出整数部分 1,得到二进制小数部分的第二个数。
0.3333333333...x2=0.6666666666...,取出整数部分 0,得到二进制小数部分的第三个数。
依此类推,最终得到0.33333...的二进制表示(下标的10和2表示进制):
4,规范化表示
基于常规数表示对m的要求,m需要符合。因此,上述二进制小数可以表示成1.xxxxx...的形式:
这样一来便得到了指数e = -2。
5,在给定的精度p=24范围内,对的二进制表示进行截取,取前24个有效数字
如果把这个截断后的二进制数返还到十进制,我们就会发现被截断后的已经变成了:
最终数在2进制中的正规数为:
例二,用相对少见的数sub-normal number的方式来表示()
根据sub-normal number的规定:,且指数e必须等于。
1,符号位
是一个正数,所以符号位s=0。
2,-128<-126说明这个数足够小,可以用sub-normal number来表示。令e==-126,得到:
3,转换为二进制
得到m=0.11
4,sub-normal number的最终表示
以下是一些关于浮点数特殊值的定义:
1,最小的正常规数(the smallest positive normal number)
2,最小的正的相对少见的数(the smallest positive sub-normal number)
3,最大的有限浮点数(the largest finite floating-point number)
(全文完)
--- 作者,松下J27
参考文献(鸣谢):
1,《Handbook of floating-point arithmetic》 ,second edition, Jean-Michel Muller
2,《Elementary Functions Algorithms and Implementation》,Jean-Michel Muller
3,https://en.wikipedia.org/wiki/Floating-point_arithmetic#IEEE_754:_floating_point_in_modern_computers
4,https://en.wikipedia.org/wiki/Single-precision_floating-point_format
5,https://en.wikipedia.org/wiki/Double-precision_floating-point_format
版权声明:所有的笔记,可能来自很多不同的网站和说明,在此没法一一列出,如有侵权,请告知,立即删除。欢迎大家转载,但是,如果有人引用或者COPY我的文章,必须在你的文章中注明你所使用的图片或者文字来自于我的文章,否则,侵权必究。 ----松下J27
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)