Beware of the dog answer!
There is some experimental code for l3fp
(xfp
) in l3trial/l3fp-extras
, which provides the feature you are looking for. However, this code is not distributed yet (you won't find it in your TeX installation) because it's in one way or another incomplete. You are free to use that code, but beware that it may be changed/removed without prior notice.
Installation:
Should you want to try it, clone the repository with git clone 'https://github.com/latex3/latex3.git'
(or just download the files in the folder linked above), then in the folder latex3/l3trial/l3fp-extras
run pdftex l3fp-extras.ins
, then copy the unpacked l3fp-extras.sty
to your working directory.
Using it:
Since there is barely no documentation, here is what I guessed found out from looking at the code:
For simple functions, like your cube root example, you can use:
\fp_set_function:nnn { <name> } { <arg list> } { <function> }
for example:
\fp_set_function:nnn { cbrt } { x } { x^(1/3) }
For more complex functions, like your GCD example, you can use:
\fp_new_function:Npn <function> <parameters> { <definition> }
for example, to compute the GCD using Euclid's recursive algorithm:
\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) }
}
The simple cases, that are like typing shortcuts (e.g., cbrt(8)
instead of 8^(1/3)
) can be solved with the more powerful \fp_set_function:nnn
, but it doesn't let you go too far from simple expressions yet. For more complicate cases, where you need, for example, comparisons, you have to use (read: I managed to make it work with) \fp_new_function:Npn
. It defines a macro that takes a bunch of arguments and processes them inside the fp expression.
Note that in the simpler case you can then call \fpeval{cbrt(8)}
, whereas in the second case you have to precede the function name with a backslash: \fpeval{\GCD(3,4)}
. I didn't manage to make \GCD
work with the symbolic name.
Also it seems it is not yet possible to have a variable number of arguments, so you have to write \GCD(\GCD(6, 12), 120)
instead of \GCD(6, 12, 120)
.
Anyway, here it goes:
\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}
l3trial
, so it's not distributed and it's not really “ready for use”