计算机系统基础3---值的表示2---定点数与浮点数的介绍

文章目录

定点数和浮点数是计算机中表示数值的两种主要方式,它们在精度、范围和运算效率上有显著差异。

一、定点数(Fixed-Point Number)

定义

定点数是计算机中表示实数(即带小数部分的数字)的一种方法。它的核心思想是约定小数点在二进制数中的位置是固定不变的。

定点数就是将整数运算电路直接用于小数运算的一种高效方式。

定点数的表示方法

定点数的格式通常描述为 Qm.n 或 Fx.m.n,其中:

m: 表示整数部分的位数(包括可能的符号位)。

n: 表示小数部分的位数。

总位数: m + n。

最常见的形式如下:

定点整数

小数点位置:固定在数字的最右边。

表示范围:只能表示整数。

例子:8位无符号定点整数,范围是 0 到 255。本质上就是普通的整数。

定点小数

小数点位置:固定在数字的最左边(紧跟在符号位之后)。

表示范围:只能表示小于1的纯小数。

例子:8位定点小数(1位符号位,7位小数位),能表示的范围大约是 -1 到 1。

带整数和小数的定点数(最常见)

小数点位置:固定在数字中间的某个位置。

例子:一个 Q8.8 格式的16位定点数,意思是高8位是整数部分(其中最高位通常是符号位),低8位是小数部分。

特点

1、表示范围有限

数值范围由整数和小数部分的位数决定。例如,8位定点数(Q3.4)范围为:-8.0 到 7.9375(二进制补码表示)。

2、精度固定

小数位数固定,运算时不会丢失精度(但可能溢出)。

3、运算效率高

硬件实现简单,适合嵌入式系统或对速度要求高的场景(如数字信号处理)。

4、无指数部分

仅通过整数和小数部分表示数值,无阶码(指数)和尾数的分离结构。

示例

Q2.3格式(总5位,2位整数,3位小数):

二进制 101.011 = 1×2¹ + 0×2⁰ + 1×2⁻¹ + 0×2⁻² + 1×2⁻³ = 2 + 0.5 + 0.125 = 2.625

范围:-4.0 到 3.875(补码表示)。

定点数的运算

定点数的运算基于整数运算,但需要手动处理小数点。

1. 加减法

规则:小数点必须对齐。只有相同格式(即 n 相同)的定点数才能直接相加减。

操作:直接将两个数的整数表示 V1 和 V2 相加。

结果:结果的格式仍然是与操作数相同的 Qm.n。

例子:2.5 (Q12.3 的 20) + 1.0 (Q12.3 的 8) = 20 + 8 = 28。 28 / 8 = 3.5。

2. 乘法

规则:乘法会导致小数位数变化。

操作:直接将两个数的整数表示 V1 和 V2 相乘。

结果分析:

V result = V1×V2=(R1×2 ^ n)×(R2×2 ^ n)=(R1×R2)×2 ^ 2n

此时,Vresult 代表的是实际值R1 * R2 * 2 ^ 2n。也就是说,中间结果的"小数点"偏移到了 2 ^ n位后。

修正:为了将结果存回原始的 Qm.n 格式,我们需要将乘积结果右移 n 位。

例子:2.5 (20) * 2.0 (16) = 320。

320 对应的是(2.5 * 2.0)* 2 ^ (2 * 3) = 5 * 64 = 320

要得到 Q12.3 格式的 5.0,我们需要右移 3 位: 320 >> 3 = 40。

验证:40 / 8 = 5.0。

3. 除法

规则:除法同样会改变小数位数。

操作:为了得到 Qm.n 格式的商,需要先将被除数左移 n 位,然后再除以除数。

V result = (V1<<n)/V2

定点数的优缺点

优点

1、速度快:定点数运算直接使用CPU的整数算术逻辑单元(ALU),不涉及浮点运算单元(FPU)。在没有FPU的低端微控制器(MCU)或早期游戏中,这是巨大的性能优势。

2、精度确定:定点数的精度在整个数值范围内是均匀的。而浮点数的精度会随着数值的增大而降低(大数加小数可能没变化)。

3、确定性:定点运算在不同平台上的结果完全一致(因为就是整数运算)。浮点数由于精度和舍入模式的差异,在不同硬件上可能会有细微差别。

