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