# 浮点数的表示

浮点数分为阶码和尾数部分,一个浮点数可表示为-0.10101*2^

其中阶码可以分为阶符和阶码的数值部分,尾数可以分为数符和尾数的数值部分,如上面的例子

- 为数符,0.10101 为尾数数值部分,+ 为阶符,11011 为阶码数值部分

阶码:常用补码或移码表示的定点整数

尾数:常用原码或补码表示的定点小数

阶码 E 反映浮点数的表示范围及小数点的实际位置;尾数 M 的数值部分的位数 n 反映浮点数的精度

尾数给出一个小数,阶码指明了小数点要向前 / 向后移动几位

# 规格化浮点数的特点

浮点数尾数的规格化:

规格化浮点数:规定尾数的最高数值位必须是一个有效值

左规:当浮点数运算的结果位非规格化时要进行规格化处理,将尾数算数左移一位,阶码减 1

右规:当浮点数运算的结果尾数出现溢出 (双符号位 01 或 10) 时,将尾数算数右移一位,阶码加 1

注:采用双符号位,当溢出发生时,可以挽救

  • 用原码表示的尾数进行规格化:尾数的最高数值位必须是 1

    • 正数为 0.1xxxxxx 的形式,其最大值表示为 0.11......11,最小值表示为 0.10...00。尾数的表示范围为12M(12n)\frac{1}{2}\le M\le(1-2^{-n})
    • 负数为 1.1xxxxxx 的形式,其最大值表示为 1.10......00,最小值表示为 1.11...11。尾数的表示范围为-(1-2^{-n})\le M\le -\frac{1}
  • 用补码表示尾数进行规格化:尾数的最高数值位必须和尾数符号位相反

    • 正数为 0.1xxxxxx 的形式,其最大值表示为 0.11......11,最小值表示为 0.10...00。尾数的表示范围为12M(12n)\frac{1}{2}\le M\le(1-2^{-n})
    • 负数为 1.0xxxxxx 的形式,其最大值表示为 1.01......11,最小值表示为 1.00...00。尾数的表示范围为-1\le M\le -\frac{1}{2}+2^

# IEEE 754

移码:补码的基础上符号位取反。注意:移码只能表示整数

移码定义:移码 = 真值 + 偏置值,8 位移码的编制值 = 128D=10000000B,即2^

类型数符阶码尾数数值总位数偏置值
短浮点数 (float)182332十六进制:7FH;十进制:127
长浮点数 (double)1115264十六进制:3FFH;十进制:1023
临时浮点数 (long double)1156480十六进制:3FFFH;十进制:16383

IEEE 754 标准:阶码部分用移码表示,尾数部分用源码表示,隐藏表示最高位 1

阶码真值 = 移码 - 偏移量,msm_s 位数符,EE 为阶码部分,MM 为尾数数值位

规格化的短浮点数的真值为:(-1)^s\times1.M\times2^

规格化的长浮点数的真值为:(-1)^s\times1.M\times2^

例:将十进制 - 0.75 转换为 IEEE 754 的单精度浮点数格式表示

(-0.75)_{10}=(-0.11)_2=-(1.1)_2\times2^

数符 = 1 尾数部分.10000....(隐含最高位 1)

阶码真值 - 1,单精度浮点数偏移量 = 127D,移码 = 移码真值 + 偏移量 = 1+1111111=01111110(凑足 8 位)

IEEE 754 单精度浮点数最小绝对值、最大绝对值:

  • 最小绝对值:尾数全部为 0,阶码真值最小 1-127=-126,对应移码机器数 0000 0001,此时整体真值为(1.0)_2\times2^

  • 最大绝对值:尾数全部为 1,阶码真值最大 127,对应移码机器数 1111 1110,此时整体真值为(1.111...1)_2\times2^

  • 阶码最小为 - 128,最大为 127,但是 - 128(全 1)和 - 127(全 0)用来做特殊用途,因此在计算式不适用这两个阶码

双进度浮点数最小绝对值:1.0×210221.0\times2^{-1022},最大绝对值:1.11..1\times2^{1023}=(2-2^{-52})\times2^

单精度浮点数:

  • 只有1E2541\le E\le 254 时,真值 =(-1)^s\times1.M\times2^

  • 当阶码 E 全为 0,尾数 M 不全为 0 时,表示非规格化小数:\pm(0.xxxx)_2\times2^

  • 当阶码 E 全为 0,尾数 M 全为 0 时,表示真值±0\pm0

  • 当阶码 E 全为 1,尾数 M 全为 0 时,表示无穷大±\pm\infin

  • 当阶码 E 全为 1,尾数 M 不全为 0 时,表示非数值 "NaN"(Not a Number)

# 浮点数的运算

  • 对阶:使两个数的阶码相等,小阶向大阶看齐,尾数每右移一位,阶码加 1
    • 求阶差判断那个数阶码为小阶
    • 对阶
  • 尾数相减:通常采用双符号位表示尾数,这样可以挽救尾数溢出
  • 规格化:左规 | 右规
  • 舍入
    • 0 舍 1 入法:类似于十进制数运算的四舍五入法,即在尾数右移时,被移去的数值位为 0,则舍去;被移去的数值为 1,则在尾数的末尾加 1。这样做完可能会使尾数溢出,此时需要再做一次右规
    • 恒置 1 法:尾数右移时,不论丢掉的数值位是 1 还是 0,都使右移的尾数末尾恒置 1。这种方法同样有使尾数变大和变小的两种可能
  • 判溢出
    • 阶码上溢:抛出异常 (中断)
    • 阶码下溢:按机器 0 处理

强制类型转换:

char->int->long->double、float->double 没有精度损失

int->float 会损失精度,float->int:可能溢出及损失精度