一些函数在 中定义xfp
。例如:您可以编写类似的内容\fpeval{max(1, 2, 3, 4)}
并获得4
结果。
我想定义类似crbt(x) = x^(1/3)
或可变数量整数的最大公约数的函数。\fpeval{gcd(6, 12, 120)}
应扩展为6
。这可能吗?
抱歉,我无法创建 MWE。里面有太多代码expl3
。我不知道从哪里开始。
谢谢。 :)
答案1
小心狗的答案!
l3fp
在( xfp
) 中有一些实验代码l3trial/l3fp-extras
,它提供了您正在寻找的功能。但是,由于它在某种程度上不完整,因此尚未分发此代码(您不会在 TeX 安装中找到它)。您可以自由使用该代码,但请注意,它可能会在未经事先通知的情况下被更改/删除。
安装:
如果您想尝试一下,请使用克隆存储库git clone 'https://github.com/latex3/latex3.git'
(或仅下载上面链接的文件夹中的文件),然后在文件夹中latex3/l3trial/l3fp-extras
运行pdftex l3fp-extras.ins
,然后将解压后的文件复制l3fp-extras.sty
到您的工作目录。
使用它:
由于几乎没有文档,以下是我通过查看代码猜测得出的结论:
对于简单函数,例如立方根示例,您可以使用:
\fp_set_function:nnn { <name> } { <arg list> } { <function> }
例如:
\fp_set_function:nnn { cbrt } { x } { x^(1/3) }
对于更复杂的函数,比如您的 GCD 示例,您可以使用:
\fp_new_function:Npn <function> <parameters> { <definition> }
例如,使用欧几里得递归算法计算 GCD:
\fp_new_function:Npn \GCD #1 #2 { \fp_compare:nNnTF {#1} > {#2} { \__gcd_aux:nn {#1} {#2} } { \__gcd_aux:nn {#2} {#1} } } \cs_new:Npn \__gcd_aux:nn #1 #2 { \fp_compare:nNnTF {#2} = { 0 } {#1} { \GCD (#1-#2,#2) } }
简单情况,例如键入快捷键(例如,cbrt(8)
而不是8^(1/3)
),可以使用更强大的 来解决\fp_set_function:nnn
,但它还不能让你远离简单的表达式。对于更复杂的情况,例如,你需要比较,你必须使用(阅读:我设法让它与 一起工作)\fp_new_function:Npn
。它定义了一个宏,它接受一堆参数并在 fp 表达式中处理它们。
请注意,在较简单的情况下,您可以调用\fpeval{cbrt(8)}
,而在第二种情况下,您必须在函数名称前加上反斜杠:\fpeval{\GCD(3,4)}
。我无法\GCD
使用符号名称进行工作。
而且似乎还不可能有可变数量的参数,所以你必须写\GCD(\GCD(6, 12), 120)
而不是\GCD(6, 12, 120)
。
无论如何,事情是这样的:
\documentclass{article}
\usepackage{l3fp-extras}
\usepackage{xfp}
\ExplSyntaxOn
\fp_set_function:nnn { cbrt } { x } { x^(1/3) }
%
\fp_new_function:Npn \GCD #1 #2
{
\fp_compare:nNnTF {#1} > {#2}
{ \__gcd_aux:nn {#1} {#2} }
{ \__gcd_aux:nn {#2} {#1} }
}
\cs_new:Npn \__gcd_aux:nn #1 #2
{
\fp_compare:nNnTF {#2} = { 0 }
{#1} { \GCD (#1-#2,#2) }
}
\ExplSyntaxOff
\begin{document}
\fpeval{cbrt(8)} % prints 2
\fpeval{\GCD(1071, 462)} % prints 21
\fpeval{\GCD(\GCD(6, 12), 120)} % prints 6
\end{document}