% \iffalse meta-comment % %% File: l3fp.dtx Copyright (C) 2011-2014 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 %% %% http://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 released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX3 Project Team. %% %% ----------------------------------------------------------------------- %% % %<*driver|package> \RequirePackage{l3bootstrap} \GetIdInfo$Id: l3fp.dtx 4642 2014-01-04 17:28:32Z joseph $ {L3 Floating points} % %<*driver> \documentclass[full]{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 % \thanks{This file describes v\ExplFileVersion, % last revised \ExplFileDate.}^^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 \ExplFileDate} % % \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: 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 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,y,\ldots)$, $\min(x,y,\ldots)$, % $\operatorname{abs}(x)$. % \item Rounding functions: $\operatorname{round}(x,n)$ rounds to % closest, $\operatorname{trunc}(x,n)$ rounds towards zero, % $\operatorname{floor}(x,n)$ rounds towards~$-\infty$, % $\operatorname{ceil}(x,n)$ rounds towards~$+\infty$. And % \emph{(not yet)} modulo, and \enquote{quantize}. % \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{\meta{type}_use:N}) of % integer, dimension, and skip variables to floating points, % expressing dimensions in points and ignoring the stretch and % shrink components of skips. % \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. 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} % But in all fairness, this 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} % \usepackage{xparse, siunitx} % \ExplSyntaxOn % \NewDocumentCommand { \calcnum } { m } % { \num { \fp_to_scientific:n {#1} } } % \ExplSyntaxOff % \calcnum { 2 pi * sin ( 2.3 ^ 5 ) } % \end{verbatim} % % \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} will % initially be~$+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} will be 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{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}. % \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}. % \end{function} % % \section{Using floating point numbers} % % \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. This function is identical to \cs{fp_to_decimal:n}. % \end{function} % % \begin{function}[EXP, added = 2012-05-08, updated = 2012-07-08, % tested = m3fp-convert003] % {\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. % \end{function} % % \begin{function}[EXP, updated = 2012-07-08, tested = m3fp-convert003] % {\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}. 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. The values $\pm\infty$ and~\nan{} trigger an % \enquote{invalid operation} exception. % \end{function} % % \begin{function}[EXP, updated = 2012-07-08, tested = m3fp-convert003] % {\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. The values $\pm\infty$ and~\nan{} trigger % an \enquote{invalid operation} exception. % \end{function} % % \begin{function}[EXP, added = 2012-05-08, updated = 2012-07-08, % tested = m3fp-convert003] % {\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. % \end{function} % % \begin{function}[EXP, updated = 2012-07-08, tested = m3fp-convert003] % {\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 (see % \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. % \end{function} % % \begin{function}[EXP, updated = 2012-07-08, tested = m3fp-convert003] % {\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. 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 point % numbers $x$ and~$y$ may obey four mutually exclusive relations: % $xy$, or $x$ and~$y$ are not ordered. The latter % case occurs exactly when either operand is~\nan{}, and this relation % is denoted by the symbol~|?|. 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} % \end{function} % % \begin{function}[EXP, pTF, updated = 2012-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 % point numbers $x$ and~$y$ may obey four mutually exclusive % relations: $xy$, or $x$ and~$y$ are not ordered. The % latter case occurs exactly when one of the operands is~\nan{}, and % this relation is denoted by the symbol~|?|. 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 % floatin 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). % \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} will be inserted into % the input stream again and a loop will occur 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} will be inserted into the % input stream again and a loop will occur 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 will be repeated, and a loop will occur 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 will be repeated, and a loop will occur until the test is % \texttt{false}. % \end{function} % % \begin{function}[rEXP, added = 2012-08-16, 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} will be inserted into % the input stream again and a loop will occur until the % \meta{relation} is \texttt{true}. % \end{function} % % \begin{function}[rEXP, added = 2012-08-16, 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} will be inserted into the % input stream again and a loop will occur until the \meta{relation} % is \texttt{false}. % \end{function} % % \begin{function}[rEXP, added = 2012-08-16, 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 will be repeated, and a loop will occur until the test is % \texttt{true}. % \end{function} % % \begin{function}[rEXP, added = 2012-08-16, 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 will be repeated, and a loop will occur until the test is % \texttt{false}. % \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 = 2012-05-08, 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 % \textsc{IEEE} standard defines $5$ types of exceptions. % \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 almost any % operation involving a \nan{}. This normally results in a \nan{}, % except for conversion functions whose target type does not have a % notion of \nan{} (\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 \emph{e.g.}, $\ln(0)$ or $\cot(0)$. This % results in $\pm\infty$. % \item \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 is associated a \enquote{flag}, which can be either % \emph{on} or \emph{off}. By default, the \enquote{invalid operation} % exception triggers an (expandable) error, and raises the corresponding % flag. Other exceptions only raise the corresponding flag. The state % of the flag can be tested % and modified. The behaviour when an exception occurs can be modified % (using \cs{fp_trap:nn}) to either produce an error and turn the flag % on, or only turn the flag on, or do nothing at all. % % \begin{function}[EXP, pTF, added = 2012-08-08, tested = m3fp-traps001] % {\fp_if_flag_on:n} % \begin{syntax} % \cs{fp_if_flag_on_p:n} \Arg{exception} % \cs{fp_if_flag_on:nTF} \Arg{exception} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if the flag for the \meta{exception} is on, which normally % means the given \meta{exception} has occurred. % \emph{This function is experimental, and may be altered or removed.} % \end{function} % % \begin{function}[added = 2012-08-08, tested = m3fp-traps001] % {\fp_flag_off:n} % \begin{syntax} % \cs{fp_flag_off:n} \Arg{exception} % \end{syntax} % Locally turns off the flag which indicates whether the % \meta{exception} has occurred. % \emph{This function is experimental, and may be altered or removed.} % \end{function} % % \begin{function}[EXP, added = 2012-08-08, tested = m3fp-traps001] % {\fp_flag_on:n} % \begin{syntax} % \cs{fp_flag_on:n} \Arg{exception} % \end{syntax} % Locally turns on the flag to indicate (or pretend) that the % \meta{exception} has occurred. Note that this function is % expandable: it is used internally by \pkg{l3fp} to signal when % exceptions do occur. % \emph{This function is experimental, and may be altered or removed.} % \end{function} % % \begin{function}[added = 2012-07-19, updated = 2012-08-08, % 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{invalid_operation}, % \texttt{division_by_zero}, \texttt{overflow}, or \texttt{underflow}) % 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} % % \section{Viewing floating points} % % \begin{function}[added = 2012-05-08, updated = 2012-08-14, % 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} % % \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 0.d_1d_2\ldots{}d_{16} \cdot 10^{n}$, a normal floating % point number, with $d_i\in [0,9]$, $d_1\neq 0$, and $\lvert n\rvert % \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); % \item [\emph{(not yet)}] subnormal numbers $\pm 0.d_1d_2\ldots{}d_{16} % \cdot 10^{-\ExplSyntaxOn\int_use:N \c__fp_max_exponent_int}$ with % $d_1=0$. % \end{itemize} % Normal floating point numbers are stored in base $10$, with $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~|0| characters, and an % optional |.| character), 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. % % 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 will be ignored. % \item Any unrecognizable string triggers an error, and produces a % \nan{}. % \end{itemize} % % Note that~|e-1| is not a representation of $10^{-1}$, because it could % be mistaken with the difference of \enquote{\texttt{e}} and $1$. This % is consistent with several other programming languages. However, in % order to avoid confusions, |e-1| is not considered to be this % difference either. To input the base of natural logarithms, use % \texttt{exp(1)} or \cs{c_e_fp}. % % \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 Implicit multiplication by juxtaposition (\texttt{2pi}, % \texttt{3(4+5)}, \emph{etc}). % \item Function calls (\texttt{sin}, \texttt{ln}, \emph{etc}). % \item Binary |**| and |^| (right associative). % \item Unary |+|, |-|, |!|. % \item Binary |*|, |/| and |%|. % \item Binary |+| and |-|. % \item Comparisons |>=|, |!=|, | 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} % % \begingroup \catcode`\|=12 % \begin{function}[tested = m3fp-logic002]{TWO BARS} % \begin{syntax} % \cs{fp_eval:n} \{ \meta{operand_1} \texttt{||} \meta{operand_2} \} % \end{syntax} % If \meta{operand_1} is true (non-zero), use that value, otherwise the % value of \meta{operand_2}. Both \meta{operands} are evaluated in all % cases. % \end{function} % \endgroup % % \begingroup \catcode`\&=12 % \begin{function}[tested = m3fp-logic002]{&&} % \begin{syntax} % \cs{fp_eval:n} \{ \meta{operand_1} \texttt{&&} \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. % \end{function} % \endgroup % % \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_j} \meta{operand_{i+1}} are true, and % $+0$ otherwise. All \meta{operands} are evaluated 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. % \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. % \end{function} % % \begin{function}[tested = m3fp-basics004]{+, -, !} % \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}, and |!| \meta{operand} evaluates to $1$ if % \meta{operand} is false and $0$ otherwise (this is the \texttt{not} % boolean function). Those operations never raise exceptions. % \end{function} % % \begingroup\catcode`\^=12 % \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$. The \enquote{invalid operation} exception occurs % if \meta{operand_1} is negative or $-0$, and \meta{operand_2} is not % an integer, unless the result is zero (in that case, the sign is % chosen arbitrarily to be $+0$). \enquote{Division by zero} occurs % when raising $\pm 0$ to a strictly negative power. % \enquote{Underflow} and \enquote{overflow} occur when appropriate. % \end{function} % \endgroup % % \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}. This function % does not raise any exception beyond those raised when computing its % operand \meta{fpexpr}. 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. % \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. % \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{}, the result is % \nan{}. Those operations do not raise exceptions. % \end{function} % % \begin{function}^^A % [tested = {m3fp-round001, m3fp-round002}, added = 2013-12-14] % {round, trunc, ceil, floor} % \begin{syntax} % \cs{fp_eval:n} \{ |round| |(| \meta{fpexpr} |)| \} % \cs{fp_eval:n} \{ |round| |(| \meta{fpexpr_1} , \meta{fpexpr_2} |)| \} % \end{syntax} % Evaluates $\meta{fpexpr_1}=x$ and $\meta{fpexpr_2}=n$, 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$~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$, and % if $x$~is half-way between two such multiples, the even multiple % is chosen (\enquote{ties to even}); % \item |floor|, or the deprecated |round-|, yields the largest % multiple of~$10^{-n}$ smaller or equal to~$x$ (\enquote{round % towards negative infinity}); % \item |ceil|, or the deprecated |round+|, yields the smallest % multiple of~$10^{-n}$ greater or equal to~$x$ (\enquote{round % towards positive infinity}); % \item |trunc|, or the deprecated |round0|, 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$). % \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}(8pi)$ is not quite % zero, while its analog $\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. % \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}(8pi)$ is not quite % zero, while its analog $\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. % \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. % \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. % \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. Only the \enquote{underflow} exception can occur. % \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. Only the \enquote{underflow} % exception can occur. % \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; 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{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-08, tested = m3fp-convert002] % {\dim_to_fp:n} % \begin{syntax} % \cs{dim_to_fp:n} \Arg{dimexpr} % \end{syntax} % Expands to an internal floating point number equal to the value of % the \meta{dimexpr} in \texttt{pt}. Since dimension expressions are % evaluated much faster than their floating point equivalent, % \cs{dim_to_fp:n} can be used to speed up parts of a computation % where a low precision is acceptable. % \end{function} % % \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. This function does not raise any exception beyond % those raised when evaluating its argument. Within floating point % expressions, |abs()| can be used. % \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. This function does not raise any % exception beyond those raised when evaluating its argument. 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_+|; 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 Decide what exponent range to consider. % \item Support signalling \texttt{nan}. % \item Modulo and remainder, and rounding functions |quantize|, % |quantize0|, |quantize+|, |quantize-|, |quantize=|, |round=|. % Should the modulo also be provided as (catcode 12) |%|? % \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 Random numbers (pgfmath provides |rnd|, |rand|, |random|), with % seed reset at every \cs{fp_set:Nn}. % \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 \cs{fp_if_nan:nTF}, and an |isnan| function? % \item Support keyword arguments? % \end{itemize} % \pkg{Pgfmath} also provides box-measurements (depth, height, width), but % boxes are not possible expandably. % % Bugs. (Exclamation points mark important bugs.) % \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. % \item The overflow trap receives the wrong argument in % \pkg{l3fp-expo} (see |exp(1e5678)| in \file{m3fp-traps001}). % \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 Fix the |TWO BARS| business with the index. % \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)? Perhaps for including comments inside the computation % itself?? % \end{itemize} % % \end{documentation} % % \begin{implementation} % % \section{\pkg{l3fp} implementation} % % \begin{macrocode} %<*package> % \end{macrocode} % % \begin{macrocode} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} \__expl_package_check: % \end{macrocode} % % \begin{macrocode} % % \end{macrocode} % % \end{implementation} % % \PrintIndex