xfp - 巨大的整数 - 为什么 \inteval 不如 \fpeval 准确?

xfp - 巨大的整数 - 为什么 \inteval 不如 \fpeval 准确?

我试图打印超阶乘的前几个项,它们由 H(0)=1 和 H(n)=H(n-1)*n^n 定义。

  1. 何时fpeval用于计算,何时inteval用于打印:
\documentclass{article}
\usepackage{tikz}
\usepackage{xfp}
\begin{document}

These are the first few terms of hyperfactorials. \\
\edef\x{1}
\foreach[remember=\x] \i in {1,2,...,13} {
    \edef\x{\fpeval{\x*\i^\i}}
    $\inteval{\x}$ \\
}
\end{document}

错误:

! Number too big.

输出(忽略错误时):

These are the first few terms of hyperfactorials.
1
4
108
27648
86400000
2147483647
2147483647
2147483647
2147483647
2147483647
2147483647
2147483647
2147483647
  1. 何时fpeval用于计算和打印:
\documentclass{article}
\usepackage{tikz}
\usepackage{xfp}
\begin{document}

These are the first few terms of hyperfactorials. \\
\edef\x{1}
\foreach[remember=\x] \i in {1,2,...,13} {
    \edef\x{\fpeval{\x*\i^\i}}
    $\fpeval{\x}$ \\
}
\end{document}

输出:

These are the first few terms of hyperfactorials.
1
4
108
27648
86400000
4031078400000
3319766398771200000
55696437941726560000000000
21577941222941860000000000000000000
215779412229418600000000000000000000000000000
61564384586635060000000000000000000000000000000000000000
548914237009501600000000000000000000000000000000000000000000000000000
166252458044258000000000000000000000000000000000000000000000000000000000000000000000
  1. 何时inteval用于计算和打印:
\documentclass{article}
\usepackage{tikz}
\usepackage{xfp}
\begin{document}

These are the first few terms of hyperfactorials. \\
\edef\x{1}
\foreach[remember=\x] \i in {1,2,...,13} {
    \edef\y{\x}
    \foreach[parse=true][remember=\y] \j in {1,...,\i} {
        \edef\y{\inteval{\y*\i}}
    }
    $\inteval{\y}$ \\
    \edef\x{\y}
}
\end{document}

错误:

! Arithmetic overflow.

输出(忽略错误时):

These are the first few terms of hyperfactorials.
1
1
1
1
1
1
1
1
1
1
1
1
1

正确输出:

These are the first few terms of hyperfactorials.
1
4
108
27648
86400000
4031078400000
3319766398771200000
55696437941726556979200000
21577941222941856209168026828800000
215779412229418562091680268288000000000000000
61564384586635053951550731889313964883968000000000000000
548914237009501581804104224704637116078267727827959808000000000000000
166252458044258018207674078620690924617735088270974773221032328167424000000000000000

比较这三种情况,很明显,使用\fpeval进行计算和打印可获得最佳精度。为什么更精确?由于没有指数位,整数不应该具有更高的精度和范围吗?此外,是否有任何包/命令可以 100% 准确地覆盖巨大的整数?最后,和\fpeval的确切范围和精度是多少?\fpeval\inteval

答案1

\inteval命令是 e-TeX\numexpr基元的薄包装器。这允许进行简单的算术运算而无需赋值,但仍与 TeX 的整数概念相关:最大值为 2 31。相比之下,\fpeval它是一种基于宏的实现,可提供符合 IEEE 754 的浮点方法。它的尾数精度为 16b 位,指数最高为 10000。

可以像 一样实现扩展的(“大”)整数表达式系统\fpeval。但是,我们这样做的原因\fpeval主要是针对排版中计算出现的领域:更经典的是,像 这样的近似值trig已用于例如缩放图形。大整数不需要这样做,因为它们不会出现在排版中。值得注意的是,宏基方法的性能总是比公开原语慢:因此,\inteval永远不会改变,因为我们需要它来进行一系列低级操作。

答案2

为什么 \fpeval 更精确?由于没有指数位,整数不应该具有更高的精度和范围吗?

比较:为什么doubleC 中的数据类型比更精确int

在 C 语言中,double占用 8 个字节,而int占用 4 个字节。它们不是相等的比较。

另外,是否存在可以 100% 准确度覆盖巨大整数的包/命令?

最后,\fpeval 和 \inteval 的确切范围和精度是多少?

