% \iffalse meta-comment
%
%% File: l3fp.dtx
%
% Copyright (C) 2011-2026 The LaTeX 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 \pkg{l3fp} module\\ Floating points^^A
% }
%
% \author{^^A
%  The \LaTeX{} Project\thanks
%    {^^A
%      E-mail:
%        \href{mailto:latex-team@latex-project.org}
%          {latex-team@latex-project.org}^^A
%    }^^A
% }
%
% \date{Released 2026-08-10}
%
% \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.  \emph{Floating point
% expressions} (\enquote{\meta{fp expr}}) 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$ 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$, $\operatorname{logb} x$.
%   \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 Rounding 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: $\operatorname{rand}()$,
%     $\operatorname{randint}(m,n)$.
%   \item Constants: \texttt{pi}, \texttt{deg} (one degree in radians).
%   \item Dimensions, automatically expressed in points, 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{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 initializing 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{fp expr}
%   \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{fp expr}.
% \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_set:NV, \fp_set:cV,
%     \fp_gset:Nn, \fp_gset:cn, \fp_gset:NV, \fp_gset:cV
%   }
%   \begin{syntax}
%     \cs{fp_set:Nn} \meta{fp~var} \Arg{fp expr}
%   \end{syntax}
%   Sets \meta{fp~var} equal to the result of computing the
%   \meta{fp expr}.
% \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{fp expr}
%   \end{syntax}
%   Adds the result of computing the \meta{fp expr} 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{fp expr}
%   \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{fp expr}
%   \end{syntax}
%   Evaluates the \meta{fp expr} 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 = 2018-11-03]{\fp_sign:n}
%   \begin{syntax}
%     \cs{fp_sign:n} \Arg{fp expr}
%   \end{syntax}
%   Evaluates the \meta{fp expr} and leaves its sign in the input stream
%   using \cs{fp_eval:n} |{sign(|\meta{result}|)}|: $+1$ for positive
%   numbers and for $+\infty$, $-1$ for negative numbers and for
%   $-\infty$, $\pm 0$ for $\pm 0$.  If the operand is a tuple or is
%   \nan{}, then \enquote{invalid operation} occurs and the result
%   is~$0$.
% \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{fp expr}
%   \end{syntax}
%   Evaluates the \meta{fp expr} 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{fp expr}
%   \end{syntax}
%   Evaluates the \meta{fp expr} 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{fp expr}
%   \end{syntax}
%   Evaluates the \meta{fp expr}, 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{fp expr}
%   \end{syntax}
%   Evaluates the \meta{fp expr} 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{fp expr}
%   \end{syntax}
%   Evaluates the \meta{fp expr} 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{Formatting floating points}
%
% \begin{function}[EXP, added = 2025-06-09]{\fp_format:nn}
%   \begin{syntax}
%     \cs{fp_format:nn} \Arg{fp expr} \Arg{format specification}
%   \end{syntax}
%   Evaluates the \meta{fp expr} and converts the
%   result to a string according to the \meta{format specification}.
%   The \meta{style} can be
%   \begin{itemize}
%     \item |e| for scientific notation, with one digit before and
%       \meta{precision} digits after the decimal separator, and an
%       integer exponent, following |e|;
%     \item |f| for a fixed point notation, with \meta{precision} digits
%       after the decimal separator and no exponent;
%     \item |g| for a general format, which uses style |f| for numbers
%       in the range $[10^{-4}, 10^{\meta{precision}})$ and style |e|
%       otherwise.
%   \end{itemize}
%   When there is no \meta{style} specifier nor \meta{precision} the
%   number is displayed without rounding.  Otherwise the
%   \meta{precision} defaults to~$6$.  The details of the
%   \meta{format specification} are described in
%   Section~\ref{sec:l3str-format:spec}.
% \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{fp expr_1} \meta{relation} \Arg{fp expr_2}
%     \cs{fp_compare:nNnTF} \Arg{fp expr_1} \meta{relation} \Arg{fp expr_2} \Arg{true code} \Arg{false code}
%   \end{syntax}
%   Compares the \meta{fp expr_1} and the \meta{fp expr_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{fp expr_1} \meta{relation_1} \\
%     ~~~~\ldots{} \\
%     ~~~~\meta{fp expr_N} \meta{relation_N} \\
%     ~~~~\meta{fp expr_{N+1}} \\
%     ~~\} \\
%     \cs{fp_compare:nTF}
%     ~~\{ \\
%     ~~~~\meta{fp expr_1} \meta{relation_1} \\
%     ~~~~\ldots{} \\
%     ~~~~\meta{fp expr_N} \meta{relation_N} \\
%     ~~~~\meta{fp expr_{N+1}} \\
%     ~~\} \\
%     ~~\Arg{true code} \Arg{false code}
%   \end{syntax}
%   Evaluates the \meta{fp exprs} as described for
%   \cs{fp_eval:n} and compares consecutive result using the
%   corresponding \meta{relation}, namely it compares \meta{fp expr_1}
%   and \meta{fp expr_2} using the \meta{relation_1}, then
%   \meta{fp expr_2} and \meta{fp expr_3} using the \meta{relation_2},
%   until finally comparing \meta{fp expr_N} and \meta{fp expr_{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{fp exprs} 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}
%
% \begin{function}[pTF, added = 2019-08-25]{\fp_if_nan:n}
%   \begin{syntax}
%     \cs{fp_if_nan_p:n} \Arg{fp expr}
%     \cs{fp_if_nan:nTF} \Arg{fp expr} \Arg{true code} \Arg{false code}
%   \end{syntax}
%   Evaluates the \meta{fp expr} and tests whether the result is exactly
%   \nan{}.  The test returns \texttt{false} for any other result, even
%   a tuple containing \nan{}.
% \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{fp expr_1} \meta{relation} \Arg{fp expr_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{fp expr_1} \meta{relation} \Arg{fp expr_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{fp expr_1} \meta{relation} \Arg{fp expr_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{fp expr_1} \meta{relation} \Arg{fp expr_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{fp expr_1} \meta{relation} \meta{fp expr_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{fp expr_1} \meta{relation} \meta{fp expr_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{fp expr_1} \meta{relation} \meta{fp expr_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{fp expr_1} \meta{relation} \meta{fp expr_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{Symbolic expressions}
%
% Floating point expressions support variables: these can only be set locally,
% so act like standard \cs[no-index]{l_\dots} variables.
% \begin{quote}\let\obeyedline=\newline\obeylines^^A
%   \cs{fp_new_variable:n} |{ A }|
%   \cs{fp_set:Nn} \cs{l_tmpb_fp} |{ 1 * sin(A) + 3**2 }|
%   \cs{fp_show:n} |{| \cs{l_tmpb_fp} |}|
%   \cs{fp_show:N} \cs{l_tmpb_fp}
%   \cs{fp_set_variable:nn} |{ A }| |{ pi/2 }|
%   \cs{fp_show:n} |{| \cs{l_tmpb_fp} |}|
%   \cs{fp_show:N} \cs{l_tmpb_fp}
%   \cs{fp_set_variable:nn} |{ A }| |{ 0 }|
%   \cs{fp_show:n} |{| \cs{l_tmpb_fp} |}|
%   \cs{fp_show:N} \cs{l_tmpb_fp}
% \end{quote}
% defines~|A| to be a variable, then defines \cs{l_tmpb_fp} to stand for
% |1*sin(A)+9| (note that |3**2| is evaluated, but the |1*|~product is
% not simplified away).  Until \cs{l_tmpb_fp} is changed, \cs{fp_show:N}
% \cs{l_tmpb_fp} will show |((1*sin(A))+9)| regardless of the value
% of~|A|.  The next step defines~|A| to be equal to~|pi/2|: then
% \cs{fp_show:n} |{| \cs{l_tmpb_fp} |}| will evaluate \cs{l_tmpb_fp} and
% show~|10|.  We then redefine~|A| to be~|0|: since \cs{l_tmpb_fp} still
% stands for |1*sin(A)+9|, the value shown is then~|9|.  Variables can
% be set with \cs{fp_set_variable:nn} to arbitrary floating point
% expressions including other variables.
%
% At present, the following operations and functions are \emph{not} supported
% \begin{itemize}
%  \item infix binary comparisons like |>|, |=|, |<|
%  \item infix ternary operator like |?:|
%  \item prefix variable-ary functions like |round| and friends,
%    |min|, |max|, |atan|, |acot|, |atand|, |acotd|
% \end{itemize}
%
% \begin{function}[added = 2023-10-19]{\fp_new_variable:n}
%   \begin{syntax}
%     \cs{fp_new_variable:n} \Arg{identifier}
%   \end{syntax}
%   Declares the \meta{identifier} as a variable, which allows it to be
%   used in floating point expressions.  For instance,
%   \begin{quote}
%     \cs{fp_new_variable:n} |{ A }| \\
%     \cs{fp_show:n} |{ A**2 - A + 1 }|
%   \end{quote}
%   shows |(((A^2)-A)+1)|.  If the declaration was missing, the parser
%   would complain about an \enquote{\texttt{Unknown fp word 'A'}}.  The
%   \meta{identifier} must consist entirely of Latin letters among
%   |[a-zA-Z]|.
% \end{function}
%
% \begin{function}[added = 2023-10-19]{\fp_set_variable:nn}
%   \begin{syntax}
%     \cs{fp_set_variable:nn} \Arg{identifier} \Arg{fp expr}
%   \end{syntax}
%   Sets the \meta{identifier} to stand in any further expression for
%   the result of evaluating the \meta{floating point expression} as
%   much as possible.  The \meta{identifier} must be declared by
%   \cs{fp_new_function:n} first.  The result may contain other
%   variables, which are then replaced by their values if they have any.
%   For instance,
%   \begin{quote}\let\obeyedline=\newline\obeylines^^A
%     \cs{fp_new_variable:n} |{ A }|
%     \cs{fp_new_variable:n} |{ B }|
%     \cs{fp_new_variable:n} |{ C }|
%     \cs{fp_set_variable:nn} |{ A } { 3 }|
%     \cs{fp_set_variable:nn} |{ C } { A ** 2 + B * 1 }|
%     \cs{fp_show:n} |{ C + 4 }|
%     \cs{fp_set_variable:nn} |{ A } { 4 }|
%     \cs{fp_show:n} |{ C + 4 }|
%   \end{quote}
%   shows |((9+(B*1))+4)| twice: changing the value of~|A| to~|4| does
%   not alter~|C| because |A|~was replaced by its value~|3| when
%   evaluating |A**2+B*1|.
% \end{function}
%
% \begin{function}[added = 2023-10-19]{\fp_clear_variable:n}
%   \begin{syntax}
%     \cs{fp_clear_variable:n} \Arg{identifier}
%   \end{syntax}
%   Removes any value given by \cs{fp_set_variable:nn} to the variable
%   with this \meta{identifier}.  For instance,
%   \begin{quote}\let\obeyedline=\newline\obeylines^^A
%     \cs{fp_new_variable:n} |{ A }|
%     \cs{fp_set_variable:nn} |{ A } { 3 }|
%     \cs{fp_show:n} |{ A ^ 2 }|
%     \cs{fp_clear_variable:n} |{ A }|
%     \cs{fp_show:n} |{ A ^ 2 }|
%   \end{quote}
%   shows~|9|, then~|(A^2)|.
% \end{function}
%
% \section{User-defined functions}
%
% It is possible to define new user functions which can be used inside
% the argument to \cs{fp_eval:n}, etc. These functions may take one or
% more named arguments, and should be implemented using expansion methods
% only.
%
% \begin{function}[added = 2023-10-19]{\fp_new_function:n}
%   \begin{syntax}
%     \cs{fp_new_function:n} \Arg{identifier}
%   \end{syntax}
%   Declares the \meta{identifier} as a function, which allows it to be
%   used in floating point expressions.  For instance,
%   \begin{quote}
%      \cs{fp_new_function:n} |{ foo }| \\
%      \cs{fp_show:n} |{ foo ( 1 + 2 , foo(3), A ) ** 2 } }|
%   \end{quote}
%   shows |(foo(3, foo(3), A))^(2)|.  If the declaration was missing,
%   the parser would complain about an \enquote{\texttt{Unknown fp word 'foo'}}.
%   The \meta{identifier} must consist entirely of Latin letters |[a-zA-Z]|.
% \end{function}
%
% \begin{function}[added = 2023-10-19]{\fp_set_function:nnn}
%   \begin{syntax}
%     \cs{fp_set_function:nnn} \Arg{identifier} \Arg{vars} \Arg{fp expr}
%   \end{syntax}
%   Sets the \meta{identifier} to stand in any further expression for
%   the result of evaluating the \meta{floating point expression}, with
%   the \meta{identifier} accepting the \meta{vars} (a non-empty
%   comma-separated list). The \meta{identifier} must be declared by
%   \cs{fp_new_function:n} first.
%   The result may contain other functions, which are
%   then replaced by their results if they have any.  For instance,
%   \begin{quote}
%     \cs{fp_new_function:n} |{ npow }| \\
%     \cs{fp_set_function:nnn} |{ npow } { a,b } { a**b }| \\
%     \cs{fp_show:n} |{ npow(16,0.25) }|
%   \end{quote}
%   shows |2|. The names of the \meta{vars} must
%   consist entirely of Latin letters |[a-zA-Z]|, but are otherwise not
%   restricted: in particular, they are independent of any variables
%   declared by \cs{fp_new_variable:n}.
% \end{function}
%
% \begin{function}[added = 2023-10-19]{\fp_clear_function:n}
%   \begin{syntax}
%     \cs{fp_clear_function:n} \Arg{identifier}
%   \end{syntax}
%   Removes any definition given by \cs{fp_set_function:nnn} to the function
%   with this \meta{identifier}.
% \end{function}
%
% \section{Some useful constants, and scratch variables}
%
% \begin{variable}[added = 2012-05-08, module = fp]{\c_zero_fp, \c_minus_zero_fp}
%   Zero, with either sign.
% \end{variable}
%
% \begin{variable}[added = 2012-05-08, module = fp]{\c_one_fp}
%   One as an \texttt{fp}: useful for comparisons in some places.
% \end{variable}
%
% \begin{variable}[added = 2012-05-08, module = fp]{\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}[added = 2012-05-08, module = fp]{\c_nan_fp}
%   Not a number.  This can be input directly in a floating point expression
%   as \texttt{nan}.
% \end{variable}
%
% \begin{variable}[updated = 2012-05-08, module = fp]{\c_e_fp}
%   The value of the base of the natural logarithm, $\mathrm{e} = \exp(1)$.
% \end{variable}
%
% \begin{variable}[updated = 2013-11-17, module = fp]{\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, module = fp]
%   {\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}
%
% \section{Scratch variables}
%
% \begin{variable}[module = fp]{\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}[module = fp]{\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 (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, 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}: \cs{l_fp_overflow_flag},
% \cs{l_fp_underflow_flag}, \cs{l_fp_invalid_operation_flag} and
% \cs{l_fp_division_by_zero_flag}.  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 behavior 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}
% \end{function}
%
% \begin{variable}
%   {
%     \l_fp_overflow_flag,
%     \l_fp_underflow_flag,
%     \l_fp_invalid_operation_flag,
%     \l_fp_division_by_zero_flag
%   }
%   Flags denoting the occurrence of various floating-point exceptions.
% \end{variable}
%
% \section{Viewing floating points}
%
% \begin{function}[added = 2012-05-08, updated = 2021-04-29,
%   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{fp expr}
%   \end{syntax}
%   Evaluates the \meta{fp expr} and displays the
%   result in the terminal.
% \end{function}
%
% \begin{function}[added = 2014-08-22, updated = 2021-04-29]
%   {\fp_log:N, \fp_log:c, \fp_log:n}
%   \begin{syntax}
%     \cs{fp_log:N} \meta{fp~var}
%     \cs{fp_log:n} \Arg{fp expr}
%   \end{syntax}
%   Evaluates the \meta{fp expr} 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 signaling (\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| or |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 (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[module = fp]{c_e_fp} (which is
% faster).
%
% 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} & = (1\mathrm{in})/(1\mathrm{cm}) = 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, module = {}]{?:}
%   \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{fp expr} |)| \}
%   \end{syntax}
%   Computes the absolute value of the \meta{fp expr}.  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{fp expr} |)| \}
%   \end{syntax}
%   Computes the exponential of the \meta{fp expr}.  \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{fp expr} |)| \}
%   \end{syntax}
%   Computes the factorial of the \meta{fp expr}.  If the \meta{fp expr}
%   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{fp expr} |)| \}
%   \end{syntax}
%   Computes the natural logarithm of the \meta{fp expr}.  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}[EXP, added = 2018-11-03]{logb}
%   \begin{syntax}
%     \cs{fp_eval:n} \{ |logb(| \meta{fp expr} |)| \}
%   \end{syntax}
%   Determines the exponent of the \meta{fp expr}, namely the floor of
%   the base-$10$ logarithm of its absolute value.  \enquote{Division by
%   zero} occurs when evaluating $\operatorname{logb}(\pm 0) = -\infty$.
%   Other special values are $\operatorname{logb}(\pm\infty)=+\infty$
%   and $\operatorname{logb}(\nan{})=\nan{}$.  If the operand is a tuple
%   or is \nan{}, then \enquote{invalid operation} occurs and the result
%   is \nan{}.
% \end{function}
%
% \begin{function}[tested = m3fp-logic002]{max, min}
%   \begin{syntax}
%     \cs{fp_eval:n} \{ |max(| \meta{fp expr_1} |,| \meta{fp expr_2} |,| \ldots{} |)| \}
%     \cs{fp_eval:n} \{ |min(| \meta{fp expr_1} |,| \meta{fp expr_2} |,| \ldots{} |)| \}
%   \end{syntax}
%   Evaluates each \meta{fp expr} and computes the largest (smallest) of
%   those.  If any of the \meta{fp expr} 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{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |round| |(| \meta{fp expr_1} , \meta{fp expr_2} |)| \}
%     \cs{fp_eval:n} \{ |round| |(| \meta{fp expr_1} , \meta{fp expr_2} , \meta{fp expr_3} |)| \}
%   \end{syntax}
%   Only |round| accepts a third argument.
%   Evaluates $\meta{fp expr_1}=x$ and $\meta{fp expr_2}=n$ and $\meta{fp
%   expr_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{fp expr_2} is omitted,
%   $n=0$, i.e., \meta{fp expr_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 than 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{fp expr_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{fp expr} |)| \}
%   \end{syntax}
%   Evaluates the \meta{fp expr} 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{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |cos(| \meta{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |tan(| \meta{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |cot(| \meta{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |csc(| \meta{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |sec(| \meta{fp expr} |)| \}
%   \end{syntax}
%   Computes the sine, cosine, tangent, cotangent, cosecant, or secant
%   of the \meta{fp expr} given in radians.  For arguments given in
%   degrees, see \texttt{sind}, \texttt{cosd}, 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{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |cosd(| \meta{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |tand(| \meta{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |cotd(| \meta{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |cscd(| \meta{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |secd(| \meta{fp expr} |)| \}
%   \end{syntax}
%   Computes the sine, cosine, tangent, cotangent, cosecant, or secant
%   of the \meta{fp expr} given in degrees.  For arguments given in
%   radians, see \texttt{sin}, \texttt{cos}, 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{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |acos(| \meta{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |acsc(| \meta{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |asec(| \meta{fp expr} |)| \}
%   \end{syntax}
%   Computes the arcsine, arccosine, arccosecant, or arcsecant of the
%   \meta{fp expr} 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}, 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{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |acosd(| \meta{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |acscd(| \meta{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |asecd(| \meta{fp expr} |)| \}
%   \end{syntax}
%   Computes the arcsine, arccosine, arccosecant, or arcsecant of the
%   \meta{fp expr} and returns the result in degrees, in the range
%   $[-90,90]$ for \texttt{asind} and \texttt{acscd} and $[0,180]$ for
%   \texttt{acosd} and \texttt{asecd}.  For a result in radians, use
%   \texttt{asin}, etc.  If the argument of |asind| or |acosd| lies
%   outside the range $[-1,1]$, or the argument of |acscd| or |asecd|
%   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{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |atan(| \meta{fp expr_1} , \meta{fp expr_2} |)| \}
%     \cs{fp_eval:n} \{ |acot(| \meta{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |acot(| \meta{fp expr_1} , \meta{fp expr_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{fp expr}: 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{fp expr_2},
%   \meta{fp expr_1})$: this is the arctangent of
%   $\meta{fp expr_1}/\meta{fp expr_2}$, possibly shifted by~$\pi$
%   depending on the signs of \meta{fp expr_1} and \meta{fp expr_2}.  The
%   two-argument arccotangent computes the angle in polar coordinates of
%   the point $(\meta{fp expr_1}, \meta{fp expr_2})$, equal to the
%   arccotangent of $\meta{fp expr_1}/\meta{fp expr_2}$, possibly shifted
%   by~$\pi$.  Both two-argument functions take values in the wider
%   range $[-\pi,\pi]$.  The ratio $\meta{fp expr_1}/\meta{fp expr_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{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |atand(| \meta{fp expr_1} , \meta{fp expr_2} |)| \}
%     \cs{fp_eval:n} \{ |acotd(| \meta{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |acotd(| \meta{fp expr_1} , \meta{fp expr_2} |)| \}
%   \end{syntax}
%   Those functions yield an angle in degrees: \texttt{atan} and
%   \texttt{acot} are their analogs in radians.  The one-argument
%   versions compute the arctangent or arccotangent of the
%   \meta{fp expr}: 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{fp expr_2}, \meta{fp expr_1})$: this is the
%   arctangent of $\meta{fp expr_1}/\meta{fp expr_2}$, possibly shifted
%   by~$180$ depending on the signs of \meta{fp expr_1} and
%   \meta{fp expr_2}.  The two-argument arccotangent computes the angle
%   in polar coordinates of the point $(\meta{fp expr_1},
%   \meta{fp expr_2})$, equal to the arccotangent of
%   $\meta{fp expr_1}/\meta{fp expr_2}$, possibly shifted by~$180$.  Both
%   two-argument functions take values in the wider range $[-180,180]$.
%   The ratio $\meta{fp expr_1}/\meta{fp expr_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{fp expr} |)| \}
%   \end{syntax}
%   Computes the square root of the \meta{fp expr}.  The \enquote{invalid
%     operation} is raised when the \meta{fp expr} 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{fp expr} |)| \}
%     \cs{fp_eval:n} \{ |randint(| \meta{fp expr_1} , \meta{fp expr_2} |)| \}
%   \end{syntax}
%   Produces a pseudo-random integer between $1$~and \meta{fp expr} or
%   between \meta{fp expr_1} and \meta{fp expr_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[module = fp]{c_inf_fp}, \cs[module = fp]{c_minus_inf_fp} and
%   \cs[module = fp]{c_nan_fp}).
% \end{variable}
%
% \begin{variable}[tested = m3fp-parse001]{pi}
%   The value of $\pi$ (see \cs[module = fp]{c_pi_fp}).
% \end{variable}
%
% \begin{variable}[tested = m3fp-parse001]{deg}
%   The value of $1^{\circ}$ in radians (see \cs[module = fp]{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]{\ifmmode\,\fi\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.52587890625 \times 10^{-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{fp expr}
%   \end{syntax}
%   Evaluates the \meta{fp expr} 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 expr_1} \Arg{fp expr_2}
%   \end{syntax}
%   Evaluates the \meta{fp exprs} 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}
%
% This module may break 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 signaling \texttt{nan}.
%   \item Modulo and remainder, and rounding function |quantize| (and its friends analogous to |trunc|, |ceil|, |floor|).
%   \item \cs{fp_format:nn} \Arg{fp expr} \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
%     centeralizing 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[no-index]{__fp_basics_pack_weird_low:NNNNw}
%     and \cs[no-index]{__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 (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
