csapp Day2 Class4 浮点数-2022.05.13
1.二进制分数的表示
0.1111111->1,用1-ε表示,ε越小,数越接近1
对于固定位数存储浮点数,采取移动小数点的方式进行范围与精度的均衡(浮点的来源)
2.浮点数的表示法
IEEE标准754规定了如今浮点数的存储方式
一个二进制浮点数可表示为$$(-1)^{S} M 2^{E}$$
其中S代表符号位,0为正数1为负数
M为尾数,在规格化浮点数中范围是$[1.0~2.0)$,在非规格化浮点数中范围是$(0,1.0)$
E为阶码,作用是给浮点数加权,权重是2的E次幂
而在实际的浮点数保存中,我们将浮点数的位划分为三个字段,分别为S,exp,frac
exp与frac并非是E与M的值,而是依赖于E与M的值
(1)规格化
规格化指exp的位中同时含有0和1的情况
E与exp的关系为$E=exp-Bias$,Bias被称为偏置,值为$2^ {k-1}-1$,k为exp的位数
引入bias的原因是这样可以用无符号整数对指数进行保存,从而在比较中将两个浮点数看成两个无符号整数进行比较
假设exp是8位,则Bias为$2^ {8-1}-1=127$,这样就产生了指数的表示范围:(-126 ~ +127)(exp在规格化浮点数下范围是(1 ~ 254))
M与frac的关系为$M=1+f$,可以理解为f隐藏了以1作为小数点前第一位从而额外获得了一位精度
例:15213的浮点数表示
(2)非规格化
非规格化指exp为0时,此时$E=1-bias,M=f$,非规格化的浮点数可能的数值分布均匀接近0.0
值得注意的是,当exp于frac均为0时,可以得到+0.0与-0.0,它们在某些方面被认为是不同的,其他方面是相同的
(3)特殊值
当exp全为1时出现特殊值。frac全为0时得到的值为无穷,根据s的值又可以分为正无穷与负无穷。当操作结果溢出或者进行了除以0的操作时就会得到无穷。frac不全为0时的值为NaN,即“不是一个数字“。一些运算的结果不能为实数或无穷,就会返回NaN。例如$\sqrt {-1}$或$\infty-\infty$
3.一个小栗子
我们使用4位exp,3位frac的浮点数进行枚举可能出现的浮点数以探究IEEE标准754的优点
主要注意非规格化浮点数的最大值与规格化浮点数的最小值之间的平滑转变。
0 0000 111 为非规格化浮点数的最大值,此时exp=0,E=1-Bias=1-7=-6,M=frac=$\frac{7}{8}$,值为$\frac{7}{8}*\frac{1}{2^{-6}}=\frac{7}{512}$
0 0001 000 为规格化浮点数的最大值,此时exp=1,E=exp-Bias=1-7=-6,M=frac+1=1+0=1,值为$\frac{8}{8}*\frac{1}{2^{-6}}=\frac{8}{512}$
这种平滑性归功于对非规格化的E的定义
同时还有另一点值得注意:假如把浮点数视为无符号正数,则他们是递增的。IEEE如此设计就是为了使浮点数能够使用整数排序函数进行排序
4.浮点数的舍入
默认舍入方式为"向偶数舍入"或"向最接近的值舍入",在十进制中为四舍六入五成双,而在二进制中,中间值为最高位1其他位为0,舍入时前一位为0则舍,为1则入
5.浮点运算
浮点加法不具有结合性,可能由于精度差距较大或得出特殊值导致交换前后的结果不同
对于数据类型转换,可能会因为舍入导致值的改变
int->float 不会溢出,但是可能发生舍入
int/float->double 能够保留精确数值
double->float 可能发生溢出或舍入
double/float->int 向0舍入,甚至可能发生溢出