浮点数运算

588 阅读2分钟

浮点数表示法:

X=M×2rX=M×2^r

其中 M尾数 , r阶码

阶码是定点整数, 决定浮点数的范围

尾数是定点小数, 决定浮点数的精度

IEEE745 标准

如使用 32 位表示单精度(float), 第一位表示 符号位 (注意是浮点数的符号, 不是阶码的符号), 第 2~9 位表示阶码(移码表示), 剩下 23 位表示尾数(原码表示, 若阶码不是 0 , 则省略小数点左边的 1 )

阶码的偏移量是 127

规格化数

Untitled.png

(1)s1.M×2E127(-1)^s1.M×2^{E-127}

尾数由于隐藏位 1 , 因此实际为 24

非规格化数

当阶码为 0, 尾数不为 0 时, 隐藏位为 0

(1)s0.M×2126(-1)^s0.M×2^{-126}

采用 IEEE754 标准单精度浮点数格式表示 45100000H
二进制表示为 0100 0101 0001 0000 0000 0000 0000 0000
第一位为 0 , 表示正数
阶码 1000 1010 其原码需要移码减去 127(0111 1111)1011(十进制11)
尾数存在隐藏 1 , 因此为 1.001...(1.125)
因此结果为 1.125×2^11

IEEE754 标准中移码的规格化, 正数为 0.1... 负数为 1.1...

加减法

阶数相同时, 尾数直接进行加减法

image.png

阶数不相同时

x=0.1101×201x=0.1101×2^{01}y=0.1010×211y=-0.1010×2^{11}, 求 x+yx+y

需要进行如下五步

  1. 对阶

已知 [x]=00,01;00.1101[x]_补=00,01;00.1101[y]=00,11;11.0110[y]_补=00,11;11.0110

注意这里符号位都是两位的...☃️

求出阶差

[Δr]=[rx][ry]=[rx]+[ry]=0001(1)+1101(3)=1110(2)[Δ_r]_补=[r_x]_补-[r_y]_补=[r_x]_补+[-r_y]_补=0001(1)+1101(-3)=1110(-2)

说明 xx 的阶更小, 为了让 小阶向大阶看齐 , 让 xx 的阶加 2, 那么 xx 的尾数就要缩小 222^2 倍, 也就是右移 2

x=00,11;00.0011(010)x=00,11;00.0011(010)

通常移除的部分要保留, 称为 保留附加位 , IEEE754 通常包括 3 位保留附加位, 分别为 保护位 舍入位 粘位 舍入位右边若没有数了, 则粘位为 0

image.png

  1. 尾数运算

因为对阶了, 因此这里和阶数相同时运算法则一致

image.png

  1. 规格化

注意这里是补码得规格化

正数时尾数 00.1...

负数时尾数 11.0... (除了-0.5 , 也就是 11.10....0 )

左规: 将尾数 00.01.... 或者 11.10... 左移一位, 阶码减 1

右规: 将尾数 10.?.... 或者 01.?.... 右移一位, 阶码加 1

image.png

  1. 舍入

末位恒置1 规格化时尾数均加 1

0舍1入 规格化丢失的最高位是 1 则结果加 1

image.png

  1. 溢出处理

image.png

下溢时趋于 0 , 直接当作 0

image.png

乘法

  1. 阶码相加

  2. 尾数相乘

  3. 规范化舍入

除法

  1. 尾数调整

  2. 阶码求差

  3. 尾数相除

  4. 规范化舍入