浮点数的表示(小数点位置是浮动的)
首先,我们需要知道的是定点数的表示范围的是有限:
例如long long
可以存储
1
0
20
\color{red}{10^{20}}
1020这么大的数据,但是如果数据再更大,这时候long long
就无法存储了,所以定点数存储的范围终究是有限的,要想存储更大的数据只能使用更多的比特位,而浮点数因为采用了不同的存储方式,其存储的范围比较大。
IEE754
浮点数由4部分组成:
1.阶府:存储阶码的符号位 表示阶码为正 1表示阶码为负
2.阶码:存储阶码的数值部分
3.数符:存储尾数的符号位 0表示尾数为正,1表示尾数为负。
4.尾数:存储尾数的数值部分
注:
阶码:常用补码或者移码表示的定点整数。
尾数:常用原码或者补码表示的定点小数。
阶码的底在实现浮点数表示的时候是没有表示出来的,但是题目可能会给出浮点数的真值,让你对阶码进行一个修改。
例如:
N
=
4
E
×
M
\color{red}{N=4^E\times M}
N=4E×M, 请将真值不变的前提下,将阶码改成2
4
是2
的平方,所以只需要让阶码乘2即可:
N
=
2
2
E
×
M
\color{red}{N=2^{2E}\times M}
N=22E×M
阶码的位数和尾数的位数具有什么含义?
阶码E的位数反映浮点数的表示范围以及小数点的实际位置,尾数M的位数表明了浮点数的精度
浮点数尾数的规格化(左规)
所谓规格化:也就是在存储前,需要判断尾数是否满足存储要求,因为浮点数的存储本质是基于科学计数法的,而科学技术法中规定,例如
0.004
\color{red}{0.004}
0.004,根据科学计数法我们需要将其表示为
4
×
1
0
−
3
\color{red}{4\times 10^{-3}}
4×10−3,即我们需要将前面的数的个数变成非0的整数。
在二进制中也是同理,例如要我们存储
0.01001
×
2
2
\color{red}{0.01001 \times 2^2}
0.01001×22这时候我们就需要将其变成
0.1001
×
2
1
\color{red}{0.1001 \times 2^1}
0.1001×21,即在浮点数的存储中是要求小数点的最高位必须是非0整数。
对于左规我们有三种处理方法:
第一种:不管尾数存储的是补码还是原码,先转化成真值,然后看下真值是否满足要求,如果不满足就进行转化,然后再转会对应的原码或者补码。
第二种:如果是原码,无论是正数还是负数,只要尾数的第一位非0,就说明不需要左规了,如果是0,就说明需要左规,几个0就左规几位。
第三种:如果是正数补码,那就和原码一样的处理方式。
如果是负数补码,那么第一位必须是0,如果是1,就需要进行左规,几个1就左规几位。
注意:左规不会导致精度损失,因为是算数左移,并且最左侧去掉的实际上都是真值中的前导0。
浮点数尾数的规格化(右规)
如果说左规是对浮点数的表示形式进行一个修正,那么右规更多的是
浮点数的表示范围
首先浮点数的尾数部分是有范围的,即尾数的最大值和最小值。
通过阶码的最大值搭配尾数的最大值我们就可以得到浮点数的最大范围
通过阶码的最小值搭配尾数的最小值我们就可以得到浮点数表示的最小范围。
其在如果某个数字超过了浮点数超过的最大范围,那么就是正上溢,如果超出了浮点数表示的最小范围,那么就是负上溢。
接着,对于一个正数,如果比这个正数最小能够表示的数字还要小,也就是说超出了这个数字的负上溢,那么我们这个时候又将其叫做正下溢。
我们看一张图:首先,需要知道,尾数的正负决定了真值的正负,而由于浮点数中要求原码的数值位第一位必须为1,那么其表示的最小正数就一定是大于0的,而阶码无论取得多小,即也只能非常靠近0,而无法小于0。所以0到下面的绿色之间的范围就是对应浮点数无法表示的正数范围,其中绿色是能够表示的最小正数。当需要表示的数字处于这个范围时,叫做正下溢。浮点数也是如此,因为浮点数的数值位的第一位必须是1,所以能够表示的最大的尾数肯定是小于0的,无论阶码多大,其也还是小于0,所以蓝色就是该浮点数能够表示的最大负数,蓝色到0之前是无法表示的负数,叫做负下溢。
然后对于超出最大的正数和最小的负数的,也就是正上溢和负上溢。
浮点数的标准
接下来我们看下IEEE标准下的浮点数如何表示:
需要注意,
IEEE标准下是这样规定的:
其中规定了阶码使用移码表示,然后尾数使用原码表示。并且尾数我们需要表示到1.xxxx
其中阶码真值=移码-偏移量。在算真值的时候,将移码和偏移量当作二进制直接进行相减即可,还有一种方法就是先将移码和偏移量当作无符号数看待,然后全部转化成对应的二进制,然后相减。
需要注意的是,原本尾数的最高位为符号位,现在在IEEE标准下,最高位的为数值位了。
原来的符号位变成了阶码部分的最高位。并且需要注意全1和全0作为最小和次小的数一般有特殊用途,所以实际的表示范围,从负数部分需要减2。
这里对于浮点数的表示范围我们看一下:
在IEEE标准下的浮点数的表示范围同样也是具有限制的:
其中落在左侧红线和右侧绿色中的数其实是无法进行表示的。如果我们采用普通的方式。
所以IEEE中进行了一定的优化:之前对于全0和全1的两种移码,我们是没有算进移码的表示范围的,因为全0和全1被特殊规定了:当为全0时,这时候尾数部分就没有存储的要求了,数值位最高可以是,并且没有隐含的1,但是还是0.xxxxx,
并且这时候阶码固定为-126。
需要注意的是,当阶码为全0和全1的时候,就不能通过之前移码的规则进行转化了,例如全1就应该直接解读为8个1对应的无符号整数。全0就解读为移码表示的最小范围对应的负数。