1. 引言
计算机内存容量是有限的,而实数集 中的数通常无法用有限的位数精确表示。例如,将有理数
转换为十进制小数时,结果是
,无法精确表示。
因此,在计算机中,实数必须通过某种方式近似表示(截断或四舍五入)。本文将介绍浮点数的基本表示方法,并探讨其在数值计算中的精度限制。
2. 截断与四舍五入
将实数近似为有限位数时,有两种主要方式:
2.1 截断(Chopping)
截断是指直接舍去指定小数位之后的所有数字。
✅ 示例:将 56.555
截断为 1 位小数,结果为 56.5
。
2.2 四舍五入(Rounding)
四舍五入是指选择与原数最接近的指定小数位数的值。
✅ 示例:将 56.555
四舍五入为 1 位小数,结果为 56.6
。因为 56.6
更接近原数。
2.3 判断规则
设 p
是指定小数位之后的部分:
- 若
p > 0.5 × 10^{-t}
:进位 - 若
p < 0.5 × 10^{-t}
:不进位
当 p = 0.5 × 10^{-t}
时,遵循“偶数进位法”:若当前位是奇数则进位,否则不进位。
2.4 示例对比
原数 | 四舍五入(t=3) | 截断(t=3) |
---|---|---|
0.2397 | 0.240 | 0.239 |
0.23750 | 0.238 | 0.237 |
0.23650 | 0.236 | 0.236 |
π ≈ 3.1415926 | 3.142 | 3.141 |
2.5 实际影响
温哥华证券交易所指数曾因使用截断而非四舍五入,导致指数值严重低估。实际值应为 1082.00
,但因截断计算,最终显示为 500
多点。
3. 计算机数制系统
我们日常使用十进制系统(base 10),但计算机使用二进制系统(base 2)进行数值计算。
任何实数都可以表示为如下形式:
$$ x = d_n \beta^n + d_{n-1}\beta^{n-1} + \ldots + d_1 \beta^{1} + d_0 \beta^0 + d_{-1}\beta^{-1} + d_{-2} \beta^{-2} + \ldots $$
其中 β
是基数,d_i
是 [0, β)
范围内的整数。
3.1 数制转换算法
十进制转二进制(整数部分)
将十进制整数除以 2,依次记录余数,直到商为 0,余数倒序排列即为二进制表示。
✅ 示例:250
转二进制:
步骤 | 商 | 余数 |
---|---|---|
0 | 250 | 0 |
1 | 125 | 1 |
2 | 62 | 0 |
3 | 31 | 1 |
4 | 15 | 1 |
5 | 7 | 1 |
6 | 3 | 1 |
7 | 1 | 1 |
结果:11111010
十进制转二进制(小数部分)
将小数部分不断乘以 2,记录整数部分,直到小数部分为 0。
✅ 示例:0.15625
转二进制:
步骤 | 小数 | 乘以 2 | 整数 |
---|---|---|---|
0 | 0.15625 | 0.3125 | 0 |
1 | 0.3125 | 0.625 | 0 |
2 | 0.625 | 1.25 | 1 |
3 | 0.25 | 0.5 | 0 |
4 | 0.5 | 1.0 | 1 |
结果:0.00101
3.2 定点与浮点表示
- 定点数:小数点位置固定,表示范围受限
- 浮点数:小数点位置可变,表示范围更广
浮点数的一般形式为:
$$ a = \pm m \cdot \beta^e $$
其中:
m
:尾数(mantissa)e
:指数(exponent)β
:基数(通常是 2)
3.3 浮点数的精度问题
由于内存有限,浮点数只能表示有限个数的实数。这导致两个问题:
- 并非所有实数都能表示
- 浮点数之间的间隔不均匀
浮点数之间的最小间隔称为 机器 epsilon,即 1.0
与下一个最大浮点数之间的距离。
4. IEEE 浮点标准简述
现代计算机遵循 IEEE 754 标准,定义了单精度(32 位)和双精度(64 位)浮点数格式:
类型 | 符号位 | 指数位 | 尾数位 |
---|---|---|---|
单精度 | 1 | 8 | 23 |
双精度 | 1 | 11 | 52 |
IEEE 浮点数的格式为:
$$ v = (-1)^s (1.m)_2 \cdot 2^e $$
其中:
s
:符号位(0 为正,1 为负)m
:尾数(隐含前导 1)e
:指数(偏移量为 127 或 1023)
5. 浮点运算中的“坑”
5.1 不精确的比较
(0.10 + 0.20) == 0.30 # False
✅ 原因:0.1
和 0.2
无法在二进制浮点数中精确表示。
5.2 精度丢失示例
0.1
在双精度下表示为≈0.10000000000000000555
0.2
表示为≈0.2000000000000000111
0.3
表示为≈0.29999999999999998889
因此:
0.1 + 0.2 > 0.3 # True
⚠️ 结论:代数上等价的表达式在数值上不一定等价。
6. 总结
- 浮点数的表示基于有限精度,无法精确表示所有实数。
- IEEE 754 标准定义了单精度和双精度格式。
- 浮点运算存在精度误差,特别是在比较和加减操作中。
- 在进行数值计算时,应避免直接比较浮点数,应使用误差容忍机制(如
abs(a - b) < epsilon
)。
✅ 建议:使用 BigDecimal
(Java)、decimal
(C#)或 Decimal
(Python)进行高精度计算。
附录:浮点数系统特性
浮点数系统由以下参数定义:
β
:基数(通常为 2)t
:尾数位数e_min
:最小指数e_max
:最大指数
IEEE 双精度格式为:
$$ F(\beta=2, t=52, e_{min}=-1022, e_{max}=1023) $$
术语对照表(常用)
英文术语 | 中文术语 |
---|---|
floating point | 浮点数 |
rounding | 四舍五入 |
chopping | 截断 |
mantissa | 尾数 / 有效数位 |
exponent | 指数 |
machine epsilon | 机器 epsilon |
IEEE 754 | IEEE 浮点标准 |