## 1. 数学上的极限求导

导数的定义是：

f′(x)=lim⁡h→0 f(x+h)−f(x)hf′(x)=h→0 lim​hf(x+h)−f(x)​

在纯数学里，hh 可以无限趋近于 0，所以这个极限是精确的。  
如果计算机能进行**无限精度运算**，那么让 hh 越来越小，结果就会越来越接近真实导数。

---

## 2. 计算机里用浮点数近似

计算机一般用 IEEE 754 浮点数（如 float、double）表示实数。  
它有两个关键限制：

1. **精度有限**：比如 double 大约只有 15~17 位有效十进制数字。
    
2. **减法会丢失有效数字**：两个很接近的数相减，结果的有效位数会大幅减少。
    

数值求导常用：

f′(x)≈f(x+h)−f(x)hf′(x)≈hf(x+h)−f(x)​

这里有两个误差来源：

### （1）截断误差（数学近似误差）

因为 hh 不是 0，所以这个公式只是近似。  
根据泰勒展开：

f(x+h)=f(x)+f′(x)h+f′′(x)2 h 2+⋯f(x+h)=f(x)+f′(x)h+2 f′′(x)​h 2+⋯

所以：

f(x+h)−f(x)h=f′(x)+f′′(x)2 h+⋯hf(x+h)−f(x)​=f′(x)+2 f′′(x)​h+⋯

截断误差大致是 O(h)O(h)。  
所以 **hh 越小，截断误差越小**。

### （2）舍入误差（浮点误差）

计算机算 f(x+h)f(x+h) 和 f(x)f(x) 时，本身就有舍入误差。  
如果 hh 非常小，那么 f(x+h)f(x+h) 和 f(x)f(x) 非常接近。

例如：

f(x+h)=1.000000001 f(x+h)=1.000000001 f(x)=1.000000000 f(x)=1.000000000

两者相减：

f(x+h)−f(x)=0.000000001 f(x+h)−f(x)=0.000000001

但计算机存储这两个数时，可能只能保留有限位。  
如果它们都被舍入成差不多的值，相减后可能变成 0，或者只剩下噪声。

更严重的是，这个很小的差还要除以很小的 hh，误差会被放大：

带误差的小差 hh 带误差的小差​

所以 **hh 太小，舍入误差会爆炸**。

---

## 3. 总误差是两种误差的权衡

总误差大致可以写成：

总误差≈C 1 h⏟截断误差+C 2ϵh⏟舍入误差总误差≈截断误差 C 1​h​​+舍入误差 hC 2​ϵ​​​

其中 ϵϵ 是机器精度，比如 double 约为 10−1610−16。

- hh 太大：截断误差大，结果不精确。
    
- hh 太小：舍入误差大，结果也不精确。
    
- 存在一个**最优的 hh**，使总误差最小。
    

对 C 1 h+C 2ϵ/hC 1​h+C 2​ϵ/h 求最小，可以得到：

h∼ϵh∼ϵ​

对 double 来说：

h∼10−16=10−8 h∼10−16​=10−8

所以实际数值求导时，hh 常取 10−510−5 到 10−810−8 左右，而不是无限小。

---

## 4. 举个例子

假设真实导数是 1。

用 h=10−6 h=10−6：

f(x+h)−f(x)hhf(x+h)−f(x)​

可能得到 1.000001，还不错。

用 h=10−16 h=10−16：

由于 x+hx+h 和 xx 在浮点数里可能根本区分不开，或者相减后只剩舍入噪声，结果可能变成 0、2、甚至几百万，完全失真。

这就是“精确，但是会受到浮点误差影响”的意思：

- **理论上**：h→0 h→0 时极限精确。
    
- **实际上**：计算机浮点数精度有限，hh 太小会导致相减抵消和误差放大，反而不精确。
    

---

## 5. 一句话总结

数学上 lim⁡h→0 limh→0​ 是精确的；但计算机用浮点数算时，hh 太小会让 f(x+h)−f(x)f(x+h)−f(x) 的有效数字丢失，再除以小 hh 会把误差放大，所以数值求导不能真正让 h→0 h→0，只能取一个折中的小值。