计算机中机器数的类型:定点数(整数)与浮点数(小数)
本文内容参考自王达老师的《深入理解计算机网络》一书
<中国水利水电出版社>中国水利水电出版社>
一、计算机中一共有两种机器数类型:
- 1、定点数
定点数又细分为两类:定点整数,定点小数:- ⑴、定点整数
定点整数是小数点固定在有效数值部分最低位之后的定点数,等于就是纯整数了,如,一个定点整数是n位二进制,那么它的最高位是符号为,所以它能表达的数值范围为:-(2n-1-1)<=X<=2n-1-1。例如一个8位的定点整数,除了最高位表示符号位外,能具体用于表示数值的剩下7位,所以它的最大值是0 ,即127,等于27-1,所能表示的最小值为1 ,即-127,等于-(27-1)。 - ⑵、定点小数
定点小数是小数点位置固定在符号位之后,有效数最高位之前的定点数,是纯小数,如一个定点小数是n位,它的最高位同样是符号位,则它所能表示的数值范围为:-(1-2-(n-1))<=X<=1-2-(n-1)。例如一个8位的定点小数,除了符号位外,用于表示真值的共7位,由此可以得出它所能表示的最大值为0.,即0.5+0.25+0.125+0.0625+0.03125+0.015625+0.0078125=0.(从这里你也能看出来,为什么机器数的表示是有限的。实际上,你看到这里,你马上就能知道,按照这种方式,你无法用机器数表示出0.!因为每一步的叠加都是通过1/2n-1实现的)。等于1-2-7,所能表示的最小值为1.,即-0.,等于-(1-2-7)。
经验之谈
一个n位连续为1的正二进制整数的值是2n-1(n-1是因为最高位是符号位)。
一个n位连续为1的负二进制整数的值是-2n-1(n-1是因为最高位是符号位)
一个n位连续为1的整二进制小数的值是1-2-n,不再需要将每位转换成十进制再相加,直接1-2-n就行,同理,一个n位连续为1的负二进制小数 的值是-(1-2-n)。 - ⑴、定点整数
- 2、浮点数
我在上文中已经分析了,计算机中二进制如果要表示即有整数又有小数的定点数(这里称为定点数的意思就是在存储器中固定一位,让它表示”.”)不可能像书写十进制小数那样方便(意思就是表示中不可能包括”.”),实际上的解决办法还是需要通过0和1来表示,但是表示方法需要换一下,说直白一些,我们实际使用的表示即有整数又有小数的二进制表示法不包括”.”,计算机可以通过实际的表示确定小数点的具体位置,其实就是”浮点数法”–这种表示法很灵活,可以表示任何小数,同时也充分利用的计算机的字长,表示的范围也比定点法扩大好多倍,实际应用起来没有一点问题。
这里通过实际的举例来说明”浮点”,比如12.23中”.“是在第3位,1.223中”.“是在第2位,1099.25中”.“是在第5位,看上去,不同的数中这个”.“是不是位置不同,浮来浮去的?所以我们很形象地把实际中用来表示即有整数部分又有小数部分的定点数的表示法称为”浮点”。于是乎,即有整数部分又有小数部分的数直接就称为”浮点数”了。
那么,计算机中是如何灵活地来表示一个浮点数的呢?
我们知道,在十进制数中,比如123.45用科学计数法可以表达为1.2345 * 22,其中1,2345为尾数,10为进制基数,2为指数,尾数和指数均为十进制表示,如果是负数,在前面加一个”-“就行。
如果需要将以上内容整理成一个通式表达的话,尾数用M表示,指数用E表示,那么十进制数N的表达通式是:
N = M * 10E;
按照以上的思路可以得出二进制的表达通式为:
N = M * 2E(只需要换进制基数就行,将10换成2)。
但是二进制的表达通式中,尾数M必须是二进制原码格式,指数E也必须是二进制原码格式,E在十进制中称”指数”,但是在二进制通式中称为”阶码”(IEEE 754中是用移码表示)。
最后一点需要强调的是,浮点数在计算机存储器中存储的格式可以是原码格式,也可以是补码格式,但通常都是补码格式,因为补码格式方便正负数的运算。
我们再来仔细观察一下这个表达通式:
:N = M * 2E
之前直接在存储器中像存储十进制小数一样存储二进制浮点数的方式已经被证明不灵活以及非常受限。那么还有什么办法?
通过再次对以上通式的观察,我们可以发现,一个浮点数只要知道了它的符号位,指数和尾数,就可以根据以上的通式反推出它的实际值,所以最终的解决办法就是在存储器中分别存数浮点数的符号位,指数位和尾数位,不同的标准对符号位,指数位和尾数为规定的存储位数不同,我们来讨论IEEE 754标准。
通过表格图示符号位(S),指数(E),尾数(M)的存储顺序:符号位 S 指数位 E 尾数位 M 指数位E的形式实际上就是一个定点整数(纯整数),可以通过它推算出浮点数的小数点位置,所以它也间接决定了浮点数的表示范围,M的形式实际上就是一个定点小数(纯小数),它表示了浮点数的有效值,决定了浮点数的精度(精度说白了就是小数点保留几位)。指数E为正时,表示转换后尾数部分的小数点比原数的小数点位置左移了E位(用十进制举例,更直观,比如123.4变成1.234 * 102,那么1.234的小数点相比123.4左移了2位,二进制也是一个意思,只是进制基数为2),指数E为负时,表示转换后尾数部分的小数点与原数的小数点位置右移了E位。
如一个浮点数为-0.10101 * 211,则它在16位字长的存储器(假设规定E用4位表示,M用11位表示,S符号位占1位)中的存储格式如下表格:符号位 S 指数位 E 尾数位 M 1 0011 通过以上的分析,我们发现了,实际上所有的浮点数都可以通过移动小数点来变成一个纯小数和一个指数的乘积,同时,为了规范起见,规定机器数的浮点数表达形式中尾数的最高有效位(即小数点右边第一位)不能为0,必须为1,也就是说,不要出现0.00 * 2这种情况!
把所有不满足小数点右边第一位必须为1的浮点数变成满足要求格式的过程称为浮点数的规格化处理(实际上就是通过小数点的以为和修改指数来实现)。
在IEEE 754标准中,把浮点数分成了单精度和双精度两种,同时规定了单精度浮点数长度为32位(4字节),双精度浮点数为64位(8字节)。
IEEE 754标准中,E和M都是用补码表示,而不是原码,因为补码方便计算。
这里又有一个问题需要说明,我们都知道,指数E是可以为负的,这样可能导致一个浮点数中出现两个符号位(浮点数自身和浮点数指数的),这样的结果会导致在比较两个浮点数大小时比较麻烦,那么这种问题如何解决呢?
实际中的解决办法是,可以在指数的基础上加上一个固定的正数(这个正数是无符号的正数,就是说,它所有的二进制位都是它的真值,它没有符号位!),保证指数一定是正的(加的这个正数是固定的)!这种操作在IEEE 754中称为偏移,得到的结果称为”移码”。所以,用移码表示能确保指数部分均为无符号的正数,正数的原码和补码完全一致,不用转换。
下表提供单精度浮点数和双精度浮点数各部分在存储器中的结构浮点数类型 符号所在位(S) 指数所在位(E) 尾数所在位(M) 偏移值(固定的正数) 单精度浮点数 31(1) 30-23(8) 22-0(23) 127(对应二进制位:0) 双精度浮点数 63(1) 62-52(11) 51-0(52) 1023(对应二进制位:0) 以上表中的指数E是以”移码”格式表示的,所以IEEE 754 中用于浮点数中小数点位置的移码 = 原指数 + 偏移值。如果用e来表示原来的指数,则有如下关系式:
e = E + 偏移值
总结:在计算浮点数时可以用以下公式统一表示:X = S(1.M) * 2E-偏移值,其中X为浮点数原码,S为符号位,M为尾数,E为移码表示,”E-偏移值”就等于原指数。
PS:可能有的人会异或,为什么是1.M。因为这是格式化,所有的浮点数都可以通过移动指数来格式化,比如二进制的0.1 = 1.0 * 2-1,0.00101 = 1.01 * 2-3。统一了格式便于理解和计算!
在此,再次感谢王达老师的《深入理解计算机网络》一书对本文的启发!
PS:时间有限,有关计算机基础的内容会持续更新!今天就先写这么多,如果有疑问或者有兴趣,可以加:,并注明CSDN,我会就博文中有疑义的问题做出解答。同时希望博文中不正确的地方各位加以指正!
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/216677.html原文链接:https://javaforall.net
