跳转至

素数定理

层级:① 教科书共识 · 来源:Hadamard & de la Vallée Poussin (1896)

一句话版本

素数虽然无穷多,但越来越稀——而稀的方式精确可测。 不超过 \(x\) 的素数个数 \(\pi(x)\),渐近等于 \(x/\ln x\)。

直觉

把 1 到 \(x\) 的整数排成一列,素数在其中"随机撒点"。一个数 \(n\) 是素数的概率大约是 \(1/\ln n\)(数字越大,越容易被小素数整除掉),所以素数总数大约是 \(\sum_{n\le x} 1/\ln n \approx x/\ln x\)。这个粗糙的骰子论证,答案竟然精确到惊人。

实测数据

\(x\) \(\pi(x)\) 精确值 \(x/\ln x\) 近似 相对误差
\(10^4\) 1,229 1,086 11.6%
\(10^6\) 78,498 72,382 7.8%
\(10^8\) 5,761,455 5,428,681 5.8%

更好的近似是对数积分 \(\operatorname{li}(x)\):\(\operatorname{li}(10^6) = 78{,}627.5\),误差降到 0.16%。

严格表述

\[\pi(x) \sim \frac{x}{\ln x} \qquad (x \to \infty)\]

即 \(\pi(x) / (x/\ln x) \to 1\)。误差项的经典结果(1896):

\[\pi(x) = \operatorname{li}(x) + O\!\left(x\, e^{-c\sqrt{\ln x}}\right)\]

黎曼假设若成立,误差可收紧为 \(O(\sqrt{x}\,\ln x)\)——这就是 ζ 函数与素数分布深度纠缠的原因(见黎曼 ζ 函数)。

自己验证

# 素数定理验证:筛出 10^6 以内素数,对照 x/ln x
import math

def primes_upto(n):
    sieve = bytearray([1]) * (n + 1)
    sieve[0:2] = b"\x00\x00"
    for p in range(2, int(n**0.5) + 1):
        if sieve[p]:
            sieve[p*p::p] = bytearray(len(sieve[p*p::p]))
    return [i for i, f in enumerate(sieve) if f]

P = primes_upto(1_000_000)
pi_1e6 = len(P)
assert pi_1e6 == 78498, pi_1e6          # 教科书标准值

approx = 1_000_000 / math.log(1_000_000)
print(f"pi(10^6) = {pi_1e6}")
print(f"x/ln x   = {approx:.0f}  (低估 {(1-approx/pi_1e6)*100:.1f}%)")

延伸


发布:2026-10-23 07:39:14 · 数论库