4、成本和功耗低:实现定点运算所需的逻辑门电路比浮点运算少得多。

缺点

1、动态范围小:容易溢出或下溢。例如,用16位定点数很难同时表示一个非常大的数(如星系距离)和一个非常小的数(如原子直径)。

2、编程复杂度高:程序员必须时刻跟踪小数点的位置,手动处理乘法后的移位操作,防止溢出。

3、精度损失:在转换格式或进行除法时,可能会因为截断而产生误差。

应用场景

1、嵌入式系统:许多8位或32位的微控制器(如ARM Cortex-M系列的一些型号)没有硬件FPU,使用定点数是处理小数的唯一高效方式。

2、数字信号处理(DSP):音频编解码、调制解调、图像滤波等算法大量使用定点数,因为它们对实时性要求极高,且精度可控。

3、金融计算:某些金融系统要求精确到分,且运算结果必须完全确定,以避免法律纠纷。定点数(或直接用整数表示"分")是比浮点数更安全的选择。

4、旧式游戏机和早期3D游戏:在3D图形加速卡普及之前,许多游戏(如《毁灭战士》)的3D渲染逻辑完全依赖定点数来实现透视变换。

二、浮点数(Floating-Point Number)

定义

浮点数(Floating-point number)是计算机中表示实数(即包含小数部分的数)的一种重要方式。与之前介绍的定点数不同,浮点数的小数点位置是"浮动"的,这使得它能够以固定的位数表示极大和极小的数值,同时保持较高的精度。

浮点数采用科学计数法,通过符号位、阶码(指数)和尾数(有效数字)表示数值,小数点位置可浮动。例如,IEEE 754标准。

为什么需要浮点数?

定点数虽然简单高效,但存在一个根本性的缺陷:动态范围小。用16位定点数,你无法同时表示一个原子的直径 (10 ^ (-10米))和一个星系的距离(10 ^ 20米)。

为了覆盖如此巨大的范围,我们需要一种类似于科学记数法的表示方法:

数值=尾数 ×(基数 ^ 指数)

特点

1、表示范围大

阶码决定范围,尾数决定精度。例如,32位单精度浮点数范围约 ±3.4×10³⁸。

2、精度动态调整

尾数位数固定,但有效数字位数随数值大小变化(大数精度低,小数精度高)。

3、运算复杂度高

需处理阶码对齐、尾数运算和规格化,硬件开销大。

4、存在舍入误差

尾数位数有限,可能丢失精度(如0.1无法精确表示)。

例如,阿伏伽德罗常数6.022 * (10 ^ 23),光速3.0 * (10 * 8)m/s。在计算机中,我们使用二进制科学记数法,这就是浮点数的核心思想。

IEEE 754标准

目前几乎所有计算机都采用 IEEE 754 浮点数标准。它定义了多种精度格式,最常用的是:

1、单精度(32位):通常称为 float。

2、双精度(64位):通常称为 double。

基本格式

一个 IEEE 754 浮点数由三个字段组成(以单精度为例,双精度类似但位数不同):

字段 单精度位数 双精度位数 说明
符号位 (S) 1 1 0 表示正数,1 表示负数
指数位 (E) 8 11 使用移码(偏移量)表示
尾数位 (M) 23 52 存储规格化后的小数部分(隐含整数位1)

计算公式(以单精度为例):

数值 = (-1 ^ S)* (1.M) * (2 ^ (E - 127))

指数偏移量(bias)为 127(双精度为 1023)。

尾数 M 是一个小数部分,隐含的整数部分总是 1(规格化数的情况)。

规格化数

当指数位不全为0且不全为1时,我们称这个数为规格化数。此时尾数部分隐含一个整数位"1",因此实际有效位数为 24 位(单精度)。这保证了精度最大化。

例如,单精度浮点数 0 01111100 01000000000000000000000:

符号 S = 0

指数 E = 124 → 实际指数 = 124 - 127 = -3

尾数 M = 0.01(二进制) = 0.25(十进制)

数值 = 1.25 * (2 ^ -3)= 0.15625

非规格化数

当指数位全为0时,我们进入非规格化数(或称次正规数)区域。此时隐含的整数位变为0,公式为:

数值 = (-1 ^ S)* (0.M) * (2 ^ - 126)

