0%

2.3_浮点数的表示和运算

前置知识

大端存储与小端存储

实际有效字节

大端存储

低地址存储最高有效字节,高地址存储最低有效字节

小端存储

与大端相反,方便机器是因为机器从低往高读

视频讲解:大端与小端

边界对齐

视频讲解:边界对齐

如何将字地址转换成与之对应的字节地址

已知字编号,对应的字节编号就是自编号逻辑左移2位

已知半字编号,对应的字节编号就是半字编号逻辑左移1位

浮点数的表示

浮点数的表示

视频讲解:浮点数表示

浮点数通常表示为:

$ N = r^E * M$

  • r:阶码的底,通常为2
  • E:阶码,反映浮点数的表示范围和小数点的实际位置,用补码或移码表示
  • M:尾数,其位数反映了小数的精度,用原码或补码表示

例:阶码和尾数都用补码表示,求a、b的真值

  • a = 0,01; 1.1001
  • b = 0,01; 0.01001

a:

  • 阶码0,01对应真值+1
  • 尾数1.1001(补码)对应真值(先转换成原码)-0.0111
  • 故 a=-0.111(B)(上面二进制小数点右移1位) = \(-\frac{7}{8}\)

b:

  • 阶码对应真值+1
  • 尾数0.01001对应真值+0.01001
  • 故 b=0.1001=\(\frac{9}{16}\)

浮点数的规格化

视频讲解:浮点数规格化

规格化的种类

左规

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

规定尾数的最高位必须是一个有效值。个人理解,浮点数尾数还是定点小数,表示成0.*******(正数)或者1.******(表示负数),所以符号位后,小数点下一位,也就是第二位不能是0


举例:


右规

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

规格化数的特点

如何判断需要规格化

1. 无论正数负数,原码尾数最高位(就是符号位下一位)必须是1

2. 补码尾数最高位(就是符号位下一位)必须和尾数符号相反,比如正数就是1,负数就是0


举例:


规格化的小数所能表示范围

原码

补码

上溢和下溢


举例:


IEEE754 标准

移码的求法

移码的求法:移码 = 真值 + 偏置值

偏置值常见两种取法,一种取常数 \(2^{n - 1}\),等价于符号位取反

另一种是\(2^{n - 1} - 1,等价于加01111111(一个0和7个1)\)


举例:


注:移码只能表示整数,不能表示小数,所以移码用来表示阶码,因为阶码一定是整数

IEEE754标准下的浮点数表示

视频讲解:IEEE754标准下的移码

尾数前隐含一位1

类型 数阶 阶码 尾数数值 总位数 偏置值
短浮点数 1 8 23 32 7FH(127)
长浮点数 1 11 52 64 3FFH(1023)
临时浮点数 1 15 64 80 3FFFH

对于短浮点数而言,偏置值取127,此时阶码(移码)的表示范围为-126~127

真值 补码 移码
-128 1000 0000 1111 1111
-127 1000 0001 0000 0000
-126 1000 0010 0000 0001
…… …… ……
0 0000 0000 0111 1111
…… …… ……
127 0111 1111 1111 1110

-128和-127的作用:

E=0且 M=0,则真值为0;

E=0且 E≠0 M≠0,为非规格化数,真值 = (-1)^S ×0.M×2^(-126);

E=255且 E≠0 M≠0,真值为‘NaN’(非数值);

E=255且 E=0 M=0,真值为正或负无穷。


例1:十进制小数转单精度浮点数

例2:单精度浮点数转十进制


浮点数的运算

视频讲解

加减运算

步骤

  1. 对阶

  2. 尾数加减

  3. 规格化

  4. 舍入

  5. 判溢出

已知十进制数: \(X = -\frac{5}{256}\) \(Y = +\frac{59}{1024}\)

按机器补码浮点运算规则计算 ( X - Y ),结果用二进制表示,浮点数格式如下:阶符取2位,阶码取3位,数符取2位,尾数取9位。 例子中的浮点数计算过程如下:

  1. 计算X和Y的浮点表示:

X: 阶码: -101(补码为:1011,阶符取两位、阶码取三位:11011) 尾数: -0.101(补码为1.011,数符取两位、尾数取九位:11.011000000)

Y: 阶码: -100(补码为1100,阶符取两位、阶码取三位:11100) 尾数: +0.111011(补码为0.111011,数符取两位、尾数取九位:00.111011000)

  1. 对阶: 计算阶码差:ΔE = 11011 - 11100 = 11011 + 00100 = 11111 (11111为-1的补码) 所以 ΔE = -1 ,X的阶码比Y的阶码小1 阶码每加1,尾数右移一位,则有新的X:11100;11.101100000(右移之后前面补1)

  2. 尾数相加减: -Y: 11100;11.000101000 尾数相加,得:10.110001000

  3. 规格化: 尾数右移一位,阶码加1,得:X-Y=11101;11.011000100

  4. 舍入: 由于无舍入,不需要进行舍入操作。

  5. 判断溢出: 未发生溢出

因此,结果真值为 \(2^{-3} \times (-0.1001111)_2\)

视频讲解

强制类型转换

数据类型 16位机器 32位机器 64位机器
char 8 8 8
short 16 16 16
int 16 32 32
long 32 32 64
long long 64 64 64
float 16 32 32
double 64 64 64

char --> int --> long --> double 以及 float --> double,不会损失精度。

对于32位系统:

  • 整数类型(int)表示整数,范围为 \(-2^{31} \sim 2^{31}-1\),有效数字32位。

  • 浮点数类型(float)表示整数及小数,范围为 \(\pm [2^{-126} \sim 2^{127} \times (2^{-2^{-23}})]\),有效数字为23位尾数加1位整数部分,共24位。

在进行类型转换时:

  • int --> float:可能会损失精度,因为float类型的有效数字比int类型多。

  • float --> int:可能会溢出(超出int表示范围),同时可能损失精度(小数部分被舍弃)。