1. 引言

计算机内存容量是有限的,而实数集 R 中的数通常无法用有限的位数精确表示。例如,将有理数 \frac{4}{3} 转换为十进制小数时,结果是 (1.333\overline{3})_{10},无法精确表示。

因此,在计算机中,实数必须通过某种方式近似表示(截断或四舍五入)。本文将介绍浮点数的基本表示方法,并探讨其在数值计算中的精度限制。


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 浮点数的精度问题

由于内存有限,浮点数只能表示有限个数的实数。这导致两个问题:

  1. 并非所有实数都能表示
  2. 浮点数之间的间隔不均匀

浮点数之间的最小间隔称为 机器 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.10.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 浮点标准

参考资料


原始标题:Why Are Floating Point Numbers Inaccurate?