对于二进制小数,小数点之后的数位依然表示2的幂次。整个数的计算同二进制整数:$ \sum_{k=-j}^ib_k\times 2^k $
数字左移和右移对应到 乘 / 除以 2的操作,0.11111111...只比1小一点点,我们用1.0-epsilon表示(这由小数点后有多少位决定)。
只能表示2的幂次之和的数,其他小数只能通过循环数位表示。
浮点数字节有限,无法平衡数值范围和精度,存在限制。
IEEE Standard 754(IEEE 754 标准)
IEEE 标准对浮点数的舍入、溢出、下溢进行了统一的规定:
挑战:硬件实现的复杂性
IEEE 754 浮点数标准定义了浮点数的 二进制表示形式,其核心是基于科学计数法的一种形式。下面我们具体解析该表示形式和编码细节:
IEEE 754 针对浮点数定义了一个通用的数学表示形式:
$ (−1)^s⋅M⋅2^E $
s (Sign,比特位):
M (Significand,尾数):
数值的有效部分,称为 有效数字部分 或 尾数。
通常是一个分数值,其范围通常在 [1.0, 2.0) 之间(规范化形式)。
规范化形式确保 M 的第一个有效位始终为 1,减少冗余。
E (Exponent,指数):
浮点数需要通过具体的位字段编码来存储在计算机的二进制内存中。IEEE 754 的编码方案是分为以下几个字段:
S (Sign):最高位(Most Significant Bit, MSB, 即第一个比特),表示符号位 s。
0 表示正号,1 表示负号。
exp (Exponent Field,指数字段):
用来编码指数 E,但指数的实际值 E 通常需要经过偏移(bias)调整:
E=exp−Bias
其中,Bias 是根据字段长度设定的偏移量,用来支持正数和负数的指数值。
frac (Fractional Field,尾数字段):
用来编码有效数字 M。但 M 并不是直接以完整的形态保存,而是存储尾数的 小数部分(省略规范化表示中的隐藏部分 1.)。
例如,M=1.1101中只存储 1101(小数部分)。
浮点数的完整二进制形式分为符号、指数和尾数三个部分,具体结构如下:
数值公式:$ (−1)^s⋅(1+frac)⋅2^{exp−Bias} $
字段分布(以 32 位单精度为例):
IEEE 754 的表示方法可以高效地表示非常大的或非常小的数值,同时兼顾精度,成为现代计算机浮点运算的标准。
exp部分一般不会是全0或全1,在公式中使用exp时,还需要减去其对应的偏移量bias,计算公式为:$ bias = 2^{k-1}-1 $,其中k为指数位exp字段的位数。
| 数据类型 | 指数字段 k | 偏移量bias | exp | E | 
|---|---|---|---|---|
| 单精度 | k=8 | 127 | 1~254 | -126~127 | 
| 双精度 | k=11 | 1023 | 1~2046 | -1022~1023 | 
对于尾数位,只存储了浮点数的小数部分,也即分数字段,例如对于1.011,只存储其分数部分的011,故有效位为:1.xxxxx...xxx=1.0+frac。
这种方法平衡了浮点数的数值范围和精度问题。
当exp=000...0时,会认为是非标准化浮点数,此时E=1-bias而非0-bias,表示范围在0到1之间。
以及一些特殊值:
exp=111...1,frac=000...0->infinite
exp=111...1,frac!=000...0->NaN(Not-a-Number)
向偶数舍入是计算机和 IEEE 754 标准默认的舍入模式,其基本原则是:
舍入到最近的值
居中则舍入到最近的偶数值
这种方法有效的减少了累计误差,考虑到了长期计算下的数值稳定性。
在二进制舍入(Binary Rounding) 下,有以下规律:
待省略部分为xxx|1xxx,进一;
待省略部分为xxx|0xxx,略去;
待省略部分为xxx|100...0,舍入使前一位为0。
以上规律为形式化规律。
浮点数乘法包括三部分:
符号位结果为两数符号位异或运算的结果;
尾数则为原有两数尾数的乘积;
指数位为两数指数之和。
之后还需要对结果进行修正与调整:
尾数修正:若尾数大于2,则将其除以2/右移一位,指数加1;
指数范围检查:指数会出现溢出现象;
截断和舍入:对尾数进行舍入,以匹配精度。
指数对齐 将两个数的指数对齐,较小数的尾数右移,使指数相同;右移可能导致精度损失或直接舍入为 0。
尾数计算 根据符号,尾数相加或相减;相减时保留绝对值较大的数的符号,结果为 0 时直接返回。
尾数规范化 调整尾数使其满足标准化要求:尾数过大时右移并增加指数,尾数过小时左移并减少指数。
溢出和下溢处理 检查指数是否超出范围;溢出返回无穷大,下溢返回 0 或次正规数。
舍入 根据舍入规则处理尾数超过有效位数的多余部分,可能导致尾数溢出,触发重新规范化。
组装结果 根据最终符号、指数和规范化尾数,组装出浮点数结果,特殊值(如无穷大或 NaN)需特殊处理。