非规格化数主要用于表示接近0的极小数值,实现逐渐下溢,避免突然下溢到0。

特殊值

IEEE 754 还定义了几个特殊值的表示

无穷大:指数全1,尾数全0。符号位表示正无穷或负无穷。用于溢出等情况。

NaN(Not a Number):指数全1,尾数非0。用于表示无效运算结果,如 0/0、√(-1)(根号-1)等。

浮点数的范围与精度(单精度为例)

最大正规格化数:约3.4×(10 ^ 38)( 2 ^ (128 − 127) × ( 2 − 2 ^ (− 23) )

最小正规格化数:约1.2×(10 ^ -38)( 2 ^ (1 − 127) × 1.0)

最小正非规格化数:约 1.2×(10 ^ -45)( 2 ^ -149)

精度:大约 7 位十进制有效数字(因为2 ^ -23 ≈ 1.2×(10^-7)

双精度的范围约(10 ^ -308)到(10 ^ 308),精度约 15-16 位十进制有效数字。

浮点数的优缺点

优点

动态范围极大:能同时表示极大和极小的数。

相对精度固定:有效数字位数基本固定,数值的相对误差大致均匀。

标准化:IEEE 754 保证了跨平台的一致性(除了一些细节如舍入)。

缺点

精度不均匀:数值越大,绝对误差越大。例如,100000000 附近的两个浮点数之间的间隔可能大于1,导致无法表示所有整数。

运算复杂:硬件实现复杂,功耗和面积大于整数运算单元。

存在舍入误差:许多十进制小数无法精确表示(如 0.1),导致累积误差。

比较时需小心:由于误差,直接判断两个浮点数相等(a == b)往往不可靠。

实际应用中的注意事项

1、避免直接比较相等:应使用容差比较,如 fabs(a - b) < epsilon。

2、警惕大数吃小数:当非常大和非常小的数相加时,小数可能被"吃掉"而丢失。例如,1e20 + 1.0 在单精度下结果仍然是 1e20。

3、累积误差:长循环或迭代计算时,误差可能积累到不可接受的程度。可考虑使用更高精度或改变算法。

4、不要用浮点数表示精确值:如货币金额,应使用整数(分)或定点数。

5、了解编译器和硬件的浮点行为:一些编译优化可能改变运算顺序,导致结果变化(如 -ffast-math 选项)。

示例:

试试在 Python 中运行:

c 复制代码
>>> 0.1 + 0.2
0.30000000000000004

应用场景

浮点数广泛应用于科学计算、图形处理、人工智能等几乎所有需要处理非整数的领域。

浮点数与定点数的对比

特性 浮点数 定点数
表示范围 极大 有限,由位宽决定
精度分布 相对精度均匀,绝对精度随数值增大而降低 绝对精度均匀(最小刻度固定)
硬件复杂度 高(需要 FPU) 低(可用整数 ALU)
运算速度 相对较慢(尤其在没有 FPU 的系统中) 极快
功耗/成本
确定性 受舍入模式影响,不同平台可能有微小差异 完全确定,与整数运算一致
典型应用 科学计算、图形学、AI、通用软件 嵌入式系统、DSP、金融(需要精确小数)
相关推荐
云深处@2 小时前
【数据结构】栈
数据结构·算法
啊我不会诶2 小时前
Codeforces Round 1076 (Div. 3) vp补题
算法·深度优先
Bear on Toilet2 小时前
递归_二叉树_49 . 路径综合Ⅲ
数据结构·算法·前缀和·深度优先·递归
CHANG_THE_WORLD2 小时前
深入指针3 - 完全精讲版
数据结构·算法
im_AMBER2 小时前
Leetcode 124 二叉搜索树的最小绝对差 | 二叉树的锯齿形层序遍历
数据结构·学习·算法·leetcode·二叉树
ADDDDDD_Trouvaille2 小时前
2026.2.14——OJ78-82题
c++·算法
Hag_202 小时前
LeetCode Hot100 560.和为K的子数组
数据结构·算法·leetcode
田里的水稻3 小时前
FA_规划和控制(PC)-规律路图法(PRM)
人工智能·算法·机器学习·机器人·自动驾驶
追随者永远是胜利者3 小时前
(LeetCode-Hot100)23. 合并 K 个升序链表
java·算法·leetcode·链表·go