你需要以某种方式知道以下信息

  • \fpeval在内部使用 expl3 实现\fp_eval:n。引用 interface3.pdf:

    interface3.pdf浮点的截图

    因此,有效数字为 16 位,指数最多约为 10000。

  • \inteval是通过 expl3 内部实现的\int_eval:n...

    interface3.pdf整数的屏幕截图

    ... 反过来又用 e-TeX 原语实现\numexpr...(引用 etex_man.pdf)

    eTeX 手册引述

    这就是确切的规则。最多约为 2 31(缩放操作除外)。

答案3

关于你的问题:“还有没有任何包/命令可以 100% 准确地覆盖大整数?”我想说,如果你正在做任何类型的计算密集型数学,你应该研究一下鼠尾草给你一个 CAS 的包,智者。它与 Mathematica 类似,只是它是免费的。您的问题提供了一个可能的原因:您只想将超阶乘计算放入文档中,然后继续生活。相反,您发现自己遇到了诸如数字太大、输出不好和算术流错误等问题。在旅途中,您发现“\fpeval计算和打印结果都具有最佳精度。”这引发了更多问题,例如“为什么\fpeval更精确?由于没有指数位,整数不应该具有更高的精度和范围吗?”。现在您已经有几个答案告诉您各种方法的局限性。太好了!它可以帮您解决这个问题,但很容易想象下一个问题(鉴于您正在研究超阶乘,肯定会有下一个问题);由于 LaTeX 不是 CAS,所以您的答案的准确性总是会受到质疑。

这里有一些代码可以解决最初带你到这里的问题,准确计算 H(n):

\documentclass{article}
\usepackage{sagetex,amsmath,seqsplit}
\begin{document}
These are the first few terms of hyperfactorials. \\

\begin{sagesilent}
def H(n):
    if n==1:
        return 1
    else:
        return H(n-1)*n^n

output = r"\noindent "
for i in range(1,12):
    output += r"H(%d)= %d\\"%(i,H(i))
\end{sagesilent}
\sagestr{output}
Sage can even calculate $H(100)$ but since it has    so many digits, we need
to use the sepsplit package so it won't overflow the line:\\

\begin{sagesilent}
BigN = r"$H(100)=\seqsplit{%s}$"%(str(H(100)))
\end{sagesilent}
\noindent \sagestr{BigN}
\end{document}

在 Cocalc 中运行的输出如下: 在此处输入图片描述

sagetex软件包还允许您使用 Python 编程。使用 CAS、Python 和 LaTeX,您可以快速处理几乎所有问题,并减少花在研究准确性上的时间\fpeval

在 中\sagetex\sagesilent模式是您交给 Sage 的工作。函数 H(n) 是使用 Python 定义的。由于我想创建一个字符串供 LaTeX 排版(使用 Sage 找到的计算),因此我需要一个raw string可以处理有问题的输入(例如)的程序\。这些行for i in range(1,12): output += r"H(%d)= %d\\"%(i,H(i))运行一个循环,将 i(计数器)和 H(i) 放入 %d 所在的位置。请注意,%d 表示整数,%f 表示浮点数据,%s 表示字符串数据。该输出使用 放入您的 LaTex 文档中\sagestr{output}。较大的 H(n) 值将溢出该行,因此包序列分割用于使输出显示在多行上。从图片中可以看出,这是一个 4 页的文档;排版 H(100) 需要很多页。

圣人文档说,“感谢 GNU 多精度库 (GMP),Sage 可以处理非常大的数字,甚至是数百万或数十亿位的数字”如果你搜索GMP,你可以找到它们这里他们说,“GMP 是一个免费的任意精度算术库,可对有符号整数、有理数和浮点数进行运算。除了 GMP 运行机器的可用内存所暗示的限制外,精度没有实际限制.GMP具有丰富的函数集,且函数间有规范的接口。

GMP 的主要目标应用是密码学应用和研究、互联网安全应用、代数系统、计算代数研究等。”这是个好消息,但我需要提一下在 LaTeX 文档中运行 Sage 会限制其功能。例如,我可以在 Sage 中轻松计算 H(1000),但如果我尝试在上面的 LaTeX 代码中执行此操作,我会收到涉及过多递归的错误。

最后,值得一提的是,Sage 可以用作绘图引擎。例如,这里. 在此站点搜索更多示例。

的缺点sagetex是 Sage 不是 LaTeX 发行版的一部分。对于某些人来说,在计算机上安装并使其工作存在问题。最简单的入门方法是使用免费的可钙帐户。

相关内容