summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/l3kernel/l3fp-aux.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/l3kernel/l3fp-aux.dtx')
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-aux.dtx1291
1 files changed, 0 insertions, 1291 deletions
diff --git a/macros/latex/contrib/l3kernel/l3fp-aux.dtx b/macros/latex/contrib/l3kernel/l3fp-aux.dtx
deleted file mode 100644
index 1f4ea5d34d..0000000000
--- a/macros/latex/contrib/l3kernel/l3fp-aux.dtx
+++ /dev/null
@@ -1,1291 +0,0 @@
-% \iffalse meta-comment
-%
-%% File: l3fp-aux.dtx
-%
-% Copyright (C) 2011-2024 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}
-\begin{document}
- \DocInput{\jobname.dtx}
-\end{document}
-%</driver>
-% \fi
-%
-% \title{^^A
-% The \pkg{l3fp-aux} module\\ Support for 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 2024-03-14}
-%
-% \maketitle
-%
-% \begin{documentation}
-%
-% \end{documentation}
-%
-% \begin{implementation}
-%
-% \section{\pkg{l3fp-aux} implementation}
-%
-% \begin{macrocode}
-%<*package>
-% \end{macrocode}
-%
-% \begin{macrocode}
-%<@@=fp>
-% \end{macrocode}
-%
-% ^^A todo: make sanitize and pack more homogeneous between modules.
-%
-% \subsection{Access to primitives}
-%
-% \begin{macro}{\@@_int_eval:w, \@@_int_eval_end:, \@@_int_to_roman:w}
-% Largely for performance reasons, we need to directly access primitives
-% rather than use \cs{int_eval:n}. This happens \emph{a lot}, so we
-% use private names. The same is true for \tn{romannumeral}, although it
-% is used much less widely.
-% \begin{macrocode}
-\cs_new_eq:NN \@@_int_eval:w \tex_numexpr:D
-\cs_new_eq:NN \@@_int_eval_end: \scan_stop:
-\cs_new_eq:NN \@@_int_to_roman:w \tex_romannumeral:D
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Internal representation}
-%
-% Internally, a floating point number \meta{X} is a
-% token list containing
-% \begin{quote}
-% \cs{s_@@} \cs{@@_chk:w} \meta{case} \meta{sign} \meta{body} |;|
-% \end{quote}
-% Let us explain each piece separately.
-%
-% Internal floating point numbers are used in expressions,
-% and in this context are subject to \texttt{f}-expansion. They must
-% leave a recognizable mark after \texttt{f}-expansion, to prevent the
-% floating point number from being re-parsed. Thus, \cs{s_@@}
-% is simply another name for \tn{relax}.
-%
-% When used directly without an accessor function, floating points
-% should produce an error: this is the role of \cs{@@_chk:w}. We could
-% make floating point variables be protected to prevent them from
-% expanding under \texttt{e}/\texttt{x}-expansion, but it seems more
-% convenient to treat them as a subcase of token list variables.
-%
-% The (decimal part of the) IEEE-754-2008 standard requires the format
-% to be able to represent special floating point numbers besides the
-% usual positive and negative cases. We distinguish the various
-% possibilities by their \meta{case}, which is a single digit:
-% \begin{itemize}
-% \item[0] zeros: |+0| and |-0|,
-% \item[1] \enquote{normal} numbers (positive and negative),
-% \item[2] infinities: |+inf| and |-inf|,
-% \item[3] quiet and signalling \texttt{nan}.
-% \end{itemize}
-% The \meta{sign} is |0| (positive) or |2| (negative),
-% except in the case of \texttt{nan}, which have $\meta{sign} = 1$.
-% This ensures that changing the \meta{sign} digit to $2-\meta{sign}$
-% is exactly equivalent to changing the sign of the number.
-%
-% Special floating point numbers have the form
-% \begin{quote}
-% \cs{s_@@} \cs{@@_chk:w} \meta{case} \meta{sign} \cs[no-index]{s_@@_\ldots} |;|
-% \end{quote}
-% where \cs[no-index]{s_@@_\ldots} is a scan mark carrying information about how the
-% number was formed (useful for debugging).
-%
-% Normal floating point numbers ($\meta{case} = 1$) have the form
-% \begin{quote}
-% \cs{s_@@} \cs{@@_chk:w} 1 \meta{sign} \Arg{exponent}
-% \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} |;|
-% \end{quote}
-% Here, the \meta{exponent} is an integer, between
-% $-\ExplSyntaxOn\int_use:N\c__fp_minus_min_exponent_int$ and
-% $\ExplSyntaxOn\int_use:N\c__fp_max_exponent_int$. The body consists
-% in four blocks of exactly $4$ digits,
-% $0000 \leq \meta{X_i} \leq 9999$, and the floating point is
-% \[
-% (-1)^{\meta{sign}/2} \meta{X_1}\meta{X_2}\meta{X_3}\meta{X_4}\cdot 10^{\meta{exponent}-16}
-% \]
-% where we have concatenated the $16$ digits. Currently, floating point numbers are normalized such that
-% the \meta{exponent} is minimal, in other words, $1000 \leq \meta{X_1} \leq 9999$.
-%
-% \begin{table}\centering
-% \caption{Internal representation of floating point numbers.}
-% \label{tab:fp-convert-special}
-% \begin{tabular}{ll}
-% \toprule
-% \multicolumn{1}{c}{Representation} & Meaning \\
-% \midrule
-% 0 0 \cs[no-index]{s_@@_\ldots} \texttt{;} & Positive zero. \\
-% 0 2 \cs[no-index]{s_@@_\ldots} \texttt{;} & Negative zero. \\
-% 1 0 \Arg{exponent} \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} \texttt{;}
-% & Positive floating point. \\
-% 1 2 \Arg{exponent} \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} \texttt{;}
-% & Negative floating point. \\
-% 2 0 \cs[no-index]{s_@@_\ldots} \texttt{;} & Positive infinity. \\
-% 2 2 \cs[no-index]{s_@@_\ldots} \texttt{;} & Negative infinity. \\
-% 3 1 \cs[no-index]{s_@@_\ldots} \texttt{;} & Quiet \texttt{nan}. \\
-% 3 1 \cs[no-index]{s_@@_\ldots} \texttt{;} & Signalling \texttt{nan}. \\
-% \bottomrule
-% \end{tabular}
-% \end{table}
-%
-% Calculations are done in base $10000$, \emph{i.e.} one myriad.
-%
-% \subsection{Using arguments and semicolons}
-%
-% \begin{macro}[EXP]{\@@_use_none_stop_f:n}
-% This function removes an argument (typically a digit) and replaces
-% it by \cs{exp_stop_f:}, a marker which stops \texttt{f}-type
-% expansion.
-% \begin{macrocode}
-\cs_new:Npn \@@_use_none_stop_f:n #1 { \exp_stop_f: }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_use_s:n, \@@_use_s:nn}
-% Those functions place a semicolon after one or two arguments
-% (typically digits).
-% \begin{macrocode}
-\cs_new:Npn \@@_use_s:n #1 { #1; }
-\cs_new:Npn \@@_use_s:nn #1#2 { #1#2; }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]
-% {\@@_use_none_until_s:w, \@@_use_i_until_s:nw, \@@_use_ii_until_s:nnw}
-% Those functions select specific arguments among a set of arguments
-% delimited by a semicolon.
-% \begin{macrocode}
-\cs_new:Npn \@@_use_none_until_s:w #1; { }
-\cs_new:Npn \@@_use_i_until_s:nw #1#2; {#1}
-\cs_new:Npn \@@_use_ii_until_s:nnw #1#2#3; {#2}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_reverse_args:Nww}
-% Many internal functions take arguments delimited by semicolons, and
-% it is occasionally useful to swap two such arguments.
-% \begin{macrocode}
-\cs_new:Npn \@@_reverse_args:Nww #1 #2; #3; { #1 #3; #2; }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_rrot:www}
-% Rotate three arguments delimited by semicolons. This is the inverse
-% (or the square) of the Forth primitive |ROT|, hence the name.
-% \begin{macrocode}
-\cs_new:Npn \@@_rrot:www #1; #2; #3; { #2; #3; #1; }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_use_i:ww, \@@_use_i:www}
-% Many internal functions take arguments delimited by semicolons, and
-% it is occasionally useful to remove one or two such arguments.
-% \begin{macrocode}
-\cs_new:Npn \@@_use_i:ww #1; #2; { #1; }
-\cs_new:Npn \@@_use_i:www #1; #2; #3; { #1; }
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Constants, and structure of floating points}
-%
-% \begin{macro}{\@@_misused:n}
-% This receives a floating point object (floating point number or
-% tuple) and generates an error stating that it was misused. This is
-% called when for instance an |fp| variable is left in the input
-% stream and its contents reach \TeX{}'s stomach.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_misused:n #1
- { \msg_error:nne { fp } { misused } { \fp_to_tl:n {#1} } }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\s_@@, \@@_chk:w}
-% Floating points numbers all start with \cs{s_@@} \cs{@@_chk:w},
-% where \cs{s_@@} is equal to the \TeX{} primitive \tn{relax}, and
-% \cs{@@_chk:w} is protected. The rest of the floating point number
-% is made of characters (or \tn{relax}). This ensures that nothing
-% expands under \texttt{f}-expansion, nor under
-% \texttt{e}/\texttt{x}-expansion.
-% However, when typeset, \cs{s_@@} does nothing, and \cs{@@_chk:w} is
-% expanded. We define \cs{@@_chk:w} to produce an error.
-% \begin{macrocode}
-\scan_new:N \s_@@
-\cs_new_protected:Npn \@@_chk:w #1 ;
- { \@@_misused:n { \s_@@ \@@_chk:w #1 ; } }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{variable}{\s_@@_expr_mark, \s_@@_expr_stop}
-% Aliases of \cs{tex_relax:D}, used to terminate expressions.
-% \begin{macrocode}
-\scan_new:N \s_@@_expr_mark
-\scan_new:N \s_@@_expr_stop
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\s_@@_mark, \s_@@_stop}
-% Generic scan marks used throughout the module.
-% \begin{macrocode}
-\scan_new:N \s_@@_mark
-\scan_new:N \s_@@_stop
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}[EXP]{\@@_use_i_delimit_by_s_stop:nw}
-% Functions to gobble up to a scan mark.
-% \begin{macrocode}
-\cs_new:Npn \@@_use_i_delimit_by_s_stop:nw #1 #2 \s_@@_stop {#1}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}
-% {
-% \s_@@_invalid, \s_@@_underflow, \s_@@_overflow,
-% \s_@@_division, \s_@@_exact
-% }
-% A couple of scan marks used to indicate where special floating point
-% numbers come from.
-% \begin{macrocode}
-\scan_new:N \s_@@_invalid
-\scan_new:N \s_@@_underflow
-\scan_new:N \s_@@_overflow
-\scan_new:N \s_@@_division
-\scan_new:N \s_@@_exact
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{variable}
-% {\c_zero_fp, \c_minus_zero_fp, \c_inf_fp, \c_minus_inf_fp, \c_nan_fp}
-% The special floating points. We define the floating points here as \enquote{exact}.
-% \begin{macrocode}
-\tl_const:Nn \c_zero_fp { \s_@@ \@@_chk:w 0 0 \s_@@_exact ; }
-\tl_const:Nn \c_minus_zero_fp { \s_@@ \@@_chk:w 0 2 \s_@@_exact ; }
-\tl_const:Nn \c_inf_fp { \s_@@ \@@_chk:w 2 0 \s_@@_exact ; }
-\tl_const:Nn \c_minus_inf_fp { \s_@@ \@@_chk:w 2 2 \s_@@_exact ; }
-\tl_const:Nn \c_nan_fp { \s_@@ \@@_chk:w 3 1 \s_@@_exact ; }
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\c_@@_prec_int, \c_@@_half_prec_int, \c_@@_block_int}
-% The number of digits of floating points.
-% \begin{macrocode}
-\int_const:Nn \c_@@_prec_int { 16 }
-\int_const:Nn \c_@@_half_prec_int { 8 }
-\int_const:Nn \c_@@_block_int { 4 }
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\c_@@_myriad_int}
-% Blocks have $4$~digits so this integer is useful.
-% \begin{macrocode}
-\int_const:Nn \c_@@_myriad_int { 10000 }
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\c_@@_minus_min_exponent_int, \c_@@_max_exponent_int}
-% Normal floating point numbers have an exponent between $-$
-% \texttt{minus_min_exponent} and \texttt{max_exponent} inclusive.
-% Larger numbers are rounded to $\pm\infty$. Smaller numbers are
-% rounded to $\pm 0$. It would be more natural to define a
-% \texttt{min_exponent} with the opposite sign but that would waste
-% one \TeX{} count.
-% \begin{macrocode}
-\int_const:Nn \c_@@_minus_min_exponent_int { 10000 }
-\int_const:Nn \c_@@_max_exponent_int { 10000 }
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\c_@@_max_exp_exponent_int}
-% If a number's exponent is larger than that, its exponential
-% overflows/underflows.
-% \begin{macrocode}
-\int_const:Nn \c_@@_max_exp_exponent_int { 5 }
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\c_@@_overflowing_fp}
-% A floating point number that is bigger than all normal floating
-% point numbers. This replaces infinities when converting to formats
-% that do not support infinities.
-% \begin{macrocode}
-\tl_const:Ne \c_@@_overflowing_fp
- {
- \s_@@ \@@_chk:w 1 0
- { \int_eval:n { \c_@@_max_exponent_int + 1 } }
- {1000} {0000} {0000} {0000} ;
- }
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}[EXP]{\@@_zero_fp:N, \@@_inf_fp:N}
-% In case of overflow or underflow, we have to output
-% a zero or infinity with a given sign.
-% \begin{macrocode}
-\cs_new:Npn \@@_zero_fp:N #1
- { \s_@@ \@@_chk:w 0 #1 \s_@@_underflow ; }
-\cs_new:Npn \@@_inf_fp:N #1
- { \s_@@ \@@_chk:w 2 #1 \s_@@_overflow ; }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_exponent:w}
-% For normal numbers, the function expands to the exponent, otherwise
-% to $0$. This is used in \pkg{l3str-format}.
-% \begin{macrocode}
-\cs_new:Npn \@@_exponent:w \s_@@ \@@_chk:w #1
- {
- \if_meaning:w 1 #1
- \exp_after:wN \@@_use_ii_until_s:nnw
- \else:
- \exp_after:wN \@@_use_i_until_s:nw
- \exp_after:wN 0
- \fi:
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_neg_sign:N}
-% When appearing in an integer expression or after \cs{int_value:w},
-% this expands to the sign opposite to |#1|, namely $0$ (positive) is
-% turned to $2$ (negative), $1$ (\texttt{nan}) to $1$, and $2$ to $0$.
-% \begin{macrocode}
-\cs_new:Npn \@@_neg_sign:N #1
- { \@@_int_eval:w 2 - #1 \@@_int_eval_end: }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_kind:w}
-% Expands to $0$ for zeros, $1$ for normal floating point numbers, $2$
-% for infinities, $3$ for \nan{}, $4$ for tuples.
-% \begin{macrocode}
-\cs_new:Npn \@@_kind:w #1
- {
- \@@_if_type_fp:NTwFw
- #1 \@@_use_ii_until_s:nnw
- \s_@@ { \@@_use_i_until_s:nw 4 }
- \s_@@_stop
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Overflow, underflow, and exact zero}
-%
-%^^A todo: the sign of exact zeros should depend on the rounding mode.
-%
-% \begin{macro}[EXP]{\@@_sanitize:Nw, \@@_sanitize:wN}
-% \begin{macro}[EXP]{\@@_sanitize_zero:w}
-% Expects the sign and the exponent in some order, then the
-% significand (which we don't touch). Outputs the corresponding
-% floating point number, possibly underflowed to $\pm 0$ or overflowed
-% to $\pm\infty$. The functions \cs{@@_underflow:w} and
-% \cs{@@_overflow:w} are defined in \pkg{l3fp-traps}.
-% \begin{macrocode}
-\cs_new:Npn \@@_sanitize:Nw #1 #2;
- {
- \if_case:w
- \if_int_compare:w #2 > \c_@@_max_exponent_int 1 ~ \else:
- \if_int_compare:w #2 < - \c_@@_minus_min_exponent_int 2 ~ \else:
- \if_meaning:w 1 #1 3 ~ \fi: \fi: \fi: 0 ~
- \or: \exp_after:wN \@@_overflow:w
- \or: \exp_after:wN \@@_underflow:w
- \or: \exp_after:wN \@@_sanitize_zero:w
- \fi:
- \s_@@ \@@_chk:w 1 #1 {#2}
- }
-\cs_new:Npn \@@_sanitize:wN #1; #2 { \@@_sanitize:Nw #2 #1; }
-\cs_new:Npn \@@_sanitize_zero:w \s_@@ \@@_chk:w #1 #2 #3;
- { \c_zero_fp }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \subsection{Expanding after a floating point number}
-%
-% \begin{macro}[EXP]{\@@_exp_after_o:w}
-% \begin{macro}[EXP]{\@@_exp_after_f:nw}
-% \begin{syntax}
-% \cs{@@_exp_after_o:w} \meta{floating point}
-% \cs{@@_exp_after_f:nw} \Arg{tokens} \meta{floating point}
-% \end{syntax}
-% Places \meta{tokens} (empty in the case of \cs{@@_exp_after_o:w})
-% between the \meta{floating point} and the following tokens, then
-% hits those tokens with \texttt{o} or \texttt{f}-expansion, and
-% leaves the floating point number unchanged.
-%
-% We first distinguish normal floating points, which have a significand,
-% from the much simpler special floating points.
-% \begin{macrocode}
-\cs_new:Npn \@@_exp_after_o:w \s_@@ \@@_chk:w #1
- {
- \if_meaning:w 1 #1
- \exp_after:wN \@@_exp_after_normal:nNNw
- \else:
- \exp_after:wN \@@_exp_after_special:nNNw
- \fi:
- { }
- #1
- }
-\cs_new:Npn \@@_exp_after_f:nw #1 \s_@@ \@@_chk:w #2
- {
- \if_meaning:w 1 #2
- \exp_after:wN \@@_exp_after_normal:nNNw
- \else:
- \exp_after:wN \@@_exp_after_special:nNNw
- \fi:
- { \exp:w \exp_end_continue_f:w #1 }
- #2
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_exp_after_special:nNNw}
-% \begin{syntax}
-% \cs{@@_exp_after_special:nNNw} \Arg{after} \meta{case} \meta{sign} \meta{scan mark} |;|
-% \end{syntax}
-% Special floating point numbers are easy to jump over since they
-% contain few tokens.
-% \begin{macrocode}
-\cs_new:Npn \@@_exp_after_special:nNNw #1#2#3#4;
- {
- \exp_after:wN \s_@@
- \exp_after:wN \@@_chk:w
- \exp_after:wN #2
- \exp_after:wN #3
- \exp_after:wN #4
- \exp_after:wN ;
- #1
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_exp_after_normal:nNNw}
-% For normal floating point numbers, life is slightly harder, since we
-% have many tokens to jump over. Here it would be slightly better if
-% the digits were not braced but instead were delimited arguments (for
-% instance delimited by |,|). That may be changed some day.
-% \begin{macrocode}
-\cs_new:Npn \@@_exp_after_normal:nNNw #1 1 #2 #3 #4#5#6#7;
- {
- \exp_after:wN \@@_exp_after_normal:Nwwwww
- \exp_after:wN #2
- \int_value:w #3 \exp_after:wN ;
- \int_value:w 1 #4 \exp_after:wN ;
- \int_value:w 1 #5 \exp_after:wN ;
- \int_value:w 1 #6 \exp_after:wN ;
- \int_value:w 1 #7 \exp_after:wN ; #1
- }
-\cs_new:Npn \@@_exp_after_normal:Nwwwww
- #1 #2; 1 #3 ; 1 #4 ; 1 #5 ; 1 #6 ;
- { \s_@@ \@@_chk:w 1 #1 {#2} {#3} {#4} {#5} {#6} ; }
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Other floating point types}
-%
-% \begin{macro}{\s_@@_tuple, \@@_tuple_chk:w}
-% \begin{variable}{\c_@@_empty_tuple_fp}
-% Floating point tuples take the form \cs{s_@@_tuple}
-% \cs{@@_tuple_chk:w} |{| \meta{fp 1} \meta{fp 2} \dots |}| |;| where
-% each \meta{fp} is a floating point number or tuple, hence ends with
-% |;| itself. When a tuple is typeset, \cs{@@_tuple_chk:w} produces
-% an error, just like usual floating point numbers.
-% Tuples may have zero or one element.
-% \begin{macrocode}
-\scan_new:N \s_@@_tuple
-\cs_new_protected:Npn \@@_tuple_chk:w #1 ;
- { \@@_misused:n { \s_@@_tuple \@@_tuple_chk:w #1 ; } }
-\tl_const:Nn \c_@@_empty_tuple_fp
- { \s_@@_tuple \@@_tuple_chk:w { } ; }
-% \end{macrocode}
-% \end{variable}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_tuple_count:w, \@@_array_count:n}
-% \begin{macro}[EXP]{\@@_tuple_count_loop:Nw}
-% Count the number of items in a tuple of floating points by counting
-% semicolons. The technique is very similar to \cs{tl_count:n}, but
-% with the loop built-in. Checking for the end of the loop is done
-% with the |\use_none:n #1| construction.
-% \begin{macrocode}
-\cs_new:Npn \@@_array_count:n #1
- { \@@_tuple_count:w \s_@@_tuple \@@_tuple_chk:w {#1} ; }
-\cs_new:Npn \@@_tuple_count:w \s_@@_tuple \@@_tuple_chk:w #1 ;
- {
- \int_value:w \@@_int_eval:w 0
- \@@_tuple_count_loop:Nw #1 { ? \prg_break: } ;
- \prg_break_point:
- \@@_int_eval_end:
- }
-\cs_new:Npn \@@_tuple_count_loop:Nw #1#2;
- { \use_none:n #1 + 1 \@@_tuple_count_loop:Nw }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_if_type_fp:NTwFw}
-% Used as \cs{@@_if_type_fp:NTwFw} \meta{marker} \Arg{true code}
-% \cs{s_@@} \Arg{false code} \cs{s_@@_stop}, this test whether the
-% \meta{marker} is \cs{s_@@} or not and runs the appropriate
-% \meta{code}. The very unusual syntax is for optimization purposes
-% as that function is used for all floating point operations.
-% \begin{macrocode}
-\cs_new:Npn \@@_if_type_fp:NTwFw #1 \s_@@ #2 #3 \s_@@_stop {#2}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_array_if_all_fp:nTF, \@@_array_if_all_fp_loop:w}
-% True if all items are floating point numbers. Used for |min|.
-% \begin{macrocode}
-\cs_new:Npn \@@_array_if_all_fp:nTF #1
- {
- \@@_array_if_all_fp_loop:w #1 { \s_@@ \prg_break: } ;
- \prg_break_point: \use_i:nn
- }
-\cs_new:Npn \@@_array_if_all_fp_loop:w #1#2 ;
- {
- \@@_if_type_fp:NTwFw
- #1 \@@_array_if_all_fp_loop:w
- \s_@@ { \prg_break:n \use_iii:nnn }
- \s_@@_stop
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]
-% {\@@_type_from_scan:N, \@@_type_from_scan_other:N, \@@_type_from_scan:w}
-% Used as \cs{@@_type_from_scan:N} \meta{token}.
-% Grabs the pieces of the stringified \meta{token} which lies after
-% the first |s__fp|. If the \meta{token} does not contain that
-% string, the result is |_?|.
-% \begin{macrocode}
-\cs_new:Npn \@@_type_from_scan:N #1
- {
- \@@_if_type_fp:NTwFw
- #1 { }
- \s_@@ { \@@_type_from_scan_other:N #1 }
- \s_@@_stop
- }
-\cs_new:Npe \@@_type_from_scan_other:N #1
- {
- \exp_not:N \exp_after:wN \exp_not:N \@@_type_from_scan:w
- \exp_not:N \token_to_str:N #1 \s_@@_mark
- \tl_to_str:n { s_@@ _? } \s_@@_mark \s_@@_stop
- }
-\exp_last_unbraced:NNNNo
- \cs_new:Npn \@@_type_from_scan:w #1
- { \tl_to_str:n { s_@@ } } #2 \s_@@_mark #3 \s_@@_stop {#2}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_change_func_type:NNN}
-% \begin{macro}[EXP]{\@@_change_func_type_aux:w, \@@_change_func_type_chk:NNN}
-% Arguments are \meta{type marker} \meta{function} \meta{recovery}.
-% This gives the function obtained by placing the type after |@@|. If
-% the function is not defined then \meta{recovery} \meta{function} is
-% used instead; however that test is not run when the \meta{type
-% marker} is \cs{s_@@}.
-% \begin{macrocode}
-\cs_new:Npn \@@_change_func_type:NNN #1#2#3
- {
- \@@_if_type_fp:NTwFw
- #1 #2
- \s_@@
- {
- \exp_after:wN \@@_change_func_type_chk:NNN
- \cs:w
- @@ \@@_type_from_scan_other:N #1
- \exp_after:wN \@@_change_func_type_aux:w \token_to_str:N #2
- \cs_end:
- #2 #3
- }
- \s_@@_stop
- }
-\exp_last_unbraced:NNNNo
- \cs_new:Npn \@@_change_func_type_aux:w #1 { \tl_to_str:n { @@ } } { }
-\cs_new:Npn \@@_change_func_type_chk:NNN #1#2#3
- {
- \if_meaning:w \scan_stop: #1
- \exp_after:wN #3 \exp_after:wN #2
- \else:
- \exp_after:wN #1
- \fi:
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_exp_after_any_f:Nnw, \@@_exp_after_any_f:nw}
-% \begin{macro}[EXP]{\@@_exp_after_expr_stop_f:nw}
-% The |Nnw| function simply dispatches to the appropriate
-% \cs[no-index]{@@_exp_after\ldots{}_f:nw} with \enquote{\ldots{}}
-% (either empty or |_|\meta{type}) extracted from |#1|, which should
-% start with |\s__fp|. If it doesn't start with |\s__fp| the function
-% \cs{@@_exp_after_?_f:nw} defined in \pkg{l3fp-parse} gives an error;
-% another special \meta{type} is |stop|, useful for loops, see below.
-% The |nw| function has an important optimization for floating points
-% numbers; it also fetches its type marker |#2| from the floating
-% point.
-% \begin{macrocode}
-\cs_new:Npn \@@_exp_after_any_f:Nnw #1
- { \cs:w @@_exp_after \@@_type_from_scan_other:N #1 _f:nw \cs_end: }
-\cs_new:Npn \@@_exp_after_any_f:nw #1#2
- {
- \@@_if_type_fp:NTwFw
- #2 \@@_exp_after_f:nw
- \s_@@ { \@@_exp_after_any_f:Nnw #2 }
- \s_@@_stop
- {#1} #2
- }
-\cs_new_eq:NN \@@_exp_after_expr_stop_f:nw \use_none:nn
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_exp_after_tuple_o:w}
-% \begin{macro}[EXP]{\@@_exp_after_tuple_f:nw, \@@_exp_after_array_f:w}
-% The loop works by using the |n| argument of
-% \cs{@@_exp_after_any_f:nw} to place the loop macro after the next
-% item in the tuple and expand it.
-% \begin{quote}
-% \cs{@@_exp_after_array_f:w}\\
-% \meta{fp_1} |;|\\
-% \ldots{}\\
-% \meta{fp_n} |;|\\
-% \cs{s_@@_expr_stop}
-% \end{quote}
-% \begin{macrocode}
-\cs_new:Npn \@@_exp_after_tuple_o:w
- { \@@_exp_after_tuple_f:nw { \exp_after:wN \exp_stop_f: } }
-\cs_new:Npn \@@_exp_after_tuple_f:nw
- #1 \s_@@_tuple \@@_tuple_chk:w #2 ;
- {
- \exp_after:wN \s_@@_tuple
- \exp_after:wN \@@_tuple_chk:w
- \exp_after:wN {
- \exp:w \exp_end_continue_f:w
- \@@_exp_after_array_f:w #2 \s_@@_expr_stop
- \exp_after:wN }
- \exp_after:wN ;
- \exp:w \exp_end_continue_f:w #1
- }
-\cs_new:Npn \@@_exp_after_array_f:w
- { \@@_exp_after_any_f:nw { \@@_exp_after_array_f:w } }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \subsection{Packing digits}
-%
-% When a positive integer |#1| is known to be less than $10^8$, the
-% following trick splits it into two blocks of $4$ digits, padding
-% with zeros on the left.
-% \begin{verbatim}
-% \cs_new:Npn \pack:NNNNNw #1 #2#3#4#5 #6; { {#2#3#4#5} {#6} }
-% \exp_after:wN \pack:NNNNNw
-% \__fp_int_value:w \__fp_int_eval:w 1 0000 0000 + #1 ;
-% \end{verbatim}
-% The idea is that adding $10^8$ to the number ensures that it has
-% exactly $9$ digits, and can then easily find which digits correspond
-% to what position in the number. Of course, this can be modified
-% for any number of digits less or equal to~$9$ (we are limited by
-% \TeX{}'s integers). This method is very heavily relied upon in
-% \texttt{l3fp-basics}.
-%
-% More specifically, the auxiliary inserts |+ #1#2#3#4#5 ; {#6}|, which
-% allows us to compute several blocks of $4$ digits in a nested manner,
-% performing carries on the fly. Say we want to compute $1\,2345 \times
-% 6677\,8899$. With simplified names, we would do
-% \begin{verbatim}
-% \exp_after:wN \post_processing:w
-% \__fp_int_value:w \__fp_int_eval:w - 5 0000
-% \exp_after:wN \pack:NNNNNw
-% \__fp_int_value:w \__fp_int_eval:w 4 9995 0000
-% + 12345 * 6677
-% \exp_after:wN \pack:NNNNNw
-% \__fp_int_value:w \__fp_int_eval:w 5 0000 0000
-% + 12345 * 8899 ;
-% \end{verbatim}
-% The \cs{exp_after:wN} triggers \cs{int_value:w} \cs{@@_int_eval:w}, which
-% starts a first computation, whose initial value is $- 5\,0000$ (the
-% \enquote{leading shift}). In that computation appears an
-% \cs{exp_after:wN}, which triggers the nested computation
-% \cs{int_value:w} \cs{@@_int_eval:w} with starting value $4\,9995\,0000$ (the
-% \enquote{middle shift}). That, in turn, expands \cs{exp_after:wN}
-% which triggers the third computation. The third computation's value
-% is $5\,0000\,0000 + 12345 \times 8899$, which has $9$ digits. Adding
-% $5\cdot 10^{8}$ to the product allowed us to know how many digits to
-% expect as long as the numbers to multiply are not too big; it
-% also works to some extent with negative results. The \texttt{pack}
-% function puts the last $4$ of those $9$ digits into a brace group,
-% moves the semi-colon delimiter, and inserts a |+|, which combines the
-% carry with the previous computation. The shifts nicely combine into
-% $5\,0000\,0000 / 10^{4} + 4\,9995\,0000 = 5\,0000\,0000$. As long as
-% the operands are in some range, the result of this second computation
-% has $9$ digits. The corresponding \texttt{pack} function,
-% expanded after the result is computed, braces the last $4$ digits, and
-% leaves |+| \meta{5 digits} for the initial computation. The
-% \enquote{leading shift} cancels the combination of the other shifts,
-% and the |\post_processing:w| takes care of packing the last few
-% digits.
-%
-% Admittedly, this is quite intricate. It is probably the key in making
-% \pkg{l3fp} as fast as other pure \TeX{} floating point units despite
-% its increased precision. In fact, this is used so much that we
-% provide different sets of packing functions and shifts, depending on
-% ranges of input.
-%
-% \begin{macro}[EXP]{\@@_pack:NNNNNw}
-% \begin{variable}
-% {
-% \c_@@_trailing_shift_int ,
-% \c_@@_middle_shift_int ,
-% \c_@@_leading_shift_int ,
-% }
-% This set of shifts allows for computations involving results in the
-% range $[-4\cdot 10^{8}, 5\cdot 10^{8}-1]$. Shifted values all have
-% exactly $9$ digits.
-% \begin{macrocode}
-\int_const:Nn \c_@@_leading_shift_int { - 5 0000 }
-\int_const:Nn \c_@@_middle_shift_int { 5 0000 * 9999 }
-\int_const:Nn \c_@@_trailing_shift_int { 5 0000 * 10000 }
-\cs_new:Npn \@@_pack:NNNNNw #1 #2#3#4#5 #6; { + #1#2#3#4#5 ; {#6} }
-% \end{macrocode}
-% \end{variable}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_pack_big:NNNNNNw}
-% \begin{variable}
-% {
-% \c_@@_big_trailing_shift_int ,
-% \c_@@_big_middle_shift_int ,
-% \c_@@_big_leading_shift_int ,
-% }
-% This set of shifts allows for computations involving results in the
-% range $[-5\cdot 10^{8}, 6\cdot 10^{8}-1]$ (actually a bit more).
-% Shifted values all have exactly $10$ digits. Note that the upper
-% bound is due to \TeX{}'s limit of $2^{31}-1$ on integers. The
-% shifts are chosen to be roughly the mid-point of $10^{9}$ and
-% $2^{31}$, the two bounds on $10$-digit integers in \TeX{}.
-% \begin{macrocode}
-\int_const:Nn \c_@@_big_leading_shift_int { - 15 2374 }
-\int_const:Nn \c_@@_big_middle_shift_int { 15 2374 * 9999 }
-\int_const:Nn \c_@@_big_trailing_shift_int { 15 2374 * 10000 }
-\cs_new:Npn \@@_pack_big:NNNNNNw #1#2 #3#4#5#6 #7;
- { + #1#2#3#4#5#6 ; {#7} }
-% \end{macrocode}
-% \end{variable}
-% \end{macro}
-%
-% ^^A \@@_pack_Bigg:NNNNNNw = \@@_pack_big:NNNNNNw ?
-% \begin{macro}[EXP]{\@@_pack_Bigg:NNNNNNw}
-% \begin{variable}
-% {
-% \c_@@_Bigg_trailing_shift_int ,
-% \c_@@_Bigg_middle_shift_int ,
-% \c_@@_Bigg_leading_shift_int ,
-% }
-% This set of shifts allows for computations with results in the
-% range $[-1\cdot 10^{9}, 147483647]$; the end-point is $2^{31} - 1 -
-% 2\cdot 10^{9} \simeq 1.47\cdot 10^{8}$. Shifted values all have
-% exactly $10$ digits.
-% \begin{macrocode}
-\int_const:Nn \c_@@_Bigg_leading_shift_int { - 20 0000 }
-\int_const:Nn \c_@@_Bigg_middle_shift_int { 20 0000 * 9999 }
-\int_const:Nn \c_@@_Bigg_trailing_shift_int { 20 0000 * 10000 }
-\cs_new:Npn \@@_pack_Bigg:NNNNNNw #1#2 #3#4#5#6 #7;
- { + #1#2#3#4#5#6 ; {#7} }
-% \end{macrocode}
-% \end{variable}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_pack_twice_four:wNNNNNNNN}
-% \begin{syntax}
-% \cs{@@_pack_twice_four:wNNNNNNNN} \meta{tokens} |;| \meta{$\geq 8$ digits}
-% \end{syntax}
-% Grabs two sets of $4$ digits and places them before the semi-colon
-% delimiter. Putting several copies of this function before a
-% semicolon packs more digits since each takes the digits
-% packed by the others in its first argument.
-% \begin{macrocode}
-\cs_new:Npn \@@_pack_twice_four:wNNNNNNNN #1; #2#3#4#5 #6#7#8#9
- { #1 {#2#3#4#5} {#6#7#8#9} ; }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_pack_eight:wNNNNNNNN}
-% \begin{syntax}
-% \cs{@@_pack_eight:wNNNNNNNN} \meta{tokens} |;| \meta{$\geq 8$ digits}
-% \end{syntax}
-% Grabs one set of $8$ digits and places them before the semi-colon
-% delimiter as a single group. Putting several copies of this
-% function before a semicolon packs more digits since each
-% takes the digits packed by the others in its first argument.
-% \begin{macrocode}
-\cs_new:Npn \@@_pack_eight:wNNNNNNNN #1; #2#3#4#5 #6#7#8#9
- { #1 {#2#3#4#5#6#7#8#9} ; }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]
-% {
-% \@@_basics_pack_low:NNNNNw,
-% \@@_basics_pack_high:NNNNNw,
-% \@@_basics_pack_high_carry:w
-% }
-% Addition and multiplication of significands are done in two steps:
-% first compute a (more or less) exact result, then round and pack
-% digits in the final (braced) form. These functions take care of the
-% packing, with special attention given to the case where rounding has
-% caused a carry. Since rounding can only shift the final digit by
-% $1$, a carry always produces an exact power of $10$. Thus,
-% \cs{@@_basics_pack_high_carry:w} is always followed by four times
-% |{0000}|.
-%
-% This is used in \pkg{l3fp-basics} and \pkg{l3fp-extended}.
-% \begin{macrocode}
-\cs_new:Npn \@@_basics_pack_low:NNNNNw #1 #2#3#4#5 #6;
- { + #1 - 1 ; {#2#3#4#5} {#6} ; }
-\cs_new:Npn \@@_basics_pack_high:NNNNNw #1 #2#3#4#5 #6;
- {
- \if_meaning:w 2 #1
- \@@_basics_pack_high_carry:w
- \fi:
- ; {#2#3#4#5} {#6}
- }
-\cs_new:Npn \@@_basics_pack_high_carry:w \fi: ; #1
- { \fi: + 1 ; {1000} }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]
-% {
-% \@@_basics_pack_weird_low:NNNNw,
-% \@@_basics_pack_weird_high:NNNNNNNNw
-% }
-% This is used in \pkg{l3fp-basics} for additions and
-% divisions. Their syntax is confusing, hence the name.
-% \begin{macrocode}
-\cs_new:Npn \@@_basics_pack_weird_low:NNNNw #1 #2#3#4 #5;
- {
- \if_meaning:w 2 #1
- + 1
- \fi:
- \@@_int_eval_end:
- #2#3#4; {#5} ;
- }
-\cs_new:Npn \@@_basics_pack_weird_high:NNNNNNNNw
- 1 #1#2#3#4 #5#6#7#8 #9; { ; {#1#2#3#4} {#5#6#7#8} {#9} }
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Decimate (dividing by a power of 10)}
-%
-% ^^A begin[todo]
-% \begin{macro}[EXP]{\@@_decimate:nNnnnn}
-% \begin{syntax}
-% \cs{@@_decimate:nNnnnn} \Arg{shift} \meta{f_1}
-% ~~\Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4}
-% \end{syntax}
-% Each \meta{X_i} consists in $4$ digits exactly,
-% and $1000\leq\meta{X_1}<9999$. The first argument determines
-% by how much we shift the digits. \meta{f_1} is called as follows:
-% \begin{syntax}
-% \meta{f_1} \meta{rounding} \Arg{X'_1} \Arg{X'_2} \meta{extra-digits} |;|
-% \end{syntax}
-% where $0\leq\meta{X'_i}<10^{8}-1$ are $8$ digit integers,
-% forming the truncation of our number. In other words,
-% \[
-% \left(
-% \sum_{i=1}^{4} \meta{X_i} \cdot 10^{-4i} \cdot 10^{-\meta{shift}}
-% \right)
-% - \bigl( \meta{X'_1} \cdot 10^{-8} + \meta{X'_2} \cdot 10^{-16} \bigr)
-% = 0.\meta{extra-digits} \cdot 10^{-16}
-% \in [0,10^{-16}).
-% \]
-% To round properly later, we need to remember some information
-% about the difference. The \meta{rounding} digit is $0$ if and
-% only if the difference is exactly $0$, and $5$ if and only if
-% the difference is exactly $0.5\cdot 10^{-16}$. Otherwise, it
-% is the (non-$0$, non-$5$) digit closest to $10^{17}$ times the
-% difference. In particular, if the shift is $17$ or more, all
-% the digits are dropped, \meta{rounding} is $1$ (not $0$), and
-% \meta{X'_1} and \meta{X'_2} are both zero.
-%
-% If the shift is $1$, the \meta{rounding} digit is simply the
-% only digit that was pushed out of the brace groups (this is
-% important for subtraction). It would be more natural for the
-% \meta{rounding} digit to be placed after the \meta{X'_i},
-% but the choice we make involves less reshuffling.
-%
-% Note that this function treats negative \meta{shift} as $0$.
-% \begin{macrocode}
-\cs_new:Npn \@@_decimate:nNnnnn #1
- {
- \cs:w
- @@_decimate_
- \if_int_compare:w \@@_int_eval:w #1 > \c_@@_prec_int
- tiny
- \else:
- \@@_int_to_roman:w \@@_int_eval:w #1
- \fi:
- :Nnnnn
- \cs_end:
- }
-% \end{macrocode}
-% Each of the auxiliaries see the function \meta{f_1},
-% followed by $4$ blocks of $4$ digits.
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_decimate_:Nnnnn, \@@_decimate_tiny:Nnnnn}
-% If the \meta{shift} is zero, or too big, life is very easy.
-% \begin{macrocode}
-\cs_new:Npn \@@_decimate_:Nnnnn #1 #2#3#4#5
- { #1 0 {#2#3} {#4#5} ; }
-\cs_new:Npn \@@_decimate_tiny:Nnnnn #1 #2#3#4#5
- { #1 1 { 0000 0000 } { 0000 0000 } 0 #2#3#4#5 ; }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]
-% {
-% \@@_decimate_auxi:Nnnnn, \@@_decimate_auxii:Nnnnn,
-% \@@_decimate_auxiii:Nnnnn, \@@_decimate_auxiv:Nnnnn,
-% \@@_decimate_auxv:Nnnnn, \@@_decimate_auxvi:Nnnnn,
-% \@@_decimate_auxvii:Nnnnn, \@@_decimate_auxviii:Nnnnn,
-% \@@_decimate_auxix:Nnnnn, \@@_decimate_auxx:Nnnnn,
-% \@@_decimate_auxxi:Nnnnn, \@@_decimate_auxxii:Nnnnn,
-% \@@_decimate_auxxiii:Nnnnn, \@@_decimate_auxxiv:Nnnnn,
-% \@@_decimate_auxxv:Nnnnn, \@@_decimate_auxxvi:Nnnnn
-% }
-% \begin{syntax}
-% \cs{@@_decimate_auxi:Nnnnn} \meta{f_1} \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4}
-% \end{syntax}
-% Shifting happens in two steps: compute the \meta{rounding} digit,
-% and repack digits into two blocks of $8$. The sixteen functions
-% are very similar, and defined through \cs{@@_tmp:w}.
-% The arguments are as follows: |#1| indicates which function is
-% being defined; after one step of expansion, |#2| yields the
-% \enquote{extra digits} which are then converted by
-% \cs{@@_round_digit:Nw} to the \meta{rounding} digit (note the |+|
-% separating blocks of digits to avoid overflowing \TeX{}'s integers).
-% This triggers the \texttt{f}-expansion of
-% \cs{@@_decimate_pack:nnnnnnnnnnw},\footnote{No, the argument
-% spec is not a mistake: the function calls an auxiliary to
-% do half of the job.} responsible for building two blocks of
-% $8$ digits, and removing the rest. For this to work, |#3|
-% alternates between braced and unbraced blocks of $4$ digits,
-% in such a way that the $5$ first and $5$ next token groups
-% yield the correct blocks of $8$ digits.
-% \begin{macrocode}
-\cs_new:Npn \@@_tmp:w #1 #2 #3
- {
- \cs_new:cpn { @@_decimate_ #1 :Nnnnn } ##1 ##2##3##4##5
- {
- \exp_after:wN ##1
- \int_value:w
- \exp_after:wN \@@_round_digit:Nw #2 ;
- \@@_decimate_pack:nnnnnnnnnnw #3 ;
- }
- }
-\@@_tmp:w {i} {\use_none:nnn #50}{ 0{#2}#3{#4}#5 }
-\@@_tmp:w {ii} {\use_none:nn #5 }{ 00{#2}#3{#4}#5 }
-\@@_tmp:w {iii} {\use_none:n #5 }{ 000{#2}#3{#4}#5 }
-\@@_tmp:w {iv} { #5 }{ {0000}#2{#3}#4 #5 }
-\@@_tmp:w {v} {\use_none:nnn #4#5 }{ 0{0000}#2{#3}#4 #5 }
-\@@_tmp:w {vi} {\use_none:nn #4#5 }{ 00{0000}#2{#3}#4 #5 }
-\@@_tmp:w {vii} {\use_none:n #4#5 }{ 000{0000}#2{#3}#4 #5 }
-\@@_tmp:w {viii}{ #4#5 }{ {0000}0000{#2}#3 #4 #5 }
-\@@_tmp:w {ix} {\use_none:nnn #3#4+#5}{ 0{0000}0000{#2}#3 #4 #5 }
-\@@_tmp:w {x} {\use_none:nn #3#4+#5}{ 00{0000}0000{#2}#3 #4 #5 }
-\@@_tmp:w {xi} {\use_none:n #3#4+#5}{ 000{0000}0000{#2}#3 #4 #5 }
-\@@_tmp:w {xii} { #3#4+#5}{ {0000}0000{0000}#2 #3 #4 #5 }
-\@@_tmp:w {xiii}{\use_none:nnn#2#3+#4#5}{ 0{0000}0000{0000}#2 #3 #4 #5 }
-\@@_tmp:w {xiv} {\use_none:nn #2#3+#4#5}{ 00{0000}0000{0000}#2 #3 #4 #5 }
-\@@_tmp:w {xv} {\use_none:n #2#3+#4#5}{ 000{0000}0000{0000}#2 #3 #4 #5 }
-\@@_tmp:w {xvi} { #2#3+#4#5}{{0000}0000{0000}0000 #2 #3 #4 #5}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_decimate_pack:nnnnnnnnnnw}
-% The computation of the \meta{rounding} digit leaves an unfinished
-% \cs{int_value:w}, which expands the following functions. This
-% allows us to repack nicely the digits we keep. Those digits come
-% as an alternation of unbraced and braced blocks of $4$ digits,
-% such that the first $5$ groups of token consist in $4$ single digits,
-% and one brace group (in some order), and the next $5$ have the same
-% structure. This is followed by some digits and a semicolon.
-% \begin{macrocode}
-\cs_new:Npn \@@_decimate_pack:nnnnnnnnnnw #1#2#3#4#5
- { \@@_decimate_pack:nnnnnnw { #1#2#3#4#5 } }
-\cs_new:Npn \@@_decimate_pack:nnnnnnw #1 #2#3#4#5#6
- { {#1} {#2#3#4#5#6} }
-% \end{macrocode}
-% \end{macro}
-% ^^A end[todo]
-%
-% \subsection{Functions for use within primitive conditional branches}
-%
-% The functions described in this section are not pretty and can easily
-% be misused. When correctly used, each of them removes one \cs{fi:} as
-% part of its parameter text, and puts one back as part of its
-% replacement text.
-%
-% Many computation functions in \pkg{l3fp} must perform tests on the
-% type of floating points that they receive. This is often done in an
-% \cs{if_case:w} statement or another conditional statement, and only a
-% few cases lead to actual computations: most of the special cases are
-% treated using a few standard functions which we define now. A typical
-% use context for those functions would be
-% \begin{syntax}
-% \cs{if_case:w} \meta{integer} \cs{exp_stop_f:}
-% | |\cs{@@_case_return_o:Nw} \meta{fp var}
-% \cs{or:} \cs{@@_case_use:nw} \Arg{some computation}
-% \cs{or:} \cs{@@_case_return_same_o:w}
-% \cs{or:} \cs{@@_case_return:nw} \Arg{something}
-% \cs{fi:}
-% \meta{junk}
-% \meta{floating point}
-% \end{syntax}
-% In this example, the case $0$ returns the floating point
-% \meta{fp~var}, expanding once after that floating point. Case $1$
-% does \meta{some computation} using the \meta{floating point}
-% (presumably compute the operation requested by the user in that
-% non-trivial case). Case $2$ returns the \meta{floating point}
-% without modifying it, removing the \meta{junk} and expanding once
-% after. Case $3$ closes the conditional, removes the \meta{junk}
-% and the \meta{floating point}, and expands \meta{something} next. In
-% other cases, the \enquote{\meta{junk}} is expanded, performing some
-% other operation on the \meta{floating point}. We provide similar
-% functions with two trailing \meta{floating points}.
-%
-% \begin{macro}[EXP]{\@@_case_use:nw}
-% This function ends a \TeX{} conditional, removes junk until the next
-% floating point, and places its first argument before that floating
-% point, to perform some operation on the floating point.
-% \begin{macrocode}
-\cs_new:Npn \@@_case_use:nw #1#2 \fi: #3 \s_@@ { \fi: #1 \s_@@ }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_case_return:nw}
-% This function ends a \TeX{} conditional, removes junk and a floating
-% point, and places its first argument in the input stream. A quirk
-% is that we don't define this function requiring a floating point to
-% follow, simply anything ending in a semicolon. This, in turn, means
-% that the \meta{junk} may not contain semicolons.
-% \begin{macrocode}
-\cs_new:Npn \@@_case_return:nw #1#2 \fi: #3 ; { \fi: #1 }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_case_return_o:Nw}
-% This function ends a \TeX{} conditional, removes junk and a floating
-% point, and returns its first argument (an \meta{fp~var}) then expands
-% once after it.
-% \begin{macrocode}
-\cs_new:Npn \@@_case_return_o:Nw #1#2 \fi: #3 \s_@@ #4 ;
- { \fi: \exp_after:wN #1 }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_case_return_same_o:w}
-% This function ends a \TeX{} conditional, removes junk, and returns
-% the following floating point, expanding once after it.
-% \begin{macrocode}
-\cs_new:Npn \@@_case_return_same_o:w #1 \fi: #2 \s_@@
- { \fi: \@@_exp_after_o:w \s_@@ }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_case_return_o:Nww}
-% Same as \cs{@@_case_return_o:Nw} but with two trailing floating
-% points.
-% \begin{macrocode}
-\cs_new:Npn \@@_case_return_o:Nww #1#2 \fi: #3 \s_@@ #4 ; #5 ;
- { \fi: \exp_after:wN #1 }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\@@_case_return_i_o:ww, \@@_case_return_ii_o:ww}
-% Similar to \cs{@@_case_return_same_o:w}, but this returns the first
-% or second of two trailing floating point numbers, expanding once
-% after the result.
-% \begin{macrocode}
-\cs_new:Npn \@@_case_return_i_o:ww #1 \fi: #2 \s_@@ #3 ; \s_@@ #4 ;
- { \fi: \@@_exp_after_o:w \s_@@ #3 ; }
-\cs_new:Npn \@@_case_return_ii_o:ww #1 \fi: #2 \s_@@ #3 ;
- { \fi: \@@_exp_after_o:w }
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Integer floating points}
-%
-% \begin{macro}[EXP, pTF]{\@@_int:w}
-% Tests if the floating point argument is an integer. For normal
-% floating point numbers, this holds if the rounding digit resulting
-% from \cs{@@_decimate:nNnnnn} is~$0$.
-% \begin{macrocode}
-\prg_new_conditional:Npnn \@@_int:w \s_@@ \@@_chk:w #1 #2 #3 #4;
- { TF , T , F , p }
- {
- \if_case:w #1 \exp_stop_f:
- \prg_return_true:
- \or:
- \if_charcode:w 0
- \@@_decimate:nNnnnn { \c_@@_prec_int - #3 }
- \@@_use_i_until_s:nw #4
- \prg_return_true:
- \else:
- \prg_return_false:
- \fi:
- \else: \prg_return_false:
- \fi:
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Small integer floating points}
-%
-% \begin{macro}[EXP]{\@@_small_int:wTF}
-% \begin{macro}[EXP]
-% {
-% \@@_small_int_true:wTF,
-% \@@_small_int_normal:NnwTF,
-% \@@_small_int_test:NnnwNTF
-% }
-% Tests if the floating point argument is an integer or $\pm\infty$.
-% If so, it is clipped to an integer in the range $[-10^{8},10^{8}]$
-% and fed as a braced argument to the \meta{true code}.
-% Otherwise, the \meta{false code} is performed.
-%
-% First filter special cases: zeros and infinities are integers,
-% \texttt{nan} is not. For normal numbers, decimate. If the rounding
-% digit is not $0$ run the \meta{false code}. If it is, then the
-% integer is |#2| |#3|; use |#3| if |#2| vanishes and otherwise
-% $10^{8}$.
-% \begin{macrocode}
-\cs_new:Npn \@@_small_int:wTF \s_@@ \@@_chk:w #1#2
- {
- \if_case:w #1 \exp_stop_f:
- \@@_case_return:nw { \@@_small_int_true:wTF 0 ; }
- \or: \exp_after:wN \@@_small_int_normal:NnwTF
- \or:
- \@@_case_return:nw
- {
- \exp_after:wN \@@_small_int_true:wTF \int_value:w
- \if_meaning:w 2 #2 - \fi: 1 0000 0000 ;
- }
- \else: \@@_case_return:nw \use_ii:nn
- \fi:
- #2
- }
-\cs_new:Npn \@@_small_int_true:wTF #1; #2#3 { #2 {#1} }
-\cs_new:Npn \@@_small_int_normal:NnwTF #1#2#3;
- {
- \@@_decimate:nNnnnn { \c_@@_prec_int - #2 }
- \@@_small_int_test:NnnwNw
- #3 #1
- }
-\cs_new:Npn \@@_small_int_test:NnnwNw #1#2#3#4; #5
- {
- \if_meaning:w 0 #1
- \exp_after:wN \@@_small_int_true:wTF
- \int_value:w \if_meaning:w 2 #5 - \fi:
- \if_int_compare:w #2 > \c_zero_int
- 1 0000 0000
- \else:
- #3
- \fi:
- \exp_after:wN ;
- \else:
- \exp_after:wN \use_ii:nn
- \fi:
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \subsection{Fast string comparison}
-%
-% \begin{macro}{\@@_str_if_eq:nn}
-% A private version of the low-level string comparison function.
-% \begin{macrocode}
-\cs_new_eq:NN \@@_str_if_eq:nn \tex_strcmp:D
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Name of a function from its \pkg{l3fp-parse} name}
-%
-% \begin{macro}[EXP]{\@@_func_to_name:N, \@@_func_to_name_aux:w}
-% The goal is to convert for instance \cs{@@_sin_o:w} to |sin|.
-% This is used in error messages hence does not need to be fast.
-% \begin{macrocode}
-\cs_new:Npn \@@_func_to_name:N #1
- {
- \exp_last_unbraced:Nf
- \@@_func_to_name_aux:w { \cs_to_str:N #1 } X
- }
-\cs_set_protected:Npn \@@_tmp:w #1 #2
- { \cs_new:Npn \@@_func_to_name_aux:w ##1 #1 ##2 #2 ##3 X {##2} }
-\exp_args:Nff \@@_tmp:w { \tl_to_str:n { @@_ } }
- { \tl_to_str:n { _o: } }
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Messages}
-%
-% Using a floating point directly is an error.
-% \begin{macrocode}
-\msg_new:nnnn { fp } { misused }
- { A~floating~point~with~value~'#1'~was~misused. }
- {
- To~obtain~the~value~of~a~floating~point~variable,~use~
- '\token_to_str:N \fp_to_decimal:N',~
- '\token_to_str:N \fp_to_tl:N',~or~other~
- conversion~functions.
- }
-\prop_gput:Nnn \g_msg_module_name_prop { fp } { LaTeX }
-\prop_gput:Nnn \g_msg_module_type_prop { fp } { }
-% \end{macrocode}
-%
-% \begin{macrocode}
-%</package>
-% \end{macrocode}
-%
-% \end{implementation}
-%
-% \PrintChanges
-%
-% \PrintIndex