超越牛顿法?一个利用高阶导数逼近 π 的迭代构想

众所周知,圆周率 π\pi 是数学里最经典的常数之一。虽然我们平时背的是 3.14159263.1415926\cdots,但真正要高精度计算 π\pi,并不是靠“量圆”或者“背小数”,而是靠各种收敛极快的公式和迭代算法。

这篇文章主要想整理一下几类常见的求 π\pi 方法,最后介绍一个我自己瞎想出来的高阶迭代公式,请大佬轻喷。


#1. 最朴素的想法:从几何出发

最早的求 π\pi 方法,基本都和圆有关。

比如阿基米德的方法,就是用内接正多边形和外切正多边形夹逼圆周长。边数越多,多边形越接近圆,于是就能把 π\pi 夹在一个越来越小的区间里。

这个方法思想很漂亮:

内接多边形周长<圆周长<外切多边形周长\text{内接多边形周长}<\text{圆周长}<\text{外切多边形周长}

但它有个明显缺点:收敛速度不算快。想要很多位小数,需要把多边形边数搞得非常大。

所以它适合理解 π\pi,但不适合现代高精度计算。


#2. 无穷级数法

后来人们发现,π\pi 可以写成很多无穷级数。

最经典的例子是莱布尼茨公式:

π4=113+1517+\frac{\pi}{4}=1-\frac13+\frac15-\frac17+\cdots

也就是:

π=4k=0(1)k2k+1\pi=4\sum_{k=0}^{\infty}\frac{(-1)^k}{2k+1}

这个公式非常简洁,而且很好证明,但问题也非常严重:收敛太慢。

比如要算很多位 π\pi,这个公式基本不现实。它的美感远大于实用价值。


#3. Machin 类公式

为了提高速度,可以利用反正切函数:

arctanx=xx33+x55x77+\arctan x=x-\frac{x^3}{3}+\frac{x^5}{5}-\frac{x^7}{7}+\cdots

xx 比较小时,这个级数收敛会快很多。

著名的 Machin 公式是:

π4=4arctan15arctan1239\frac{\pi}{4}=4\arctan\frac15-\arctan\frac1{239}

因为 15\frac151239\frac1{239} 都比较小,所以实际收敛速度比莱布尼茨公式强得多。

很长一段时间里,Machin 类公式都是计算 π\pi 的重要工具。


#4. Ramanujan 与 Chudnovsky 公式

再往后,就出现了变态级别的公式。

Ramanujan 给出过很多极快收敛的 π\pi 公式,其中一类大概长这样:

1π=229801k=0(4k)!(1103+26390k)(k!)43964k\frac1\pi=\frac{2\sqrt2}{9801} \sum_{k=0}^{\infty} \frac{(4k)!(1103+26390k)}{(k!)^4 396^{4k}}

这个公式每一项能带来很多位正确数字。

现代计算 π\pi 最有名的公式之一是 Chudnovsky 公式:

1π=12k=0(1)k(6k)!(13591409+545140134k)(3k)!(k!)36403203k+3/2\frac1\pi= 12\sum_{k=0}^{\infty} \frac{(-1)^k(6k)!(13591409+545140134k)} {(3k)!(k!)^3 640320^{3k+3/2}}

它收敛极快,是高精度计算 π\pi 的经典算法之一。

不过这类公式虽然快,但推导背景比较深,涉及模形式、椭圆函数等内容,不是正常人很容易自然想到的东西。


#5. 从“求 π\pi”变成“求方程的根”

其实还有一种思路:

因为

sinπ=0\sin \pi=0

所以求 π\pi,可以看成求方程

sinx=0\sin x=0

的正根。

当然,sinx=0\sin x=0 有很多根:

0,π,2π,3π,0,\pi,2\pi,3\pi,\cdots

如果初值选在 π\pi 附近,比如 x0=3x_0=3,那么目标就是收敛到 π\pi

这时自然可以想到牛顿法。

f(x)=sinxf(x)=\sin x

使用牛顿法:

