最接近整数的调和数
Closest Harmonic Number to an Integer

原始链接: https://www.johndcook.com/blog/2025/11/19/closest-harmonic-number-to-an-integer/

这段文字探讨了寻找最接近给定整数 *m* 的调和数 (Hn)。调和数是 1 到 *n* 的倒数之和,对于 *n* 大于 1 的情况,很少是整数。 该方法包含两个关键部分:准确计算 Hn 和有效地找到最佳 *n*。对于较小的 *n*,直接求和有效。然而,对于较大的 *n*,使用欧拉-马斯刻罗尼常数 (γ) 的渐近近似更有效,并避免了浮点误差。 为了快速估计 *n*,使用公式 *n* ≈ exp(*m* - γ) 作为起点。然后,代码通过迭代检查 *n* 的相邻值来完善此猜测,以确定最接近 *m* 的调和数。代码处理整数和实数输入 *m*,并通过例如寻找最接近 10 的调和数和 20 的平方根的例子,展示了其多功能性。

黑客新闻 新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 最接近整数的调和数 (johndcook.com) 6 分,来自 ibobev 2 小时前 | 隐藏 | 过去 | 收藏 | 讨论 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

I mentioned in the previous post that the harmonic numbers Hn are never integers for n > 1. In the spirit of that post, I’d like to find the value of n such that Hn is closest to a given integer m.

We have two problems to solve. First, how do we accurately and efficiently compute harmonic numbers? For small n we can directly implement the definition. For large n, the direct approach would be slow and would accumulate floating point error. But in that case we could use the asymptotic approximation

H_n \approx \log n + \gamma + \frac{1}{2n} - \frac{1}{12n^2}

from this post. As is often the case, the direct approach gets worse as n increases, but the asymptotic approximation gets better as n increases. Here γ is the Euler-Mascheroni constant.

The second problem to solve is how to find the value of n so that Hn comes closest to m without trying too many possible values of n? We can discard the higher order terms above and see that n is roughly exp(m − γ).

Here’s the code.

import numpy as np

gamma = 0.57721566490153286

def H(n):
    if n < 1000:
        return sum([1/k for k in range(1, n+1)])
    else:
        n = float(n)
        return np.log(n) + gamma + 1/(2*n) - 1/(12*n**3)
    
# return n such that H_n is closest harmonic number to m
def nearest_harmonic_number(m):
    
    if m == 1:
        return 1

    guess = int(np.exp(m - gamma))    
    if H(guess) < m:
        i = guess
        while H(guess) < m: guess += 1 j = guess else: j = guess while H(guess) > m:
            guess -= 1
        i = guess
        
    x = np.array([abs(H(k) - m) for k in range(i, j+1)])
    return i + np.argmin(x)

We can use this, for example, to find the closest harmonic number to 10.

>>> nearest_harmonic_number(10)
12366
>>> H(12366)
9.99996214846655

I wrote the code with integer values of m in mind, but the code works fine with real numbers. For example, we could find the harmonic number closest to √20.

>>> nearest_harmonic_number(20**0.5)
49
>>> H(49)**2
20.063280462918804
联系我们 contact @ memedata.com