- 我又来复习了
- 上篇二进制那么多阅读量,,,小心脏怦怦跳,,,
- 后来发现我最后的复习计划也被列到目录中了,,,大概是这个原因吧
浮点数与科学记数法
- 之前讲过的定点整数,只是对整数的一种存储,诸如3.14这种只能存成314,之后那就要想办法存下“小数点在最高位3和次高位1之间”这个信息
- 放心吧,计算机怎么也不会真正的保存小数点
科学记数法就发挥了很大的作用
十进制下科学记数法,就是将一个数表示成
number=a?10n
- 这种形式,并且对a做限定
1<=|a|<10
- 比如
3.14=3.14?100
314=3.14?102
- 如此一来,相当于默认了小数点位于a的最高位和次高位之间,那么只要存下了a*10^n也就不需要存小数点了
- 问题?为什么要乘10?
- 比如一个数字3.14,
3.14?10=31.4
31.4?10=314
314?10?1=31.4
看看看,小数点在运动哦~就酱
二进制下有点不同
number=b?2n
0<=|b|<1
- 比如(除了2之外都是用二进制表示)
10.01=0.1001?22
- 还可以乘别的数来表示,比如
10.01=0.1001?41
只不过4的指数每变化1小数点就要移动2格
- 这种对b的规范,默认了小数点的位置
- 进一步,如果默认了乘的数就是2的话,那么需要存储的只有小数b和指数n了,我们叫这个乘数2为基值
浮点数的格式
- 对于一个有小数部分的二进制数number,我们写出规范化的科学记数法的形式
number=b?2n
0<=|b|<1
- 那么number就可以用b和n两个数来存储,同时默认了两个条件
- n是需要乘的2的指数
- b在0到1之间,也就是说b只能是0.XXX的形式
- 对于n来说,n就是一个整数
- b是0.XXX的形式,那么我们就只需要存储“0.XXX”的“XXX”部分就可以了,这也是一个整数的形式
- 起个规范化的名字,我们称 n 为阶码,称 b 为尾数
- 看图

- 考虑到正负的问题,分别留出一位Es和Ms作为符号位,同样是0代表正数,1代表负数
规范化格式
- 问题又来了?依旧用10.01来举例
10.01=0.1001?22
10.01=0.01001?23
- 也就是说,尽管尾数已经在0到1之间了,我依旧可以移动小数点,再顺势改变一下阶码的值,同一个数存起来就有多种存法
- 于是对于计算机内存储的时候,还需要进一步规格化
- 很简单,你想移动小数点,规格化了之后就让你无法移动小数点
- 即规定:M1必须为1
- 那么10.01就只能存成
0.1001?22
的形式了
浮点数表示的问题
- 但是,这种规格化也带来了另一个问题,那就是在实现规格化的过程中,我们总是想让M1为1,就需要移动小数点,也就需要改变阶码的值
- 问题是,你移动了多少多少位来使得M1为1,但是要改变的阶码的值却超出了阶码的表示范围!!就是说阶码的表示范围是有限的!!
- 这个问题就是浮点数不得不直接面对的问题了,另外尾数的位数限制也是浮点数表示法所固有的精度问题
- 举例,取E1-E3共3位来记录阶值,Es一位记录阶符,M1-M3共3位来记录尾数的绝对值,Ms一位来记录尾符
- 最大值:M1-M3均为1,Ms为0表示正,E1-E3均为1,Es为0表示正,即
MaxValue=0.111?27=1110000
- 最小值,即最大值的Ms取1表示负,即
MinValue=?0.111?27=?1110000
- 规范化表示下最接近零的正数M1取1,M2取0,M3取0,Ms取0,Es取1,E1E2E3均为1,即
ClosestToZero=0.100?2?7=0.00000001
- 规范化表示下最接近零的负数自然就是
ClosestToZero=?0.100?2?7=?0.00000001
- 问题就是:
IEEE标准
实体 |
阶码E |
尾数F |
零0 |
全0 |
全0 |
非规格化数 |
全0 |
非全0 |
规格化数 |
[1,254] |
F |
无穷大 |
全1 |
全0 |
非数NaN |
全1 |
非全0 |
- 还记得没编入阶码的 全0 和 全1 吗,这两种状态分别与尾数的全0和非全0组合成了四种特殊情况,分别表示了除了规格化数之外的四种实体,这也使得IEEE在处理浮点数操作的时候变更为灵活
- 非数是Kahan的一个创新,其目的是当浮点运算发生一些特殊情况的时候,软件可以根据NaN的内容进行相应的处理,从而减少了特殊情况下软件处理的工作量
- 非数分为“发信号的非数”Signaling NaN 和“静默的非数”Quiet NaN两类
- “发信号的非数”用于在出现无效运算时发出异常信号
- “静默的非数”只记录发生的特殊请况,而不发出异常信号,比如
(+∞)±(?∞)
0?∞
0/0
负数????√
- 非数的有效部分是尾数,用于区分“发信号”还是“静默”,并可以指明是那种异常情况产生了这个非数,从而可以根据非数的内容进行处理。对于不同异常情况对应的编码标准没有规定,不同的实现方案可以有不同的尾数编码方案。
- 非规格化数也是一种特殊的处理方案,目的是为了避免出现下溢,从而允许用非规格化的形式来表示很小的数,而此时隐藏位就不在是 1 而是 0 了,因为已经不是规格化的范围。这种方案也叫“逐渐下溢(Gradual Underflow)”
计算机组成.运动中的小数点.浮点数
原文:http://blog.csdn.net/stringnewname/article/details/51364425