xn+1=xnf(xn)f(xn)x_{n+1}=x_n-\frac{f(x_n)}{f'(x_n)}

因为

f(x)=cosxf'(x)=\cos x

所以:

xn+1=xnsinxncosxnx_{n+1}=x_n-\frac{\sin x_n}{\cos x_n}

也就是:

xn+1=xntanxnx_{n+1}=x_n-\tan x_n

这个迭代在靠近 π\pi 时是二阶收敛的。

所谓二阶收敛,大概意思是:如果当前误差是 ene_n,下一步误差大约会变成 en2e_n^2 量级。也就是说,一旦接近正确答案,正确位数会增长得很快。

但我就想:牛顿法是二阶收敛,那有没有办法构造更高阶的迭代?

答案是:有的兄弟,有的


#6. 一个高阶求 π\pi 的想法

我的想法是,不直接对 sinx\sin x 用牛顿法,而是考虑:

g(x)=1sinxg(x)=\frac1{\sin x}

因为当 xπx\to \pi 时,sinx0\sin x\to 0,所以 g(x)g(x)x=πx=\pi 附近会趋向无穷。

换句话说,π\pi 不是 g(x)g(x) 的零点,而是 g(x)g(x) 的一个极点。

对这种函数,可以尝试利用高阶导数的比值构造迭代。

我想到的公式是:

xn+1=xn+(p1)dp2dxp2(1sinx)x=xndp1dxp1(1sinx)x=xnx_{n+1} = x_n+ (p-1) \frac{ \left.\dfrac{d^{p-2}}{dx^{p-2}}\left(\dfrac1{\sin x}\right)\right|_{x=x_n} }{ \left.\dfrac{d^{p-1}}{dx^{p-1}}\left(\dfrac1{\sin x}\right)\right|_{x=x_n} }

其中 p2p\ge 2

如果写得紧凑一点,就是:

xn+1=xn+(p1)g(p2)(xn)g(p1)(xn),g(x)=1sinxx_{n+1} = x_n+ (p-1) \frac{ g^{(p-2)}(x_n) }{ g^{(p-1)}(x_n) }, \quad g(x)=\frac1{\sin x}

并希望有:

limnxn=π\lim_{n\to\infty}x_n=\pi


#7. 为什么这个公式看起来有道理?

x=πx=\pi 附近,令误差:

e=xπe=x-\pi

因为

sinx=sin(π+e)=sine\sin x=\sin(\pi+e)=-\sin e

而当 ee 很小时:

sinee\sin e\approx e

所以:

sinxe\sin x\approx -e

于是:

1sinx1e\frac1{\sin x}\approx -\frac1e

也就是说,g(x)=1sinxg(x)=\frac1{\sin x}π\pi 附近的主要部分很像:

1xπ-\frac1{x-\pi}

而对

h(x)=1xπh(x)=\frac1{x-\pi}

求导,有:

h(k)(x)=(1)kk!(xπ)k1h^{(k)}(x)=(-1)^k k!(x-\pi)^{-k-1}

于是高阶导数的比值大概会把 xπx-\pi 提取出来。

这就说明,用

g(p2)(x)g(p1)(x)\frac{g^{(p-2)}(x)}{g^{(p-1)}(x)}

这种结构,确实有机会构造出一个把 xxπ\pi 推的高阶迭代。

直观地说,这个公式不是像牛顿法那样看函数的切线,而是利用更多阶导数的信息,试图一次性榨出更多误差项。


#8. 特殊情况:当 p=2p=2

p=2p=2,公式变成:

xn+1=xn+g(xn)g(xn)x_{n+1} = x_n+ \frac{ g(x_n) }{ g'(x_n) }

其中:

g(x)=1sinxg(x)=\frac1{\sin x}

计算导数:

g(x)=cosxsin2xg'(x)=-\frac{\cos x}{\sin^2 x}

所以:

g(x)g(x)=1sinxcosxsin2xsinxcosxtanx\frac{g(x)}{g'(x)} = \frac{\frac1{\sin x}}{-\frac{\cos x}{\sin^2 x}} -\frac{\sin x}{\cos x} -\tan x

因此:

xn+1=xntanxnx_{n+1}=x_n-\tan x_n

刚好退化成普通牛顿法。

这点我感觉还挺有意思:也就是说,这个公式可以看作牛顿法的一种高阶推广。


#9. 这个公式的优点和问题

这个公式理论上的优点是:

如果 pp 越大,它利用的导数阶数越高,局部收敛阶也可能越高。也就是说,在已经离 π\pi 比较近的时候,它可能比普通牛顿法收敛得更猛。

但是它也有很现实的问题:

第一,高阶导数不好算。

1sinx\frac1{\sin x} 的高阶导数会越来越复杂,实际计算时并不一定划算。

第二,高阶迭代不等于高效算法。

一个算法快不快,不只看迭代次数,还要看每一步的计算量。如果一步里要算特别复杂的高阶导数,那么总耗时可能反而更大。

第三,初值很重要。

这种迭代应该是局部收敛的,也就是初始值要离 π\pi 比较近。比如 x0=3x_0=3 这种就比较自然。如果初值乱选,可能跑到别的根,甚至发散。

所以我不敢说它一定能超过 Chudnovsky 这种顶级公式,但从迭代法角度看,它至少是一个挺有意思的高阶构造。


#10. 总结

π\pi 的方法有很多:

从阿基米德的几何夹逼,到莱布尼茨级数,再到 Machin 公式、Ramanujan 公式、Chudnovsky 公式,思路越来越抽象,收敛也越来越快。

而本文最后这个公式,是从另一个角度出发:

把求 π\pi 看成求 sinx=0\sin x=0 的根,再把根转化成 1sinx\frac1{\sin x} 的极点,然后利用高阶导数比值构造迭代。

公式如下:

xn+1=xn+(p1)dp2dxp2(1sinx)x=xndp1dxp1(1sinx)x=xnx_{n+1} = x_n+ (p-1) \frac{ \left.\dfrac{d^{p-2}}{dx^{p-2}}\left(\dfrac1{\sin x}\right)\right|_{x=x_n} }{ \left.\dfrac{d^{p-1}}{dx^{p-1}}\left(\dfrac1{\sin x}\right)\right|_{x=x_n} }

并猜想在合适初值下:

limnxn=π\lim_{n\to\infty}x_n=\pi

其中 pp 越大,理论上的局部收敛阶越高。

用 GitHub Pages 托管技术博客

对技术博客来说,静态站点是一个很稳的起点。HTML、CSS、JavaScript 和图片就能完成发布,不需要维护数据库,也不需要长期运行服务器进程。

#上线需要三件事

第一,仓库里保留 CNAME 文件,内容是 blog.66zhang.cn。第二,在 GitHub Pages 里选择从 GitHub Actions 发布。第三,在域名 DNS 里把 blog 子域名指向 GitHub Pages。

#为什么先保持静态

技术内容最重要的是可读、可访问、可长期维护。静态页面迁移简单、加载快、依赖少,适合先把文章体系跑起来。

#后续可以升级什么

文章数量变多后,可以引入静态站生成器,把文章从 HTML 换成 Markdown,再加代码高亮、分类页、搜索索引和自动化发布脚本。

从网络到云主机:信息技术笔记的起点

信息技术的学习很容易被工具和名词切碎:IP、DNS、Linux、Nginx、证书、云主机、CDN、日志。把它们串起来,才更接近真实工作里的问题。

这个博客会把常见场景整理成可复用的笔记:如何定位访问失败,如何部署一个服务,如何看日志,如何把一次排障变成下一次能直接复用的流程。

#先把链路画清楚

一个请求从浏览器发出,会经过本地网络、DNS 解析、公网路由、Web 服务、应用进程和后端资源。很多故障不是某一个命令能解决,而是要知道每一层应该验证什么。

技术笔记最有价值的部分,不只是答案,而是从现象走到原因的路径。

#把 Linux 当作基础环境

服务器上的多数问题最终都会落到文件、进程、端口、权限和日志。熟悉这些基础,再去看 Docker、Nginx、数据库或自动部署,理解成本会低很多。

#下一步记录什么

后续可以按专题补充:DNS 记录怎么选,HTTPS 证书怎么排错,GitHub Pages 如何绑定域名,Linux 服务如何开机自启,以及 AI 工具怎样辅助生成排障清单。

搭建个人技术知识库的写作流

技术知识库不是为了收藏资料,而是为了让下一次排障、部署或学习更快。记录得越结构化,复用价值越高。

#从问题模板开始

每条技术笔记可以固定包含:问题现象、环境版本、关键命令、日志片段、排查路径、最终方案和后续注意事项。模板简单,长期积累才容易坚持。

<!–code0–>

#让标签服务检索

网络、Linux、云服务、安全、AI、工具这些标签不是装饰,而是检索入口。以后遇到类似问题,可以直接按主题回看。

#保持轻量但可迁移

初期不需要复杂系统。先保证内容能发布、能修改、能搜索、能迁移,等文章变多后再引入 Markdown、构建脚本和全文索引。

让工具链成为技术工作台

技术工作里有大量重复动作:查日志、写命令、改配置、验证 DNS、整理步骤。好的工具链应该把这些动作压缩成稳定流程。

#把常用路径固定下来

终端命令、编辑器片段、Git 提交流程、部署命令都应该可重复。越是高频操作,越值得写成脚本或清单。

#AI 适合做技术副手

AI 可以帮忙生成排障步骤、解释日志、整理文档和检查配置,但最终判断仍然要回到真实环境、命令输出和可验证结果。

#让维护成本保持低位

工具链不是越多越好。能稳定解决问题、能被长期复用、能降低出错概率的工具,才真正值得留下。

Markdown + LaTeX 写作示例

这篇文章是写作示例。以后你只需要在 content/posts/ 目录新增一个 .md 文件,然后写 Markdown 和 LaTeX。

#行内公式

行内公式直接写在 $...$ 里,例如网络吞吐量可以粗略写成 T=DtT = \frac{D}{t}

#块级公式

块级公式写成:

latencyavg=i=1nlatencyin\text{latency}_{avg} = \frac{\sum_{i=1}^{n} latency_i}{n}

#Markdown 表格

类型 用法
A 记录 根域名指向 IP
CNAME 子域名指向另一个域名
TXT 验证所有权或配置策略

#代码块

<!–code0–>