有人能帮我吗?我需要仅使用 Latex 命令来计算总和 1+1/2+1/3+...1/n(给定 n)。我不知道该怎么做。非常感谢。
答案1
为了获得最佳精度,我建议使用l3fp
而不是 来执行此计算pgfmath
。我提出了两个函数,\mySetToSum
和\mySetToSumAlt
。两者都接受相同的参数并使用 计算总和l3fp
。不同之处在于它们如何将舍入结果写入其第一个参数:
\mySetToSum
根据第三个参数给出的小数位数对计算的结果进行四舍五入,然后丢弃尾随零(如果有);\mySetToSumAlt
执行相同操作但保留尾随零。
\documentclass{article}
\usepackage{amsmath} % only for the sample text with \dotsb
\usepackage{xparse} % not necessary with recent LaTeX (Oct. 2020)
\usepackage{xfp} % only for \fpeval (demo code)
\usepackage{pgfmath} % for printing the result with a fixed number
% of decimal places (used in \mySetToSumAlt)
\ExplSyntaxOn
\cs_new_protected:Npn \angelo_set_to_sum:Nn #1#2
{
\fp_zero_new:N #1
\int_step_inline:nn {#2} { \fp_add:Nn #1 { 1/##1 } }
}
\fp_new:N \l__angelo_result_fp
% Document-level interface
% #1: control sequence that will receive the result
% #2: value of n
% #3: round the result to this number of decimal places
\NewDocumentCommand \mySetToSum { m m m }
{
% Compute the sum with l3fp; put the result in \l__angelo_result_fp.
\angelo_set_to_sum:Nn \l__angelo_result_fp {#2}
% Set #1 to the result after rounding.
\tl_set:Nx #1 { \fp_eval:n { round(\l__angelo_result_fp, #3) } }
}
% Same macro, but uses \pgfmathprintnumberto in order to always write the
% specified number of decimal places, even if this means printing trailing
% zeros.
\NewDocumentCommand \mySetToSumAlt { m m m }
{
\angelo_set_to_sum:Nn \l__angelo_result_fp {#2}
% Set #1 to the result after rounding.
\pgfmathprintnumberto[fixed~zerofill, precision={#3}]
{ \fp_eval:n { \l__angelo_result_fp } } {#1}
}
\ExplSyntaxOff
\begin{document}
% Use n = 60 and round to 6 decimal places.
\mySetToSum{\result}{60}{6}%
% Ditto, but keep trailing zeros, if any.
\mySetToSumAlt{\resultWithTrailingZeros}{60}{6}%
\[ 1 + \frac{1}{2} + \frac{1}{3} + \dotsb + \frac{1}{60}
\approx \resultWithTrailingZeros \approx \result \]
Approximation of the Euler–Mascheroni constant:
\[ 1 + \frac{1}{2} + \frac{1}{3} + \dotsb + \frac{1}{60} - \ln(60) \approx
\fpeval{round(\result - ln(60), 6)} \]
%
% Now use n = 100
\mySetToSum{\result}{100}{6}%
\[ 1 + \frac{1}{2} + \frac{1}{3} + \dotsb + \frac{1}{100} - \ln(100) \approx
\fpeval{round(\result - ln(100), 6)} \]
%
% Now use n = 200
\mySetToSum{\result}{200}{6}%
\[ 1 + \frac{1}{2} + \frac{1}{3} + \dotsb + \frac{1}{200} - \ln(200) \approx
\fpeval{round(\result - ln(200), 6)} \]
%
% Now use n = 1000
\mySetToSum{\result}{1000}{6}%
\[ 1 + \frac{1}{2} + \frac{1}{3} + \dotsb + \frac{1}{1000} - \ln(1000) \approx
\fpeval{round(\result - ln(1000), 6)} \]
According to Wikipedia, the value of this constant is close to $0.57722$.
\end{document}
答案2
这是一个基于 LuaLaTeX 的解决方案。
% !TEX TS-program = lualatex
\documentclass{article}
\directlua{%
function harmonic ( n )
local h=0
for i=1,n do h=h+1/i end
return h
end
}
%% LaTeX macro to access the Lua function:
\newcommand\harmonic[1]{\directlua{tex.sprint(harmonic(#1))}}
\newcommand\difference[1]{\directlua{tex.sprint(harmonic(#1)-math.log(#1))}}
\begin{document}
The value of the tenth harmonic number is \harmonic{10}.
\medskip
\begin{tabular}{@{} rll @{}}
\hline
$n$ & harmonic($n$) & harmonic($n$)${}-\ln(n)$\\
\hline
1 & \harmonic{1} & \difference{1} \\
10 & \harmonic{10} & \difference{10} \\
100 & \harmonic{100} & \difference{100} \\
1000 & \harmonic{1e3} & \difference{1e3} \\
10000 & \harmonic{1e4} & \difference{1e4} \\
100000 & \harmonic{1e5} & \difference{1e5} \\
1000000 & \harmonic{1e6} & \difference{1e6} \\
10000000 & \harmonic{1e7} & \difference{1e7} \\
100000000 & \harmonic{1e8} & \difference{1e8} \\
\hline
\end{tabular}
\medskip
Euler-Mascheroni constant${}\approx 0.5772156649$.
\end{document}
答案3
由于算术能力非常有限,基本上无法仅使用 TeX 方法进行快速计算。
以下解决方案存储了最多 5000 个谐波和的值,因此它们可以在线性时间内获取。超过 5000 个,计算时间就会变得太长。
\documentclass{article}
\usepackage{booktabs}
%\usepackage{xparse} % not necessary with LaTeX 2020-10-01 or later
\usepackage{xfp} % for \fpeval
\ExplSyntaxOn
% store the values of H_n in an array (up to 5000)
\fparray_new:Nn \g_aliano_harmonic_fparray { 5000 }
% initialize
\fparray_gset:Nnn \g_aliano_harmonic_fparray { 1 } { 1 }
% at each step add the reciprocal of the next number
\int_step_inline:nn { 5000-1 }
{
\fparray_gset:Nnn \g_aliano_harmonic_fparray { #1+1 }
{
\fparray_item:Nn \g_aliano_harmonic_fparray { #1 } + 1/(#1+1)
}
}
% this retrieves the value, rounding it to 5 decimal digits
\NewExpandableDocumentCommand{\harmonic}{m}
{
\fp_eval:n { round(\fparray_item:Nn \g_aliano_harmonic_fparray { #1 },5) }
}
\ExplSyntaxOff
\begin{document}
\begin{tabular}{@{}rll@{}}
\toprule
\multicolumn{1}{@{}c}{$n$} &
\multicolumn{1}{c}{$H_n$} &
\multicolumn{1}{c@{}}{$H_n-\log n$} \\
\midrule
1 & \harmonic{1} & \fpeval{round(\harmonic{1}-ln(1),5)} \\
10 & \harmonic{10} & \fpeval{round(\harmonic{10}-ln(10),5)} \\
100 & \harmonic{100} & \fpeval{round(\harmonic{100}-ln(100),5)}\\
1000 & \harmonic{1000} & \fpeval{round(\harmonic{1000}-ln(1000),5)}\\
5000 & \harmonic{5000} & \fpeval{round(\harmonic{5000}-ln(5000),5)}\\
\bottomrule
\end{tabular}
\end{document}
如果需要更多术语,使用 LuaTeX 似乎是唯一快速的选择。也许也可以使用 PythonTeX 以足够快的方式完成此操作。