计算机组成原理——浮点数以及IEEE754
计算机组成原理——浮点数以及IEEE754
整理自up主Beokayy_点击此处看视频课
1. 浮点数
浮点数表示格式
- 通常情况下,浮点数表示为以下格式
- N = ( − 1 ) S × M × R E N = (-1)^S\times M\times R^E N=(−1)S×M×RE
- 数符S:0为正,1为负
- 尾数M:二进制定点小数,原码
- 阶码E:二进制定点小数,移码
- 基数R:隐含,一般可为2,4,16等
浮点数的规格化
- 规格化操作指通过调整一个非规格化浮点数的尾数和阶码的大小,使非零的浮点数在尾数的最高数位上保证是一个有效值。
- 规格化操作:
- 左规:
- 当尾数的最高数位不是有效位,即出现±0.00……的形式时,需要进行左规。
- 对于基数为2的情况,左规时,尾数每左移一位,阶码减1。
- 左规可能要进行多次。
- 右规:
- 当尾数的有效位进到小数点前面时,需要进行右规。
- 对于基数为2的情况,将尾数右移一位,阶码加1。
- 右规只需要进行一次。
- 左规:
- 原码表示的规格化尾数的形式如下:
- 正数为0.1……的形式,最大值为0.11……1,最小值为0.10……0。
- 负数为1.1……的形式,最大值为1.10……0,最小值为1.11……1。
- 基数为 2 n 2^n 2n:
- 规格化数:尾数最高n位不全为0。
- 左规:尾数左移n位,阶码减1。
- 右规:尾数右移n位,阶码加1。
- 请注意,这里提到的规格化和IEEE754的规格化不同。
2. IEEE754标准
IEEE754浮点数的表示格式
类型 | 数符 | 阶码 | 尾数数值 | 总位数 | 偏置值 |
---|---|---|---|---|---|
短浮点数 | 1 | 8 | 23 | 32 | 127 |
长浮点数 | 1 | 11 | 52 | 64 | 1023 |
临时浮点数 | 1 | 15 | 64 | 80 | 16383 |
-
IEEE754标准的浮点数是尾数用采取隐藏位策略的原码表示,且阶码用移码表示的浮点数。
-
IEEE754的阶码使用移码表示,且与普通移码不同的是,IEEE754要求移码的偏置值为 2 n − 1 − 1 2^{n - 1}-1 2n−1−1(机器字长为n)。以短浮点数float为例,偏置值为127;对于长浮点数,偏置值为1023。
-
IEEE754标准中,规格化的短浮点数的真值为 ( − 1 ) S × 1. M × 2 ( E − 127 ) (-1)^S\times1.M\times2^{(E - 127)} (−1)S×1.M×2(E−127);规格化长浮点数的真值为 ( − 1 ) S × 1. M × 2 ( E − 1023 ) (-1)^S\times1.M\times2^{(E - 1023)} (−1)S×1.M×2(E−1023):
- 短浮点数E的取值为1~254,M为23位,共32位。
- 长浮点数的取值位1~2046,M位52位,共64位。
IEEE754浮点数的规格化
- 对于规格化的IEEE754浮点数,数值的最高位总是1。为了使尾数多表示一位有效位,这个1将被隐藏,称为隐藏位。因此,23位尾数实际上表示了24位有效数字。
- 例如,1100规格化后的结果为 1.1 × 2 3 1.1\times2^3 1.1×23(真值),其中整数部分的1将不存储在23位尾数内,故该单精度浮点数的机器数为0 10000010 100……0。
阶码全0和全1时IEEE754浮点数的解释
值的类型 | 符号 | 阶码 | 尾数 | 值 |
---|---|---|---|---|
正零 | 0 | 0 | 0 | 0 |
负零 | 1 | 0 | 0 | 0 |
正无穷大 | 0 | 255/2047 | 0 | ∞ |
负无穷大 | 1 | 255/2047 | 0 | -∞ |
3. 浮点数的加减运算
对阶
- 通过尾数移位使操作数的小数点位置对齐,从而表现使阶码相等。
- 先求阶差,小阶向大阶对齐,将阶码小的尾数右移,每移一位阶码加1,直到两个数的阶码相同为止。
- 尾数右移时,可能会舍弃掉有效位产生误差,影响精度。
尾数求和
- 将对阶后的尾数按定点数加减运算规则进行运算。
规格化
- 注意题目此时要求的浮点数标准(决定了不同的规格化标准),IEEE754规格化尾数的形式为±1.x……x。
- 上一步的尾数求和结束后可能会得到不符合规格化的结果,此时要进行尾数左规或右规进行调整:
- 右规:
- 当结果为±1.x.x……x时,需要进行右规。
- 尾数右移一位,阶码加1。最后一位移出时,需要考虑舍入。
- 左规:
- 当结果为±0.0……01x……x时,需要进行左规。
- 尾数每左移一位,阶码减1,直到第一位1移动到小数点左边第一位。
- 右规:
- 左规一次相当于乘2,右规一次相当于除以2。
- 左规可能进行多次,右规只会进行一次。
舍入
- 上面的对阶和规格化过程中,可能会对尾数进行右移,造成有效位移出的情况。为了保证运算精度,一般会采取不同的舍入策略。
- 0舍1入法:将低位移出的两位保留下来,如果保留位的最高位为0,则舍去;最高位为1,则在尾数的末位加1。后面的操作可能会破坏尾数的规格化,所以需要再次右规调整。
溢出判断
- 尾数溢出时可以通过右规进行调整,所以尾数溢出时结果不一定溢出。
- 只要涉及到右规/左规的操作,都可能导致阶增大/减小,从而使指数发生上溢/下溢,此时判定浮点数发送溢出,产生异常/按机器零处理。
- 浮点数的溢出并不是以尾数溢出来判断的,而是通过指数溢出来判断的。
4. C语言的强制类型转换
(float) (int)
- float能表示的范围大于int,故不会发生溢出。
- int类型为32位,而float的尾数加上隐藏位只有24位,故可能影响精度。
(double) (int/float)
- double能表示的范围大于int或float,故不会发生溢出。
- double类型的有效数位于int或float,故不会对精度产生影响。
(float) (double)
- float能表示的范围小于double,故可能发生溢出。
- float的尾数比double位数少,故可能影响精度。
(int) (float/double)
- int能表示的范围小于float或double,故可能发生溢出。
- int是整数类型,没有小数部分,故数据会向0方向截断,仅保留整数部分,故可能影响精度。