浮点数的机器表示
# 浮点数的机器表示
# 用定点数表示浮点数
定点数表示浮点数的形式
- 由 IEEE 的 754 标准在 1985 年建立
定点数表示浮点数的示意图
浮点数示例
局限性
- 只能精确的表示
这类形式的数据( 为整数) 示例
- 用定点数的形式来表示浮点数,其表示范围有限
# 计算机中浮点数的二进制表示
下述规则均符合 IEEE 754 规范
数字形式
- 符号:
- 尾数:
,是一个位于区间 [1, 2.0) 内的小数 - 阶码:
- 符号:
编码
-
域: ; 域:
- 单精度浮点数:
域宽度为 8 bits, 域宽度为 23 bits,总共32 bits - 双精度浮点数:
域宽度为 11 bits, 域宽度为 52 bits, 总共64 bits - 扩展精度浮点效:
域宽度为 15 bits, 二宽度为 63 bits, 总共 80 bits(1 bit wasted)
由 IEE754 标准, 根据 exp 的取值,浮点数可分为以下三类:
- 规格化的浮点数
- 非规格化的浮点数
- 一些特殊值
# 规格化浮点数 (Normalized)
满足条件
阶码
- 真实的阶码值需要减去一个偏置 (biased) 量
: 域所表示的无符号数值 取值 - 单精度数:
- 双精度数:
- 设用
位二进制来表示 , 则 - 如此可以保证正负值基本对称
- 单精度数:
与使用补码相比,采用偏置量可以快速比较两个浮点数的大小
尾数
- 由此,可略去首位的
,以表示更多的有效位数 - 当
时, 取得最小值为 - 当
时, 取得最大值为 , 为 的位数
- 由此,可略去首位的
规格化浮点数示例
# 非规格化浮点数 (Denoomalized)
满足条件
其它域的取值
- 不采用
的原因是为了实现从非规格化值平滑转换到规格化值 - 使用
可以补偿非规格化数的尾数没有隐含的开头的 1
- 不采用
具体示例
- 表示
- 根据符号位的取值,有
与
- 表示
- 表示"非常接近"于
的浮点数 - 随着
接近于 ,会逐步的丧失精度 - 称为 "Gradual underflow"
- 表示"非常接近"于
# 一些特殊值
满足条件
具体示例
, - 表示无穷
- 根据符号位,有“正无穷”和“负无穷”
- 如:
- 如:
, - 表示:Not-a-Number (NaN)
- 如:
# 一种小的浮点数实例
8 位浮点数表示
域宽度为 bits, 域宽度为 bits - 其它规则符合 IEEE 754 规范
exp 域的取值
取值范围
数轴上的分布
# 浮点数的编码特性
(几乎)可以直接使用无符号整数的比较方式
- 反例:
的特例 的问题
# 计算给定实数的浮点数表示
基本流程
- 首先计算出精确值
- 然后将其转换为所需的精度
- 可能会溢出(如果指数的绝对值很大)
- 可能需要完成舍入 (rounding) 操作
各种舍入模式
# 向偶数舍入 (Round-To-Even)
笔记
- 计算机内默认的舍入方式,也称为“向最接近值的舍入”
- 其它方式会产生系统误差
- 关键的设计决策是确定两个可能结果的中间数值的舍入
- 确保舍入后的最低有效数字是偶数
- 前提是最低有效数字右侧位串为
- 前提是最低有效数字右侧位串为
- 比如: 向百分位舍入
1.2349999 1.23 (Less than half way)
1.2350001 1.24 (Greater than half way)
1.2350000 1.24 (Half way一round up)
1.2450000 1.24 (Half way一round dowmn)
- 确保舍入后的最低有效数字是偶数
- 对于二进制而主
- “Even” 意味着最低有效数字需要为
- 前提是最低有效数字右侧的位串为
- 前提是最低有效数字右侧的位串为
- “Even” 意味着最低有效数字需要为
实例:二进制舍入到小数点后 2 位
# 实数转换为浮点数的具体步骤
具体步骤
- 将数值规格化 (小数点前为
) - 舍入 (round to even) 以便符合尾数的位数需求
- 后调整
实例:将 8 位无符号数转换为 8 位浮点数
- 规格化
- 舍入
- 调整(Postnormalize)
- 舍入操作可能引起溢出
- 意思是使得 Fraction 部分大于 1,此时需要调整指数,使其重新小于1
- 舍入操作可能引起溢出
# C 语言中的浮点数
笔记
float
: 单精度浮点数double
: 双精度浮点数
类型转换
- 当
int
(32 位宽),float
与double
等类型之间进行转换时,基本原则如下:double
或float
转换为int
- 如果溢出或浮点数是
NaN
,则转换结果没有意义- 通常置为
Tmin
或Tmax
- 通常置为
- 否则,值会向零舍入
- 如果溢出或浮点数是
int
转换为double
- 能够精确转换
int
转换为float
- 不会溢出,但是可能被舍入(即精度受损)
编辑 (opens new window)