跳至主要內容

3.浮点数的表示和运算


浮点数的表示

1.格式

N=(1)S×M×RE N=(-1)^S\times M\times R^E

  • SS取0或1,决定符号
  • MM是一个二进制定点小数,称为尾数,一般用定点原码小数表示
  • EE是一个二进制定点整数,称为阶码或指数,用移码表示
  • RR为基数

2.表示范围

image.png
image.png

3.规格化

  • 所谓规格化操作,是指通过调整一个非规格化浮点数的尾数科阶码的大小, 使非零的浮点数在尾数的最高数位上保证是一个有效值
  • 尾数MM的绝对值应满足1/RM11\\/R\le|M|\le 1

  • 正数为0.10.1\dots的形式,其表示的最大值为0.111110.111\dots 11,最小值为0.100000.100\dots 00,范围为1/2M(12n)1/2\le M\le(1-2^{-n})
  • 负数为1.11.1\dots的形式,其表示的最大值为1.111111.111\dots11,最小值为1.100001.100\dots00,(12n)M1/2-(1-2^{-n})\le M\le -1/2
  • 当尾数为补码表示,且为1.0××1.0\times \times\dots形式时为规格化数[1]

注意

基数不同,浮点数的规格化形式也不同。当浮点数尾数的基数为2时,原码规格化数的尾数最高位一定是1。当基数为4时,原码规格化形式的尾数最高两位不全为0

浮点数规格化和IEEE754中尾数的关系

  • IEEE754标准中尾数存在一个隐藏位1,这个1实质上就是浮点数规格化中数值位的最高位(即小数点后的一位),小数点前面的一位是符号位,然而在IEEE754中,符号位没有和尾数放在一块,尾数在最后面,这里隐含的是1.M1.M,这个1是隐含的。也就是说浮点数规格化中是纯小数,而IEEE中并不是纯小数,它的整数位有一个1
  • 例如(12)10=(1100)2(12)_{10}=(1100)_2,在IEEE中规格化为1.1×231.1\times 2^3,整数部分的1无需存储,是隐含的,若按照浮点数规格化,则应当是0.110.11
  • 在平时题目中,需要特别注意,题目中到底是常规的浮点数,还是IEEE754标准的浮点数

IEEE754标准

image.png
image.png

阶码

阶码和真值的互换

在IEE754标准中,float的偏置值127(0111 1111),double的偏置值1023(011 1111 1111),所以计算的时候可以根据移码=真值+偏置值\text{移码}=\text{真值}+\text{偏置值},是二进制加减法,其中真值是+111...,-111这种类似的形式,如果不够减的话可以加上282^82112^{11}(我感觉这里就像是无符号减法一样不够减假装向前面借了一位),王道解释大概在五分钟左右open in new window

特殊的阶码

当阶码全0或者全1的时候有特殊用途

移码EE尾数MM真值
全0全0±0\pm 0
全0不全为0±(0.×××)2×2126\pm (0.\times\times\times)_{2}\times 2^{-126}隐含最高位变为0[2],且阶码真值固定视为-126
全1全0±\pm \infty
全1不全为0非数值(NAN)[3]

浮点数的加减运算

1.对阶

  • 小阶向大阶看齐的原则
  • 尾数右移时,舍弃掉有效位会产生误差,影响精度

2.尾数求和

3.规格化

4.舍入

为保证运算精度,一般將低位移出的两位保留下来,参加中间过程的运算,最后将运算结果进行舍入

5.溢出判断

  • 若一个正指数超过了最大允许值(127 或 1023),则发生指数上溢
  • 若一个负指数超过了最小允许值(-126或-1022),则发生指数下滥,通常把结果按机器零处理。

6.类型转换

  1. intfloat,虽然不会发生溢出,但float尾数连隐藏位共 24 位,当int 型数的第24~31非0时,无法精确转换成 24 位浮点数的尾数,需进行舍入处理,影响精度
  2. intfloat 转换为 double时,因double 的有效位数更多,因此能保留精确值
  3. double 转换为 float 时,因float 表示范围更小,因此大数转换时可能会发生溢出。此外, 由于尾数有效位数变少,因此高精度数转换时会发生舍入
  4. float double 转换为 int时,因int没有小数部分,因此数据会向0方向截断(仅保留整数部分),发生舍入。另外,因 int 表示范围更小,因此大数转换时可能会溢出

  1. 这里显示指的是负数的补码,正数的补码和原码一样,还和之前一样 ↩︎

  2. 表示非规格化小数 ↩︎

  3. 用来表示非法运算的结果,如\infty-\infty ↩︎