summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/l3kernel/l3fp.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/l3kernel/l3fp.dtx')
-rw-r--r--macros/latex/contrib/l3kernel/l3fp.dtx1488
1 files changed, 1488 insertions, 0 deletions
diff --git a/macros/latex/contrib/l3kernel/l3fp.dtx b/macros/latex/contrib/l3kernel/l3fp.dtx
new file mode 100644
index 0000000000..a74b27f900
--- /dev/null
+++ b/macros/latex/contrib/l3kernel/l3fp.dtx
@@ -0,0 +1,1488 @@
+% \iffalse meta-comment
+%
+%% File: l3fp.dtx
+%
+% Copyright (C) 2011-2019 The LaTeX3 Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3kernel bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\usepackage{amsmath}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% ^^A need to provide this inside the file:
+%
+% \providecommand\nan{\texttt{NaN}}
+%
+%
+% \title{^^A
+% The \textsf{l3fp} package: Floating points^^A
+% }
+%
+% \author{^^A
+% The \LaTeX3 Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2019-08-25}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% A decimal floating point number is one which is stored as a significand and a
+% separate exponent. The module implements expandably a wide set of
+% arithmetic, trigonometric, and other operations on decimal floating point
+% numbers, to be used within floating point expressions. Floating point
+% expressions support the following operations with their usual
+% precedence.
+% \begin{itemize}
+% \item Basic arithmetic: addition $x+y$, subtraction $x-y$,
+% multiplication $x*y$, division $x/y$, square root~$\sqrt{x}$,
+% and parentheses.
+% \item Comparison operators: $x\mathop{\mathtt{<}}y$,
+% $x\mathop{\mathtt{<=}}y$, $x\mathop{\mathtt{>?}}y$,
+% $x\mathop{\mathtt{!=}}y$ \emph{etc.}
+% \item Boolean logic: sign $\operatorname{sign} x$,
+% negation $\mathop{!}x$, conjunction
+% $x\mathop{\&\&}y$, disjunction $x\mathop{\vert\vert}y$, ternary
+% operator $x\mathop{?}y\mathop{:}z$.
+% \item Exponentials: $\exp x$, $\ln x$, $x^y$.
+% \item Integer factorial: $\operatorname{fact} x$.
+% \item Trigonometry: $\sin x$, $\cos x$, $\tan x$, $\cot x$, $\sec
+% x$, $\csc x$ expecting their arguments in radians, and
+% $\operatorname{sind} x$, $\operatorname{cosd} x$,
+% $\operatorname{tand} x$, $\operatorname{cotd} x$,
+% $\operatorname{secd} x$, $\operatorname{cscd} x$ expecting their
+% arguments in degrees.
+% \item Inverse trigonometric functions: $\operatorname{asin} x$,
+% $\operatorname{acos} x$, $\operatorname{atan} x$,
+% $\operatorname{acot} x$, $\operatorname{asec} x$,
+% $\operatorname{acsc} x$ giving a result in radians, and
+% $\operatorname{asind} x$, $\operatorname{acosd} x$,
+% $\operatorname{atand} x$, $\operatorname{acotd} x$,
+% $\operatorname{asecd} x$, $\operatorname{acscd} x$ giving a result
+% in degrees.
+% \item [\emph{(not yet)}] Hyperbolic functions and their inverse
+% functions: $\sinh x$, $\cosh x$, $\tanh x$, $\coth x$,
+% $\operatorname{sech} x$, $\operatorname{csch}$, and
+% $\operatorname{asinh} x$, $\operatorname{acosh} x$,
+% $\operatorname{atanh} x$, $\operatorname{acoth} x$,
+% $\operatorname{asech} x$, $\operatorname{acsch} x$.
+% \item Extrema: $\max(x_{1},x_{2},\ldots)$, $\min(x_{1},x_{2},\ldots)$,
+% $\operatorname{abs}(x)$.
+% \item Rouning functions, controlled by two optional
+% values, $n$ (number of places, $0$ by default) and
+% $t$ (behavior on a tie, $\nan$ by default):
+% \begin{itemize}
+% \item $\operatorname{trunc}(x,n)$ rounds towards zero,
+% \item $\operatorname{floor}(x,n)$ rounds towards~$-\infty$,
+% \item $\operatorname{ceil}(x,n)$ rounds towards~$+\infty$,
+% \item $\operatorname{round}(x,n,t)$ rounds to the closest value, with
+% ties rounded to an even value by default, towards zero if $t=0$,
+% towards $+\infty$ if $t>0$ and towards $-\infty$ if $t<0$.
+% \end{itemize}
+% And \emph{(not yet)} modulo, and \enquote{quantize}.
+% \item Random numbers: $\mathop{rand}()$, $\mathop{randint}(m,n)$.
+% \item Constants: \texttt{pi}, \texttt{deg} (one degree in radians).
+% \item Dimensions, automatically expressed in points, \emph{e.g.},
+% \texttt{pc} is~$12$.
+% \item Automatic conversion (no need for \cs[no-index]{\meta{type}_use:N}) of
+% integer, dimension, and skip variables to floating point numbers,
+% expressing dimensions in points and ignoring the stretch and
+% shrink components of skips.
+% \item Tuples: $(x_1,\ldots{},x_n)$ that can be stored in variables,
+% added together, multiplied or divided by a floating point number,
+% and nested.
+% \end{itemize}
+% Floating point numbers can be given either explicitly (in a form such
+% as |1.234e-34|, or |-.0001|), or as a stored floating point variable,
+% which is automatically replaced by its current value.
+% A \enquote{floating point} is a floating point number or a tuple thereof. See
+% section~\ref{sec:l3fp:fp-floats} for a description of what a floating point is,
+% section~\ref{sec:l3fp:fp-precedence} for details about how an expression is
+% parsed, and section~\ref{sec:l3fp:fp-operations} to know what the various
+% operations do. Some operations may raise exceptions (error messages),
+% described in section~\ref{sec:l3fp:fp-exceptions}.
+%
+% An example of use could be the following.
+% \begin{verbatim}
+% \LaTeX{} can now compute: $ \frac{\sin (3.5)}{2} + 2\cdot 10^{-3}
+% = \ExplSyntaxOn \fp_to_decimal:n {sin(3.5)/2 + 2e-3} $.
+% \end{verbatim}
+% The operation \texttt{round} can be used to limit the result's
+% precision. Adding $+0$ avoids the possibly undesirable output |-0|,
+% replacing it by |+0|. However, the \pkg{l3fp} module is mostly meant
+% as an underlying tool for higher-level commands. For example, one
+% could provide a function to typeset nicely the result of floating
+% point computations.
+% \begin{verbatim}
+% \documentclass{article}
+% \usepackage{xparse, siunitx}
+% \ExplSyntaxOn
+% \NewDocumentCommand { \calcnum } { m }
+% { \num { \fp_to_scientific:n {#1} } }
+% \ExplSyntaxOff
+% \begin{document}
+% \calcnum { 2 pi * sin ( 2.3 ^ 5 ) }
+% \end{document}
+% \end{verbatim}
+% See the documentation of \pkg{siunitx} for various options of
+% \cs{num}.
+%
+% \section{Creating and initialising floating point variables}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp001]
+% {\fp_new:N, \fp_new:c}
+% \begin{syntax}
+% \cs{fp_new:N} \meta{fp~var}
+% \end{syntax}
+% Creates a new \meta{fp~var} or raises an error if the name is
+% already taken. The declaration is global. The \meta{fp~var} is
+% initially~$+0$.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp001]
+% {\fp_const:Nn, \fp_const:cn}
+% \begin{syntax}
+% \cs{fp_const:Nn} \meta{fp~var} \Arg{floating point expression}
+% \end{syntax}
+% Creates a new constant \meta{fp~var} or raises an error if the name
+% is already taken. The \meta{fp~var} is set globally equal to
+% the result of evaluating the \meta{floating point expression}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp001]
+% {\fp_zero:N, \fp_zero:c, \fp_gzero:N, \fp_gzero:c}
+% \begin{syntax}
+% \cs{fp_zero:N} \meta{fp~var}
+% \end{syntax}
+% Sets the \meta{fp~var} to~$+0$.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp001]
+% {\fp_zero_new:N, \fp_zero_new:c, \fp_gzero_new:N, \fp_gzero_new:c}
+% \begin{syntax}
+% \cs{fp_zero_new:N} \meta{fp~var}
+% \end{syntax}
+% Ensures that the \meta{fp~var} exists globally
+% by applying \cs{fp_new:N} if necessary, then applies
+% \cs[index=fp_zero:N]{fp_(g)zero:N} to leave the \meta{fp~var} set to~$+0$.
+% \end{function}
+%
+% \section{Setting floating point variables}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp002]
+% {\fp_set:Nn, \fp_set:cn, \fp_gset:Nn, \fp_gset:cn}
+% \begin{syntax}
+% \cs{fp_set:Nn} \meta{fp~var} \Arg{floating point expression}
+% \end{syntax}
+% Sets \meta{fp~var} equal to the result of computing the
+% \meta{floating point expression}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp002]
+% {
+% \fp_set_eq:NN , \fp_set_eq:cN , \fp_set_eq:Nc , \fp_set_eq:cc ,
+% \fp_gset_eq:NN, \fp_gset_eq:cN, \fp_gset_eq:Nc, \fp_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{fp_set_eq:NN} \meta{fp~var_1} \meta{fp~var_2}
+% \end{syntax}
+% Sets the floating point variable \meta{fp~var_1} equal to the current
+% value of \meta{fp~var_2}.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp002]
+% {\fp_add:Nn, \fp_add:cn, \fp_gadd:Nn, \fp_gadd:cn}
+% \begin{syntax}
+% \cs{fp_add:Nn} \meta{fp~var} \Arg{floating point expression}
+% \end{syntax}
+% Adds the result of computing the \meta{floating point expression} to
+% the \meta{fp~var}.
+% This also applies if \meta{fp~var} and \meta{floating point
+% expression} evaluate to tuples of the same size.
+% \end{function}
+%
+% \begin{function}[updated = 2012-05-08, tested = m3fp002]
+% {\fp_sub:Nn, \fp_sub:cn, \fp_gsub:Nn, \fp_gsub:cn}
+% \begin{syntax}
+% \cs{fp_sub:Nn} \meta{fp~var} \Arg{floating point expression}
+% \end{syntax}
+% Subtracts the result of computing the \meta{floating point
+% expression} from the \meta{fp~var}.
+% This also applies if \meta{fp~var} and \meta{floating point
+% expression} evaluate to tuples of the same size.
+% \end{function}
+%
+% \section{Using floating points}
+%
+% \begin{function}[EXP, added = 2012-05-08, updated = 2012-07-08,
+% tested = m3fp-convert003]{\fp_eval:n}
+% \begin{syntax}
+% \cs{fp_eval:n} \Arg{floating point expression}
+% \end{syntax}
+% Evaluates the \meta{floating point expression} and expresses the
+% result as a decimal number with no
+% exponent. Leading or trailing zeros may be inserted to compensate
+% for the exponent. Non-significant trailing zeros are trimmed, and
+% integers are expressed without a decimal separator. The values
+% $\pm\infty$ and \nan{} trigger an \enquote{invalid operation}
+% exception.
+% For a tuple, each item is converted using \cs{fp_eval:n} and they are combined as
+% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
+% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
+% This function is identical to \cs{fp_to_decimal:n}.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2012-05-08, updated = 2012-07-08]
+% {\fp_to_decimal:N, \fp_to_decimal:c, \fp_to_decimal:n}
+% \begin{syntax}
+% \cs{fp_to_decimal:N} \meta{fp~var}
+% \cs{fp_to_decimal:n} \Arg{floating point expression}
+% \end{syntax}
+% Evaluates the \meta{floating point expression} and expresses the
+% result as a decimal number with no
+% exponent. Leading or trailing zeros may be inserted to compensate
+% for the exponent. Non-significant trailing zeros are trimmed, and
+% integers are expressed without a decimal separator. The values
+% $\pm\infty$ and~\nan{} trigger an \enquote{invalid operation}
+% exception.
+% For a tuple, each item is converted using \cs{fp_to_decimal:n} and they are combined as
+% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
+% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2016-03-22]
+% {\fp_to_dim:N, \fp_to_dim:c, \fp_to_dim:n}
+% \begin{syntax}
+% \cs{fp_to_dim:N} \meta{fp~var}
+% \cs{fp_to_dim:n} \Arg{floating point expression}
+% \end{syntax}
+% Evaluates the \meta{floating point expression} and expresses the
+% result as a dimension (in~\texttt{pt}) suitable for use in dimension
+% expressions. The output is identical to \cs{fp_to_decimal:n}, with
+% an additional trailing~\texttt{pt} (both letter tokens).
+% In particular, the result may
+% be outside the range $[- 2^{14} + 2^{-17}, 2^{14} - 2^{-17}]$ of
+% valid \TeX{} dimensions, leading to overflow errors if used as a
+% dimension. Tuples, as well as the values $\pm\infty$ and~\nan{},
+% trigger an \enquote{invalid operation} exception.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2012-07-08]
+% {\fp_to_int:N, \fp_to_int:c, \fp_to_int:n}
+% \begin{syntax}
+% \cs{fp_to_int:N} \meta{fp~var}
+% \cs{fp_to_int:n} \Arg{floating point expression}
+% \end{syntax}
+% Evaluates the \meta{floating point expression}, and rounds the
+% result to the closest integer, rounding exact ties to an even
+% integer.
+% The result may be outside the range $[- 2^{31} + 1, 2^{31} - 1]$ of
+% valid \TeX{}~integers, leading to overflow errors if used in an
+% integer expression. Tuples, as well as the values $\pm\infty$
+% and~\nan{}, trigger an \enquote{invalid operation} exception.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2012-05-08, updated = 2016-03-22]
+% {\fp_to_scientific:N, \fp_to_scientific:c, \fp_to_scientific:n}
+% \begin{syntax}
+% \cs{fp_to_scientific:N} \meta{fp~var}
+% \cs{fp_to_scientific:n} \Arg{floating point expression}
+% \end{syntax}
+% Evaluates the \meta{floating point expression} and expresses the
+% result in scientific notation:
+% \begin{quote}
+% \meta{optional \texttt{-}}\meta{digit}\texttt{.}\meta{15 digits}\texttt{e}\meta{optional sign}\meta{exponent}
+% \end{quote}
+% The leading \meta{digit} is non-zero except in the case of $\pm 0$.
+% The values $\pm\infty$ and~\nan{} trigger an \enquote{invalid
+% operation} exception. Normal category codes apply: thus the |e| is
+% category code~$11$ (a letter).
+% For a tuple, each item is converted using \cs{fp_to_scientific:n} and they are combined as
+% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
+% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2016-03-22]
+% {\fp_to_tl:N, \fp_to_tl:c, \fp_to_tl:n}
+% \begin{syntax}
+% \cs{fp_to_tl:N} \meta{fp~var}
+% \cs{fp_to_tl:n} \Arg{floating point expression}
+% \end{syntax}
+% Evaluates the \meta{floating point expression} and expresses the
+% result in (almost) the shortest possible form. Numbers in the
+% ranges $(0,10^{-3})$ and $[10^{16},\infty)$ are expressed in
+% scientific notation with trailing zeros trimmed and no decimal
+% separator when there is a single significant digit (this differs from
+% \cs{fp_to_scientific:n}). Numbers in the range $[10^{-3},10^{16})$
+% are expressed in a decimal notation without exponent, with trailing
+% zeros trimmed, and no decimal separator for integer values (see
+% \cs{fp_to_decimal:n}. Negative numbers start with~|-|. The
+% special values $\pm 0$, $\pm\infty$ and~\nan{} are rendered as
+% |0|, |-0|, \texttt{inf}, \texttt{-inf}, and~\texttt{nan}
+% respectively. Normal category codes apply and thus \texttt{inf} or
+% \texttt{nan}, if produced, are made up of letters.
+% For a tuple, each item is converted using \cs{fp_to_tl:n} and they are combined as
+% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
+% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2012-07-08]
+% {\fp_use:N, \fp_use:c}
+% \begin{syntax}
+% \cs{fp_use:N} \meta{fp~var}
+% \end{syntax}
+% Inserts the value of the \meta{fp~var} into the input stream as a
+% decimal number with no exponent.
+% Leading or trailing zeros may be inserted to compensate for the
+% exponent. Non-significant trailing zeros are trimmed. Integers are
+% expressed without a decimal separator. The values $\pm\infty$
+% and~\nan{} trigger an \enquote{invalid operation} exception.
+% For a tuple, each item is converted using \cs{fp_to_decimal:n} and they are combined as
+% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
+% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
+% This function is identical to \cs{fp_to_decimal:N}.
+% \end{function}
+%
+% \section{Floating point conditionals}
+%
+% \begin{function}[EXP, pTF, updated = 2012-05-08, tested = m3fp002]
+% {\fp_if_exist:N, \fp_if_exist:c}
+% \begin{syntax}
+% \cs{fp_if_exist_p:N} \meta{fp~var}
+% \cs{fp_if_exist:NTF} \meta{fp~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{fp~var} is currently defined. This does not
+% check that the \meta{fp~var} really is a floating point variable.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, updated = 2012-05-08,
+% tested = m3fp-logic001]{\fp_compare:nNn}
+% \begin{syntax}
+% \cs{fp_compare_p:nNn} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2}
+% \cs{fp_compare:nNnTF} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Compares the \meta{fpexpr_1} and the \meta{fpexpr_2}, and returns
+% \texttt{true} if the \meta{relation} is obeyed. Two floating points
+% $x$ and~$y$ may obey four mutually exclusive relations:
+% $x<y$, $x=y$, $x>y$, or $x?y$ (\enquote{not ordered}). The last
+% case occurs exactly if one or both operands is~\nan{} or is a tuple,
+% unless they are equal tuples. Note that a~\nan{} is distinct from
+% any value, even another~\nan{}, hence $x=x$ is not true for
+% a~\nan{}. To test if a value is~\nan{}, compare it to an arbitrary
+% number with the \enquote{not ordered} relation.
+% \begin{verbatim}
+% \fp_compare:nNnTF { <value> } ? { 0 }
+% { } % <value> is nan
+% { } % <value> is not nan
+% \end{verbatim}
+% Tuples are equal if they have the same number of items and items
+% compare equal (in particular there must be no~\nan{}).
+% At present any other comparison with tuples yields |?| (not ordered).
+% This is experimental.
+%
+% This function is less flexible than \cs{fp_compare:nTF} but slightly
+% faster. It is provided for consistency with \cs{int_compare:nNnTF}
+% and \cs{dim_compare:nNnTF}.
+% \end{function}
+%
+% \begin{function}[EXP, pTF, updated = 2013-12-14,
+% tested = m3fp-logic001]{\fp_compare:n}
+% \begin{syntax}
+% \cs{fp_compare_p:n} \\
+% ~~\{ \\
+% ~~~~\meta{fpexpr_1} \meta{relation_1} \\
+% ~~~~\ldots{} \\
+% ~~~~\meta{fpexpr_N} \meta{relation_N} \\
+% ~~~~\meta{fpexpr_{N+1}} \\
+% ~~\} \\
+% \cs{fp_compare:nTF}
+% ~~\{ \\
+% ~~~~\meta{fpexpr_1} \meta{relation_1} \\
+% ~~~~\ldots{} \\
+% ~~~~\meta{fpexpr_N} \meta{relation_N} \\
+% ~~~~\meta{fpexpr_{N+1}} \\
+% ~~\} \\
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Evaluates the \meta{floating point expressions} as described for
+% \cs{fp_eval:n} and compares consecutive result using the
+% corresponding \meta{relation}, namely it compares \meta{intexpr_1}
+% and \meta{intexpr_2} using the \meta{relation_1}, then
+% \meta{intexpr_2} and \meta{intexpr_3} using the \meta{relation_2},
+% until finally comparing \meta{intexpr_N} and \meta{intexpr_{N+1}}
+% using the \meta{relation_N}. The test yields \texttt{true} if all
+% comparisons are \texttt{true}. Each \meta{floating point
+% expression} is evaluated only once. Contrarily to
+% \cs{int_compare:nTF}, all \meta{floating point expressions} are
+% computed, even if one comparison is \texttt{false}. Two floating
+% points $x$ and~$y$ may obey four mutually exclusive
+% relations: $x<y$, $x=y$, $x>y$, or $x?y$ (\enquote{not ordered}).
+% The last case occurs exactly if one or both operands is~\nan{} or is
+% a tuple, unless they are equal tuples. Each \meta{relation}
+% can be any (non-empty) combination of |<|, |=|, |>|, and~|?|, plus
+% an optional leading~|!| (which negates the \meta{relation}), with
+% the restriction that the \meta{relation} may not start with~|?|, as
+% this symbol has a different meaning (in combination with~|:|) within
+% floating point expressions. The comparison $x$~\meta{relation}~$y$
+% is then \texttt{true} if the \meta{relation} does not start with~|!|
+% and the actual relation (|<|, |=|, |>|, or~|?|) between $x$ and~$y$
+% appears within the \meta{relation}, or on the contrary if the
+% \meta{relation} starts with~|!| and the relation between $x$ and~$y$
+% does not appear within the \meta{relation}. Common choices of
+% \meta{relation} include |>=|~(greater or equal), |!=|~(not equal),
+% |!?|~or~|<=>| (comparable).
+%
+% This function is more flexible than \cs{fp_compare:nNnTF} and only
+% slightly slower.
+% \end{function}
+%
+% \section{Floating point expression loops}
+%
+% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003]
+% {\fp_do_until:nNnn}
+% \begin{syntax}
+% \cs{fp_do_until:nNnn} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process,
+% and then evaluates the relationship between the two \meta{floating
+% point expressions} as described for \cs{fp_compare:nNnTF}. If the
+% test is \texttt{false} then the \meta{code} is inserted into
+% the input stream again and a loop occurs until the
+% \meta{relation} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003]
+% {\fp_do_while:nNnn}
+% \begin{syntax}
+% \cs{fp_do_while:nNnn} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process,
+% and then evaluates the relationship between the two \meta{floating
+% point expressions} as described for \cs{fp_compare:nNnTF}. If the
+% test is \texttt{true} then the \meta{code} is inserted into the
+% input stream again and a loop occurs until the \meta{relation}
+% is \texttt{false}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003]
+% {\fp_until_do:nNnn}
+% \begin{syntax}
+% \cs{fp_until_do:nNnn} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{floating point
+% expressions} as described for \cs{fp_compare:nNnTF}, and then
+% places the \meta{code} in the input stream if the \meta{relation} is
+% \texttt{false}. After the \meta{code} has been processed by \TeX{}
+% the test is repeated, and a loop occurs until the test is
+% \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003]
+% {\fp_while_do:nNnn}
+% \begin{syntax}
+% \cs{fp_while_do:nNnn} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{floating point
+% expressions} as described for \cs{fp_compare:nNnTF}, and then
+% places the \meta{code} in the input stream if the \meta{relation} is
+% \texttt{true}. After the \meta{code} has been processed by \TeX{}
+% the test is repeated, and a loop occurs until the test is
+% \texttt{false}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2012-08-16, updated = 2013-12-14, tested = m3fp-logic003]
+% {\fp_do_until:nn}
+% \begin{syntax}
+% \cs{fp_do_until:nn} \{ \meta{fpexpr_1} \meta{relation} \meta{fpexpr_2} \} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process,
+% and then evaluates the relationship between the two \meta{floating
+% point expressions} as described for \cs{fp_compare:nTF}. If the
+% test is \texttt{false} then the \meta{code} is inserted into
+% the input stream again and a loop occurs until the
+% \meta{relation} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2012-08-16, updated = 2013-12-14, tested = m3fp-logic003]
+% {\fp_do_while:nn}
+% \begin{syntax}
+% \cs{fp_do_while:nn} \{ \meta{fpexpr_1} \meta{relation} \meta{fpexpr_2} \} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process,
+% and then evaluates the relationship between the two \meta{floating
+% point expressions} as described for \cs{fp_compare:nTF}. If the
+% test is \texttt{true} then the \meta{code} is inserted into the
+% input stream again and a loop occurs until the \meta{relation}
+% is \texttt{false}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2012-08-16, updated = 2013-12-14, tested = m3fp-logic003]
+% {\fp_until_do:nn}
+% \begin{syntax}
+% \cs{fp_until_do:nn} \{ \meta{fpexpr_1} \meta{relation} \meta{fpexpr_2} \} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{floating point
+% expressions} as described for \cs{fp_compare:nTF}, and then places
+% the \meta{code} in the input stream if the \meta{relation} is
+% \texttt{false}. After the \meta{code} has been processed by \TeX{}
+% the test is repeated, and a loop occurs until the test is
+% \texttt{true}.
+% \end{function}
+%
+% \begin{function}[rEXP, added = 2012-08-16, updated = 2013-12-14, tested = m3fp-logic003]
+% {\fp_while_do:nn}
+% \begin{syntax}
+% \cs{fp_while_do:nn} \{ \meta{fpexpr_1} \meta{relation} \meta{fpexpr_2} \} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{floating point
+% expressions} as described for \cs{fp_compare:nTF}, and then places
+% the \meta{code} in the input stream if the \meta{relation} is
+% \texttt{true}. After the \meta{code} has been processed by \TeX{}
+% the test is repeated, and a loop occurs until the test is
+% \texttt{false}.
+% \end{function}
+%
+% \begin{function}[added = 2016-11-21, updated = 2016-12-06, rEXP]
+% {\fp_step_function:nnnN, \fp_step_function:nnnc}
+% \begin{syntax}
+% \cs{fp_step_function:nnnN} \Arg{initial value} \Arg{step} \Arg{final value} \meta{function}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, each of which should be a floating point
+% expression evaluating to a floating point number, not a tuple.
+% The \meta{function} is then placed in front of each \meta{value}
+% from the \meta{initial value} to the \meta{final value} in turn
+% (using \meta{step} between each \meta{value}). The \meta{step} must
+% be non-zero. If the \meta{step} is positive, the loop stops when
+% the \meta{value} becomes larger than the \meta{final value}. If the
+% \meta{step} is negative, the loop stops when the \meta{value}
+% becomes smaller than the \meta{final value}. The \meta{function}
+% should absorb one numerical argument. For example
+% \begin{verbatim}
+% \cs_set:Npn \my_func:n #1 { [I~saw~#1] \quad }
+% \fp_step_function:nnnN { 1.0 } { 0.1 } { 1.5 } \my_func:n
+% \end{verbatim}
+% would print
+% \begin{quote}
+% [I saw 1.0] \quad
+% [I saw 1.1] \quad
+% [I saw 1.2] \quad
+% [I saw 1.3] \quad
+% [I saw 1.4] \quad
+% [I saw 1.5] \quad
+% \end{quote}
+% \begin{texnote}
+% Due to rounding, it may happen that adding the \meta{step} to the
+% \meta{value} does not change the \meta{value}; such cases give an
+% error, as they would otherwise lead to an infinite loop.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2016-11-21, updated = 2016-12-06]
+% {\fp_step_inline:nnnn}
+% \begin{syntax}
+% \cs{fp_step_inline:nnnn} \Arg{initial value} \Arg{step} \Arg{final value} \Arg{code}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, all of which should be floating point
+% expressions evaluating to a floating point number, not a tuple.
+% Then for each \meta{value} from the \meta{initial value} to the
+% \meta{final value} in turn (using \meta{step} between each
+% \meta{value}), the \meta{code} is inserted into the input stream
+% with |#1| replaced by the current \meta{value}. Thus the
+% \meta{code} should define a function of one argument~(|#1|).
+% \end{function}
+%
+% \begin{function}[added = 2017-04-12]{\fp_step_variable:nnnNn}
+% \begin{syntax}
+% \cs{fp_step_variable:nnnNn} \\
+% ~~\Arg{initial value} \Arg{step} \Arg{final value} \meta{tl~var} \Arg{code}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, all of which should be floating point
+% expressions evaluating to a floating point number, not a tuple.
+% Then for each \meta{value} from the \meta{initial value} to the
+% \meta{final value} in turn (using \meta{step} between each
+% \meta{value}), the \meta{code} is inserted into the input stream,
+% with the \meta{tl~var} defined as the current \meta{value}. Thus
+% the \meta{code} should make use of the \meta{tl~var}.
+% \end{function}
+%
+% \section{Some useful constants, and scratch variables}
+%
+% \begin{variable}[added = 2012-05-08]{\c_zero_fp, \c_minus_zero_fp}
+% Zero, with either sign.
+% \end{variable}
+%
+% \begin{variable}[added = 2012-05-08]{\c_one_fp}
+% One as an \texttt{fp}: useful for comparisons in some places.
+% \end{variable}
+%
+% \begin{variable}[added = 2012-05-08]{\c_inf_fp, \c_minus_inf_fp}
+% Infinity, with either sign. These can be input directly in a
+% floating point expression as \texttt{inf} and \texttt{-inf}.
+% \end{variable}
+%
+% \begin{variable}[updated = 2012-05-08]{\c_e_fp}
+% The value of the base of the natural logarithm, $\mathrm{e} = \exp(1)$.
+% \end{variable}
+%
+% \begin{variable}[updated = 2013-11-17]{\c_pi_fp}
+% The value of~$\pi$. This can be input directly in a floating point
+% expression as~\texttt{pi}.
+% \end{variable}
+%
+% \begin{variable}[added = 2012-05-08, updated = 2013-11-17]
+% {\c_one_degree_fp}
+% The value of $1^{\circ}$ in radians. Multiply an angle given in
+% degrees by this value to obtain a result in radians. Note that
+% trigonometric functions expecting an argument in radians or in
+% degrees are both available. Within floating point expressions, this
+% can be accessed as \texttt{deg}.
+% \end{variable}
+%
+% \begin{variable}{\l_tmpa_fp, \l_tmpb_fp}
+% Scratch floating points for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_fp, \g_tmpb_fp}
+% Scratch floating points for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Floating point exceptions}
+% \label{sec:l3fp:fp-exceptions}
+%
+% \emph{The functions defined in this section are experimental, and
+% their functionality may be altered or removed altogether.}
+%
+% \enquote{Exceptions} may occur when performing some floating point
+% operations, such as \texttt{0 / 0}, or \texttt{10 ** 1e9999}. The
+% relevant \textsc{IEEE} standard defines $5$ types of exceptions,
+% of which we implement~$4$.
+% \begin{itemize}
+% \item \emph{Overflow} occurs whenever the result of an operation is
+% too large to be represented as a normal floating point number. This
+% results in $\pm \infty$.
+% \item \emph{Underflow} occurs whenever the result of an operation is
+% too close to $0$ to be represented as a normal floating point
+% number. This results in $\pm 0$.
+% \item \emph{Invalid operation} occurs for operations with no defined
+% outcome, for instance $0/0$ or $\sin(\infty)$, and results in a \nan{}.
+% It also occurs for conversion functions whose target type does not
+% have the appropriate infinite or \nan{} value (\emph{e.g.},
+% \cs{fp_to_dim:n}).
+% \item \emph{Division by zero} occurs when dividing a non-zero number
+% by $0$, or when evaluating functions at poles, \emph{e.g.},
+% $\ln(0)$ or $\cot(0)$. This results in $\pm\infty$.
+% \item [\emph{(not yet)}] \emph{Inexact} occurs whenever the result of
+% a computation is not exact, in other words, almost always. At the
+% moment, this exception is entirely ignored in \LaTeX3.
+% \end{itemize}
+% To each exception we associate a \enquote{flag}: \texttt{fp_overflow},
+% \texttt{fp_underflow}, \texttt{fp_invalid_operation} and
+% \texttt{fp_division_by_zero}. The state of these flags can be tested
+% and modified with commands from \pkg{l3flag}
+%
+% By default, the \enquote{invalid operation} exception triggers an
+% (expandable) error, and raises the corresponding flag. Other
+% exceptions raise the corresponding flag but do not trigger an error.
+% The behaviour when an exception occurs can be modified (using
+% \cs{fp_trap:nn}) to either produce an error and raise the flag, or
+% only raise the flag, or do nothing at all.
+%
+% \begin{function}[added = 2012-07-19, updated = 2017-02-13,
+% tested = m3fp-traps001]{\fp_trap:nn}
+% \begin{syntax}
+% \cs{fp_trap:nn} \Arg{exception} \Arg{trap type}
+% \end{syntax}
+% All occurrences of the \meta{exception} (\texttt{overflow},
+% \texttt{underflow}, \texttt{invalid_operation} or
+% \texttt{division_by_zero}) within the current
+% group are treated as \meta{trap type}, which can be
+% \begin{itemize}
+% \item \texttt{none}: the \meta{exception} will be entirely
+% ignored, and leave no trace;
+% \item \texttt{flag}: the \meta{exception} will turn the
+% corresponding flag on when it occurs;
+% \item \texttt{error}: additionally, the \meta{exception} will halt
+% the \TeX{} run and display some information about the current
+% operation in the terminal.
+% \end{itemize}
+% \emph{This function is experimental, and may be altered or removed.}
+% \end{function}
+%
+% \begin{variable}
+% {
+% flag fp_overflow,
+% flag fp_underflow,
+% flag fp_invalid_operation,
+% flag fp_division_by_zero
+% }
+% Flags denoting the occurrence of various floating-point exceptions.
+% \end{variable}
+%
+% \section{Viewing floating points}
+%
+% \begin{function}[added = 2012-05-08, updated = 2015-08-07,
+% tested = m3fp002]{\fp_show:N, \fp_show:c, \fp_show:n}
+% \begin{syntax}
+% \cs{fp_show:N} \meta{fp~var}
+% \cs{fp_show:n} \Arg{floating point expression}
+% \end{syntax}
+% Evaluates the \meta{floating point expression} and displays the
+% result in the terminal.
+% \end{function}
+%
+% \begin{function}[added = 2014-08-22, updated = 2015-08-07]
+% {\fp_log:N, \fp_log:c, \fp_log:n}
+% \begin{syntax}
+% \cs{fp_log:N} \meta{fp~var}
+% \cs{fp_log:n} \Arg{floating point expression}
+% \end{syntax}
+% Evaluates the \meta{floating point expression} and writes the
+% result in the log file.
+% \end{function}
+%
+% \section{Floating point expressions}
+%
+% \subsection{Input of floating point numbers} \label{sec:l3fp:fp-floats}
+%
+% We support four types of floating point numbers:
+% \begin{itemize}
+% \item $\pm m \cdot 10^{n}$, a floating
+% point number, with integer $1\leq m\leq 10^{16}$, and
+% $-{\ExplSyntaxOn\int_use:N\c__fp_minus_min_exponent_int}\leq
+% n\leq {\ExplSyntaxOn\int_use:N\c__fp_max_exponent_int}$;
+% \item $\pm 0$, zero, with a given sign;
+% \item $\pm \infty$, infinity, with a given sign;
+% \item \nan{}, is \enquote{not a number}, and can be either quiet
+% or signalling (\emph{not yet}: this distinction is currently
+% unsupported);
+% \end{itemize}
+% Normal floating point numbers are stored in base $10$, with up to $16$
+% significant figures.
+%
+% On input, a normal floating point number consists of:
+% \begin{itemize}
+% \item \meta{sign}: a possibly empty string of |+| and |-| characters;
+% \item \meta{significand}: a non-empty string of digits together with zero
+% or one dot;
+% \item \meta{exponent} optionally: the character |e|, followed by a
+% possibly empty string of |+|~and~|-| tokens, and a non-empty string
+% of digits.
+% \end{itemize}
+% The sign of the resulting number is |+| if \meta{sign} contains an
+% even number of |-|, and |-| otherwise, hence, an empty \meta{sign}
+% denotes a non-negative input. The stored significand is obtained from
+% \meta{significand} by omitting the decimal separator and leading zeros,
+% and rounding to $16$ significant digits, filling with trailing zeros
+% if necessary. In particular, the value stored is exact if the input
+% \meta{significand} has at most $16$ digits. The stored \meta{exponent}
+% is obtained by combining the input \meta{exponent} ($0$ if absent)
+% with a shift depending on the position of the significand and the number
+% of leading zeros.
+%
+% A special case arises if the resulting \meta{exponent} is either too
+% large or too small for the floating point number to be
+% represented. This results either in an overflow (the number is then
+% replaced by $\pm\infty$), or an underflow (resulting in $\pm 0$).
+%
+% The result is thus $\pm 0$ if and only if \meta{significand} contains no
+% non-zero digit (\emph{i.e.}, consists only in characters~|0|, and an
+% optional period), or if there is an underflow. Note that a
+% single dot is currently a valid floating point number, equal to~$+0$,
+% but that is not guaranteed to remain true.
+%
+% The \meta{significand} must be non-empty, so |e1| and |e-1| are not
+% valid floating point numbers. Note that the latter could be mistaken
+% with the difference of \enquote{\texttt{e}} and $1$. To avoid
+% confusions, the base of natural logarithms cannot be input as |e| and
+% should be input as \texttt{exp(1)} or \cs{c_e_fp}.
+%
+% Special numbers are input as follows:
+% \begin{itemize}
+% \item \texttt{inf} represents $+\infty$, and can be preceded by any
+% \meta{sign}, yielding $\pm\infty$ as appropriate.
+% \item \texttt{nan} represents a (quiet) non-number. It can be
+% preceded by any sign, but that sign is ignored.
+% \item Any unrecognizable string triggers an error, and produces a
+% \nan{}.
+% \item Note that commands such as \tn{infty}, \tn{pi}, or \tn{sin}
+% \emph{do not} work in floating point expressions. They may
+% silently be interpreted as completely unexpected numbers, because
+% integer constants (allowed in expressions) are commonly stored as
+% mathematical characters.
+% \end{itemize}
+%
+% \subsection{Precedence of operators}
+% \label{sec:l3fp:fp-precedence}
+%
+% We list here all the operations supported in floating point
+% expressions, in order of decreasing precedence: operations listed
+% earlier bind more tightly than operations listed below them.
+% \begin{itemize}
+% \item Function calls (\texttt{sin}, \texttt{ln}, \emph{etc}).
+% \item Binary |**| and |^| (right associative).
+% \item Unary |+|, |-|, |!|.
+% \item Implicit multiplication by juxtaposition (\texttt{2pi})
+% when neither factor is in parentheses.
+% \item Binary |*| and |/|, implicit multiplication by juxtaposition with parentheses (for instance \texttt{3(4+5)}).
+% \item Binary |+| and |-|.
+% \item Comparisons |>=|, |!=|, |<?|, \emph{etc}.
+% \item Logical \texttt{and}, denoted by |&&|.
+% \item Logical \texttt{or}, denoted by \verb+||+.
+% \item Ternary operator |?:| (right associative).
+% \item Comma (to build tuples).
+% \end{itemize}
+% The precedence of operations can be overridden using parentheses.
+% In particular, the precedence of juxtaposition implies that
+% \begin{align*}
+% \mathtt{1/2pi} & = 1/(2\pi), \\
+% \mathtt{1/2pi(pi+pi)} & = (2\pi)^{-1}(\pi+\pi) \simeq 1, \\
+% \mathtt{sin 2pi} & = \sin(2)\pi \neq 0, \\
+% \mathtt{2\char`\^2max(3,5)} & = 2^2 \max(3,5) = 20, \\
+% \mathtt{1in/1cm} & = (1in)/(1cm) = 2.54 .
+% \end{align*}
+% Functions are called on the value of their argument, contrarily to
+% \TeX{} macros.
+%
+% \subsection{Operations} \label{sec:l3fp:fp-operations}
+%
+% We now present the various operations allowed in floating point
+% expressions, from the lowest precedence to the highest. When used as
+% a truth value, a floating point expression is \texttt{false} if it is
+% $\pm 0$, and \texttt{true} otherwise, including when it is \nan{} or a
+% tuple such as $(0,0)$. Tuples are only supported to some extent by
+% operations that work with truth values (|?:|, \verb"||", |&&|, |!|),
+% by comparisons (|!<=>?|), and by |+|, |-|, |*|, |/|. Unless otherwise
+% specified, providing a tuple as an argument of any other operation
+% yields the \enquote{invalid operation} exception and a \nan{} result.
+%
+% \begin{function}[tested = m3fp-logic002]{?:}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ \meta{operand_1} |?| \meta{operand_2} |:| \meta{operand_3} \}
+% \end{syntax}
+% The ternary operator |?:| results in \meta{operand_2} if
+% \meta{operand_1} is true (not $\pm 0$), and \meta{operand_3} if \meta{operand_1}
+% is false ($\pm 0$). All three \meta{operands} are evaluated in all
+% cases; they may be tuples. The operator is right associative, hence
+% \begin{verbatim}
+% \fp_eval:n
+% {
+% 1 + 3 > 4 ? 1 :
+% 2 + 4 > 5 ? 2 :
+% 3 + 5 > 6 ? 3 : 4
+% }
+% \end{verbatim}
+% first tests whether $1 + 3 > 4$; since this isn't true, the branch
+% following |:| is taken, and $2 + 4 > 5$ is compared; since this is
+% true, the branch before |:| is taken, and everything else is
+% (evaluated then) ignored. That allows testing for various cases in
+% a concise manner, with the drawback that all computations are made
+% in all cases.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-logic002]{||}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ \meta{operand_1} \verb"||" \meta{operand_2} \}
+% \end{syntax}
+% If \meta{operand_1} is true (not $\pm 0$), use that value, otherwise the
+% value of \meta{operand_2}. Both \meta{operands} are evaluated in all
+% cases; they may be tuples. In \meta{operand_1} \verb"||"
+% \meta{operand_2} \verb"||" \ldots{} \verb"||" \meta{operands_n}, the
+% first true (nonzero) \meta{operand} is used and if all are zero the
+% last one ($\pm 0$) is used.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-logic002]{&&}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ \meta{operand_1} |&&| \meta{operand_2} \}
+% \end{syntax}
+% If \meta{operand_1} is false (equal to~$\pm 0$), use that value,
+% otherwise the value of \meta{operand_2}. Both \meta{operands} are
+% evaluated in all cases; they may be tuples. In \meta{operand_1}
+% |&&| \meta{operand_2} |&&| \ldots{} |&&| \meta{operands_n}, the
+% first false ($\pm 0$) \meta{operand} is used and if none is zero the
+% last one is used.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-logic001, updated = 2013-12-14]
+% {<, =, >, ?}
+% \begin{syntax}
+% \cs{fp_eval:n} \\
+% ~~\{ \\
+% ~~~~\meta{operand_1} \meta{relation_1} \\
+% ~~~~\ldots{} \\
+% ~~~~\meta{operand_N} \meta{relation_N} \\
+% ~~~~\meta{operand_{N+1}} \\
+% ~~\}
+% \end{syntax}
+% Each \meta{relation} consists of a non-empty string of |<|, |=|,
+% |>|, and~|?|, optionally preceded by~|!|, and may not start
+% with~|?|. This evaluates to $+1$ if all comparisons
+% \meta{operand_i} \meta{relation_i} \meta{operand_{i+1}} are true, and
+% $+0$ otherwise. All \meta{operands} are evaluated (once) in all cases.
+% See \cs{fp_compare:nTF} for details.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-basics001]{+, -}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ \meta{operand_1} |+| \meta{operand_2} \}
+% \cs{fp_eval:n} \{ \meta{operand_1} |-| \meta{operand_2} \}
+% \end{syntax}
+% Computes the sum or the difference of its two \meta{operands}. The
+% \enquote{invalid operation} exception occurs for $\infty-\infty$.
+% \enquote{Underflow} and \enquote{overflow} occur when appropriate.
+% These operations supports the itemwise addition or subtraction of
+% two tuples, but if they have a different number of items the
+% \enquote{invalid operation} exception occurs and the result is \nan{}.
+% \end{function}
+%
+% \begin{function}[tested = {m3fp-basics002, m3fp-basics003}]{*, /}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ \meta{operand_1} |*| \meta{operand_2} \}
+% \cs{fp_eval:n} \{ \meta{operand_1} |/| \meta{operand_2} \}
+% \end{syntax}
+% Computes the product or the ratio of its two \meta{operands}. The
+% \enquote{invalid operation} exception occurs for $\infty/\infty$,
+% $0/0$, or $0*\infty$. \enquote{Division by zero} occurs when
+% dividing a finite non-zero number by $\pm 0$. \enquote{Underflow}
+% and \enquote{overflow} occur when appropriate.
+% When \meta{operand_1} is a tuple and \meta{operand_2} is a floating
+% point number, each item of \meta{operand_1} is multiplied or divided
+% by \meta{operand_2}. Multiplication also supports the case where
+% \meta{operand_1} is a floating point number and \meta{operand_2} a
+% tuple. Other combinations yield an \enquote{invalid operation}
+% exception and a \nan{} result.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-basics004, label = !]{+, -, !}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |+| \meta{operand} \}
+% \cs{fp_eval:n} \{ |-| \meta{operand} \}
+% \cs{fp_eval:n} \{ |!| \meta{operand} \}
+% \end{syntax}
+% The unary |+| does nothing, the unary |-| changes the sign of the
+% \meta{operand} (for a tuple, of all its components), and
+% |!| \meta{operand} evaluates to $1$ if \meta{operand} is false
+% (is $\pm 0$) and $0$ otherwise (this is the \texttt{not}
+% boolean function). Those operations never raise exceptions.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-expo001]{**, ^}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ \meta{operand_1} |**| \meta{operand_2} \}
+% \cs{fp_eval:n} \{ \meta{operand_1} |^| \meta{operand_2} \}
+% \end{syntax}
+% Raises \meta{operand_1} to the power \meta{operand_2}. This
+% operation is right associative, hence \texttt{2 ** 2 ** 3} equals
+% $2^{2^{3}} = 256$. If \meta{operand_1} is negative or $-0$ then:
+% the result's sign is $+$ if the \meta{operand_2} is infinite and
+% $(-1)^p$ if the \meta{operand_2} is $p/5^q$ with $p$, $q$ integers;
+% the result is $+0$ if
+% |abs(|\meta{operand_1}|)^|\meta{operand_2} evaluates to zero; in
+% other cases the \enquote{invalid operation} exception occurs because
+% the sign cannot be determined. \enquote{Division by zero} occurs
+% when raising $\pm 0$ to a finite strictly negative power.
+% \enquote{Underflow} and \enquote{overflow} occur when appropriate.
+% If either operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-basics004]{abs}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |abs(| \meta{fpexpr} |)| \}
+% \end{syntax}
+% Computes the absolute value of the \meta{fpexpr}. If the operand is
+% a tuple, \enquote{invalid operation} occurs. This operation does
+% not raise exceptions in other cases. See also \cs{fp_abs:n}.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-expo001]{exp}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |exp(| \meta{fpexpr} |)| \}
+% \end{syntax}
+% Computes the exponential of the \meta{fpexpr}. \enquote{Underflow}
+% and \enquote{overflow} occur when appropriate.
+% If the operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-expo001]{fact}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |fact(| \meta{fpexpr} |)| \}
+% \end{syntax}
+% Computes the factorial of the \meta{fpexpr}. If the \meta{fpexpr}
+% is an integer between $-0$ and $3248$ included, the result is finite
+% and correctly rounded. Larger positive integers give $+\infty$ with
+% \enquote{overflow}, while $|fact(|{+\infty}|)|=+\infty$ and
+% $|fact(nan)|=|nan|$ with no exception. All other inputs give \nan{}
+% with the \enquote{invalid operation} exception.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-expo001]{ln}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |ln(| \meta{fpexpr} |)| \}
+% \end{syntax}
+% Computes the natural logarithm of the \meta{fpexpr}. Negative
+% numbers have no (real) logarithm, hence the \enquote{invalid
+% operation} is raised in that case, including for $\ln(-0)$.
+% \enquote{Division by zero} occurs when evaluating
+% $\ln(+0) = -\infty$. \enquote{Underflow} and \enquote{overflow}
+% occur when appropriate. If the operand is a tuple, \enquote{invalid
+% operation} occurs.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-logic002]{max, min}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |max(| \meta{fpexpr_1} |,| \meta{fpexpr_2} |,| \ldots{} |)| \}
+% \cs{fp_eval:n} \{ |min(| \meta{fpexpr_1} |,| \meta{fpexpr_2} |,| \ldots{} |)| \}
+% \end{syntax}
+% Evaluates each \meta{fpexpr} and computes the largest (smallest) of
+% those. If any of the \meta{fpexpr} is a \nan{} or tuple, the result
+% is \nan{}. If any operand is a tuple, \enquote{invalid operation}
+% occurs; these operations do not raise exceptions in other cases.
+% \end{function}
+%
+% \begin{function}
+% [tested = {m3fp-round001, m3fp-round002}, added = 2013-12-14, updated = 2015-08-08]
+% {round, trunc, ceil, floor}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |round| |(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |round| |(| \meta{fpexpr_1} , \meta{fpexpr_2} |)| \}
+% \cs{fp_eval:n} \{ |round| |(| \meta{fpexpr_1} , \meta{fpexpr_2} , \meta{fpexpr_3} |)| \}
+% \end{syntax}
+% Only |round| accepts a third argument.
+% Evaluates $\meta{fpexpr_1}=x$ and $\meta{fpexpr_2}=n$ and $\meta{fpexpr_3}=t$ then rounds
+% $x$~to $n$~places. If $n$~is an integer, this rounds~$x$ to a
+% multiple of~$10^{-n}$; if $n=+\infty$, this always yields~$x$; if
+% $n=-\infty$, this yields one of $\pm 0$, $\pm\infty$, or~\nan{}; if
+% $n=\nan{}$, this yields \nan{}; if
+% $n$~is neither $\pm\infty$ nor an integer, then an \enquote{invalid
+% operation} exception is raised. When \meta{fpexpr_2} is omitted,
+% $n=0$, \emph{i.e.}, \meta{fpexpr_1} is rounded to an integer. The
+% rounding direction depends on the function.
+% \begin{itemize}
+% \item |round| yields the multiple of~$10^{-n}$ closest to~$x$,
+% with ties ($x$ half-way between two such multiples) rounded
+% as follows. If $t$ is \texttt{nan} (or not given) the even
+% multiple is chosen (\enquote{ties to even}), if $t=\pm 0$ the
+% multiple closest to $0$ is chosen (\enquote{ties to zero}),
+% if $t$ is positive/negative the multiple closest to $\infty$/$-\infty$ is chosen
+% (\enquote{ties towards positive/negative infinity}).
+% \item |floor| yields the largest
+% multiple of~$10^{-n}$ smaller or equal to~$x$ (\enquote{round
+% towards negative infinity});
+% \item |ceil| yields the smallest
+% multiple of~$10^{-n}$ greater or equal to~$x$ (\enquote{round
+% towards positive infinity});
+% \item |trunc| yields a multiple
+% of~$10^{-n}$ with the same sign as~$x$ and with the largest
+% absolute value less that that of~$x$ (\enquote{round towards
+% zero}).
+% \end{itemize}
+% \enquote{Overflow} occurs if $x$~is finite and the result is
+% infinite (this can only happen if $\meta{fpexpr_2}\string<-9984$).
+% If any operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[tested = m3fp-logic002]{sign}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |sign(| \meta{fpexpr} |)| \}
+% \end{syntax}
+% Evaluates the \meta{fpexpr} and determines its sign: $+1$ for
+% positive numbers and for $+\infty$, $-1$ for negative numbers and
+% for $-\infty$, $\pm 0$ for $\pm 0$, and \nan{} for \nan{}.
+% If the operand is a tuple, \enquote{invalid operation} occurs.
+% This operation does not raise exceptions in other cases.
+% \end{function}
+%
+% \begin{function}[updated = 2013-11-17, tested = m3fp-trig001]
+% {sin, cos, tan, cot, csc, sec}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |sin(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |cos(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |tan(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |cot(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |csc(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |sec(| \meta{fpexpr} |)| \}
+% \end{syntax}
+% Computes the sine, cosine, tangent, cotangent, cosecant, or secant
+% of the \meta{fpexpr} given in radians. For arguments given in
+% degrees, see \texttt{sind}, \texttt{cosd}, \emph{etc.} Note that
+% since $\pi$~is irrational, $\operatorname{sin}(8\mathrm{pi})$ is not quite
+% zero, while its analogue $\operatorname{sind}(8\times 180)$ is exactly
+% zero. The trigonometric functions are undefined for
+% an argument of $\pm\infty$, leading to the \enquote{invalid
+% operation} exception. Additionally, evaluating tangent,
+% cotangent, cosecant, or secant at one of their poles leads to a
+% \enquote{division by zero} exception. \enquote{Underflow} and
+% \enquote{overflow} occur when appropriate.
+% If the operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[added = 2013-11-02, tested = m3fp-trig003]
+% {sind, cosd, tand, cotd, cscd, secd}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |sind(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |cosd(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |tand(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |cotd(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |cscd(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |secd(| \meta{fpexpr} |)| \}
+% \end{syntax}
+% Computes the sine, cosine, tangent, cotangent, cosecant, or secant
+% of the \meta{fpexpr} given in degrees. For arguments given in
+% radians, see \texttt{sin}, \texttt{cos}, \emph{etc.} Note that
+% since $\pi$~is irrational, $\operatorname{sin}(8\mathrm{pi})$ is not quite
+% zero, while its analogue $\operatorname{sind}(8\times 180)$ is exactly
+% zero. The trigonometric functions are undefined for
+% an argument of $\pm\infty$, leading to the \enquote{invalid
+% operation} exception. Additionally, evaluating tangent,
+% cotangent, cosecant, or secant at one of their poles leads to a
+% \enquote{division by zero} exception. \enquote{Underflow} and
+% \enquote{overflow} occur when appropriate.
+% If the operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[added = 2013-11-02, tested = m3fp-trig002]
+% {asin, acos, acsc, asec}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |asin(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |acos(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |acsc(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |asec(| \meta{fpexpr} |)| \}
+% \end{syntax}
+% Computes the arcsine, arccosine, arccosecant, or arcsecant of the
+% \meta{fpexpr} and returns the result in radians, in the range
+% $[-\pi/2,\pi/2]$ for \texttt{asin} and \texttt{acsc} and $[0,\pi]$
+% for \texttt{acos} and \texttt{asec}. For a result in degrees, use
+% \texttt{asind}, \emph{etc.} If the argument of |asin| or |acos|
+% lies outside the range $[-1,1]$, or the argument of |acsc| or |asec|
+% inside the range $(-1,1)$, an \enquote{invalid operation} exception
+% is raised. \enquote{Underflow} and \enquote{overflow} occur when
+% appropriate.
+% If the operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[added = 2013-11-02, tested = m3fp-trig004]
+% {asind, acosd, acscd, asecd}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |asind(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |acosd(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |acscd(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |asecd(| \meta{fpexpr} |)| \}
+% \end{syntax}
+% Computes the arcsine, arccosine, arccosecant, or arcsecant of the
+% \meta{fpexpr} and returns the result in degrees, in the range
+% $[-90,90]$ for \texttt{asin} and \texttt{acsc} and $[0,180]$ for
+% \texttt{acos} and \texttt{asec}. For a result in radians, use
+% \texttt{asin}, \emph{etc.} If the argument of |asin| or |acos| lies
+% outside the range $[-1,1]$, or the argument of |acsc| or |asec|
+% inside the range $(-1,1)$, an \enquote{invalid operation} exception
+% is raised. \enquote{Underflow} and \enquote{overflow} occur when
+% appropriate.
+% If the operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[added = 2013-11-02, tested = m3fp-trig002]
+% {atan, acot}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |atan(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |atan(| \meta{fpexpr_1} , \meta{fpexpr_2} |)| \}
+% \cs{fp_eval:n} \{ |acot(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |acot(| \meta{fpexpr_1} , \meta{fpexpr_2} |)| \}
+% \end{syntax}
+% Those functions yield an angle in radians: \texttt{atand} and
+% \texttt{acotd} are their analogs in degrees. The one-argument
+% versions compute the arctangent or arccotangent of the
+% \meta{fpexpr}: arctangent takes values in the range
+% $[-\pi/2,\pi/2]$, and arccotangent in the range $[0,\pi]$. The
+% two-argument arctangent computes the angle in polar coordinates of
+% the point with Cartesian coordinates $(\meta{fpexpr_2},
+% \meta{fpexpr_1})$: this is the arctangent of
+% $\meta{fpexpr_1}/\meta{fpexpr_2}$, possibly shifted by~$\pi$
+% depending on the signs of \meta{fpexpr_1} and \meta{fpexpr_2}. The
+% two-argument arccotangent computes the angle in polar coordinates of
+% the point $(\meta{fpexpr_1}, \meta{fpexpr_2})$, equal to the
+% arccotangent of $\meta{fpexpr_1}/\meta{fpexpr_2}$, possibly shifted
+% by~$\pi$. Both two-argument functions take values in the wider
+% range $[-\pi,\pi]$. The ratio $\meta{fpexpr_1}/\meta{fpexpr_2}$
+% need not be defined for the two-argument arctangent: when both
+% expressions yield~$\pm 0$, or when both yield~$\pm\infty$, the
+% resulting angle is one of $\{\pm\pi/4,\pm 3\pi/4\}$ depending on
+% signs. The \enquote{underflow} exception can occur.
+% If any operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[added = 2013-11-02, tested = m3fp-trig004]
+% {atand, acotd}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |atand(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |atand(| \meta{fpexpr_1} , \meta{fpexpr_2} |)| \}
+% \cs{fp_eval:n} \{ |acotd(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |acotd(| \meta{fpexpr_1} , \meta{fpexpr_2} |)| \}
+% \end{syntax}
+% Those functions yield an angle in degrees: \texttt{atand} and
+% \texttt{acotd} are their analogs in radians. The one-argument
+% versions compute the arctangent or arccotangent of the
+% \meta{fpexpr}: arctangent takes values in the range $[-90,90]$, and
+% arccotangent in the range $[0,180]$. The two-argument arctangent
+% computes the angle in polar coordinates of the point with Cartesian
+% coordinates $(\meta{fpexpr_2}, \meta{fpexpr_1})$: this is the
+% arctangent of $\meta{fpexpr_1}/\meta{fpexpr_2}$, possibly shifted
+% by~$180$ depending on the signs of \meta{fpexpr_1} and
+% \meta{fpexpr_2}. The two-argument arccotangent computes the angle
+% in polar coordinates of the point $(\meta{fpexpr_1},
+% \meta{fpexpr_2})$, equal to the arccotangent of
+% $\meta{fpexpr_1}/\meta{fpexpr_2}$, possibly shifted by~$180$. Both
+% two-argument functions take values in the wider range $[-180,180]$.
+% The ratio $\meta{fpexpr_1}/\meta{fpexpr_2}$ need not be defined for
+% the two-argument arctangent: when both expressions yield~$\pm 0$, or
+% when both yield~$\pm\infty$, the resulting angle is one of $\{\pm
+% 45,\pm 135\}$ depending on signs. The \enquote{underflow}
+% exception can occur.
+% If any operand is a tuple, \enquote{invalid operation} occurs.
+% \end{function}
+%
+% \begin{function}[added = 2013-12-14, tested = m3fp-basics005]{sqrt}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |sqrt(| \meta{fpexpr} |)| \}
+% \end{syntax}
+% Computes the square root of the \meta{fpexpr}. The \enquote{invalid
+% operation} is raised when the \meta{fpexpr} is negative or is a tuple; no other
+% exception can occur. Special values yield $\sqrt{-0} = -0$,
+% $\sqrt{+0} = +0$, $\sqrt{+\infty} = +\infty$ and
+% $\sqrt{\text{\nan{}}}=\text{\nan{}}$.
+% \end{function}
+%
+% \begin{function}[added = 2016-12-05]{rand}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |rand()| \}
+% \end{syntax}
+% Produces a pseudo-random floating-point number (multiple of
+% $10^{-16}$) between $0$~included and $1$~excluded. This is not available
+% in older versions of \XeTeX{}. The random seed can be queried using
+% \cs{sys_rand_seed:} and set using \cs{sys_gset_rand_seed:n}.
+% \begin{texnote}
+% This is based on pseudo-random numbers provided by the engine's
+% primitive \tn{pdfuniformdeviate} in \pdfTeX{}, \pTeX{}, \upTeX{}
+% and \tn{uniformdeviate} in \LuaTeX{} and \XeTeX{}. The underlying code is
+% based on Metapost, which follows an additive scheme recommended in
+% Section 3.6 of \enquote{The Art of Computer Programming,
+% Volume~2}.
+%
+% While we are more careful than \tn{uniformdeviate} to preserve
+% uniformity of the underlying stream of $28$-bit pseudo-random
+% integers, these pseudo-random numbers should of course not be
+% relied upon for serious numerical computations nor cryptography.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2016-12-05]{randint}
+% \begin{syntax}
+% \cs{fp_eval:n} \{ |randint(| \meta{fpexpr} |)| \}
+% \cs{fp_eval:n} \{ |randint(| \meta{fpexpr_1} , \meta{fpexpr_2} |)| \}
+% \end{syntax}
+% Produces a pseudo-random integer between $1$~and \meta{fpexpr} or
+% between \meta{fpexpr_1} and \meta{fpexpr_2} inclusive. The bounds
+% must be integers in the range $(-10^{16},10^{16})$ and the first
+% must be smaller or equal to the second. See \texttt{rand} for
+% important comments on how these pseudo-random numbers are generated.
+% \end{function}
+%
+% \begin{variable}[tested = m3fp-parse001]{inf, nan}
+% The special values $+\infty$, $-\infty$, and \nan{} are represented
+% as \texttt{inf}, \texttt{-inf} and \texttt{nan} (see \cs{c_inf_fp},
+% \cs{c_minus_inf_fp} and \cs{c_nan_fp}).
+% \end{variable}
+%
+% \begin{variable}[tested = m3fp-parse001]{pi}
+% The value of $\pi$ (see \cs{c_pi_fp}).
+% \end{variable}
+%
+% \begin{variable}[tested = m3fp-parse001]{deg}
+% The value of $1^{\circ}$ in radians (see \cs{c_one_degree_fp}).
+% \end{variable}
+%
+% \begin{variable}[tested = m3fp-parse001]
+% {em, ex, in, pt, pc, cm, mm, dd, cc, nd, nc, bp, sp}
+% \newcommand{\unit}[1]{\text{\texttt{#1}}}
+% Those units of measurement are equal to their values in \unit{pt},
+% namely
+% \begin{align*}
+% 1 \unit{in} & = 72.27 \unit{pt} \\
+% 1 \unit{pt} & = 1 \unit{pt} \\
+% 1 \unit{pc} & = 12 \unit{pt} \\
+% 1 \unit{cm} & = \frac{1}{2.54} \unit{in} = 28.45275590551181 \unit{pt} \\
+% 1 \unit{mm} & = \frac{1}{25.4} \unit{in} = 2.845275590551181 \unit{pt} \\
+% 1 \unit{dd} & = 0.376065 \unit{mm} = 1.07000856496063 \unit{pt} \\
+% 1 \unit{cc} & = 12 \unit{dd} = 12.84010277952756 \unit{pt} \\
+% 1 \unit{nd} & = 0.375 \unit{mm} = 1.066978346456693 \unit{pt} \\
+% 1 \unit{nc} & = 12 \unit{nd} = 12.80374015748031 \unit{pt} \\
+% 1 \unit{bp} & = \frac{1}{72} \unit{in} = 1.00375 \unit{pt} \\
+% 1 \unit{sp} & = 2^{-16} \unit{pt} = 1.52587890625e-5 \unit{pt}.
+% \end{align*}
+% The values of the (font-dependent) units \unit{em} and \unit{ex} are
+% gathered from \TeX{} when the surrounding floating point expression
+% is evaluated.
+% \end{variable}
+%
+% \begin{variable}[tested = m3fp-parse001]{true, false}
+% Other names for $1$ and $+0$.
+% \end{variable}
+%
+% \begin{function}[EXP, added = 2012-05-14, updated = 2012-07-08,
+% tested = m3fp-convert003]{\fp_abs:n}
+% \begin{syntax}
+% \cs{fp_abs:n} \Arg{floating point expression}
+% \end{syntax}
+% Evaluates the \meta{floating point expression} as described for
+% \cs{fp_eval:n} and leaves the absolute value of the result in the
+% input stream. If the argument is $\pm\infty$, \nan{} or a tuple,
+% \enquote{invalid operation} occurs. Within floating point
+% expressions, |abs()| can be used; it accepts $\pm\infty$ and \nan{}
+% as arguments.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2012-09-26, tested = m3fp-convert003]
+% {\fp_max:nn, \fp_min:nn}
+% \begin{syntax}
+% \cs{fp_max:nn} \Arg{fp expression 1} \Arg{fp expression 2}
+% \end{syntax}
+% Evaluates the \meta{floating point expressions} as described for
+% \cs{fp_eval:n} and leaves the resulting larger (\texttt{max}) or
+% smaller (\texttt{min}) value in the input stream. If the argument
+% is a tuple, \enquote{invalid operation} occurs, but no other case
+% raises exceptions. Within floating point expressions, |max()| and
+% |min()| can be used.
+% \end{function}
+%
+% \section{Disclaimer and roadmap}
+%
+% The package may break down if the escape character is among
+% |0123456789_+|, or if it receives a \TeX{} primitive conditional affected
+% by \cs{exp_not:N}.
+%
+% The following need to be done. I'll try to time-order the items.
+% \begin{itemize}
+% \item Function to count items in a tuple (and to determine if something is a tuple).
+% \item Decide what exponent range to consider.
+% \item Support signalling \texttt{nan}.
+% \item Modulo and remainder, and rounding function |quantize| (and its friends analogous to |trunc|, |ceil|, |floor|).
+% \item \cs{fp_format:nn} \Arg{fpexpr} \Arg{format}, but what should
+% \meta{format} be? More general pretty printing?
+% \item Add |and|, |or|, |xor|? Perhaps under the names \texttt{all},
+% \texttt{any}, and \texttt{xor}?
+% \item Add $\log(x,b)$ for logarithm of $x$ in base $b$.
+% \item \texttt{hypot} (Euclidean length).
+% Cartesian-to-polar transform.
+% \item Hyperbolic functions \texttt{cosh}, \texttt{sinh}, \texttt{tanh}.
+% \item Inverse hyperbolics.
+% \item Base conversion, input such as \texttt{0xAB.CDEF}.
+% \item Factorial (not with |!|), gamma function.
+% \item Improve coefficients of the \texttt{sin} and \texttt{tan}
+% series.
+% \item Treat upper and lower case letters identically in
+% identifiers, and ignore underscores.
+% \item Add an |array(1,2,3)| and |i=complex(0,1)|.
+% \item Provide an experimental |map| function? Perhaps easier to
+% implement if it is a single character, |@sin(1,2)|?
+% \item Provide an |isnan| function analogue of \cs{fp_if_nan:nTF}?
+% \item Support keyword arguments?
+% \end{itemize}
+% \pkg{Pgfmath} also provides box-measurements (depth, height, width), but
+% boxes are not possible expandably.
+%
+% Bugs, and tests to add.
+% \begin{itemize}
+% \item Check that functions are monotonic when they should.
+% \item Add exceptions to |?:|, |!<=>?|, |&&|, \verb"||", and |!|.
+% \item Logarithms of numbers very close to $1$ are inaccurate.
+% \item When rounding towards $-\infty$, |\dim_to_fp:n {0pt}| should
+% return $-0$, not $+0$.
+% \item The result of $(\pm0)+(\pm0)$, of $x+(-x)$, and of $(-x)+x$
+% should depend on the rounding mode.
+% \item \texttt{0e9999999999} gives a \TeX{} \enquote{number too
+% large} error.
+% \item Subnormals are not implemented.
+% \end{itemize}
+%
+% Possible optimizations/improvements.
+% \begin{itemize}
+% \item Document that \pkg{l3trial/l3fp-types} introduces tools for
+% adding new types.
+% \item In subsection~\ref{sec:l3fp:fp-floats}, write a grammar.
+% \item It would be nice if the \texttt{parse} auxiliaries for each
+% operation were set up in the corresponding module, rather than
+% centralizing in \pkg{l3fp-parse}.
+% \item Some functions should get an |_o| ending to indicate that they
+% expand after their result.
+% \item More care should be given to distinguish expandable/restricted
+% expandable (auxiliary and internal) functions.
+% \item The code for the \texttt{ternary} set of functions is ugly.
+% \item There are many |~| missing in the doc to avoid bad line-breaks.
+% \item The algorithm for computing the logarithm of the significand
+% could be made to use a $5$ terms Taylor series instead of $10$
+% terms by taking $c = 2000/(\lfloor 200x\rfloor +1) \in [10,95]$
+% instead of $c\in [1,10]$. Also, it would then be possible to
+% simplify the computation of $t$. However, we would then have to
+% hard-code the logarithms of $44$ small integers instead of $9$.
+% \item Improve notations in the explanations of the division
+% algorithm (\pkg{l3fp-basics}).
+% \item Understand and document \cs{__fp_basics_pack_weird_low:NNNNw}
+% and \cs{__fp_basics_pack_weird_high:NNNNNNNNw} better. Move the
+% other \texttt{basics_pack} auxiliaries to \pkg{l3fp-aux} under a
+% better name.
+% \item Find out if underflow can really occur for trigonometric
+% functions, and redoc as appropriate.
+% \item Add bibliography. Some of Kahan's articles, some previous
+% \TeX{} fp packages, the international standards,\ldots{}
+% \item Also take into account the \enquote{inexact} exception?
+% \item Support multi-character prefix operators (\emph{e.g.}, |@/| or
+% whatever)?
+% \end{itemize}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp} implementation}
+%
+% Nothing to see here: everything is in the subfiles!
+%
+% \end{implementation}
+%
+% \PrintIndex