}, \oper{==}, \oper{<=}, \oper{>=},
\oper{!=} (they can be chained)\strut\\\hline
%
\prec{8}& Boolean conjunction \oper{\Ampersand\Ampersand} and
its alias \oper{'and'}\strut\\\hline
%
\prec{6}& Boolean disjunction \oper{\string|\string|} and
its alias \oper{'or'}. Also \oper{'xor'} and
\oper{\strut..}, \oper{..[},
\oper{{]..}}, and \oper{:} have
this precedence\strut\\\hline
%
\prec{4}& the brackets for slicers and extractors \oper{\empty[},
\oper{\empty]}\strut\\\hline
%
\prec{3}& the comma \oper{,}\strut\\\hline
%
\prec{2}& the bracketers \oper{[}, \oper{]} construct nestable «arrays»\strut\\\hline
%
\prec{1}& the parentheses \oper{(}, \oper{)}, and the semi-colon
\oper{;} in \func{iter}, \func{rseq}, and further structures\strut\\\hline
%
\hline
%
\multicolumn{2}{|p{.6\textwidth}|}{%
\begin{itemize}[nosep]
\item Binary operators have a left and a right precedence, which for
most coincide. The right precedence is indicated within parentheses.
\item
\hyperref[ssec:tacit multiplication]{Tacit multiplication} has an elevated
left precedence level: |(1+2)/(3+4)5|
is computed as |(1+2)/((3+4)*5)| and |x/2y| is interpreted as |x/(2*y)|
when using variables.
\end{itemize}
}\\\hline
\end{tabular}
\caption{Precedence levels}
\label{tab:precedences}
\etoctoccontentsline {table}{\protect\emph{Table of precedence levels of operators}}
\restorehtdpstrutbox
\end{table}
The entries of \autoref{tab:precedences} are hyperlinked to the more detailed
discussion at each level. In these entries the number within parentheses
indicates the right-\hskip0pt precedence, if it differs from the left.
\begin{description}
%[parsep=0pt, listparindent=\leftmarginiii]
% [parsep=0pt,align=left,itemindent=0pt,
% leftmargin=\leftmarginii, labelwidth=\leftmarginii, labelsep=0pt,
% labelindent=0pt, listparindent=\leftmarginiii]
\edef\Ampersand{\string&}%
\precdesc{$\infty$} At this highest level of precedence, one finds:
\begin{description}
\item[{\hyperref[ssec:builtinfunctions]{functions} and
\hyperref[ssec:uservariables]{variables}}]
Functions (even the logic functions
\func{!} and \func{?} whose names consist of a single non-letter character)
must be used with parentheses. These parentheses may arise from expansion
after the function name is parsed (there are exceptions which are documented
at the relevant locations.)
\operdesc{\empty\lowast} Python-like «unpacking» prefix operator. Sometimes one
needs to use it as function |*()| (but I can't find an example right now)
but most of the time parentheses are unneeded.
\operdesc{\strut.} is decimal mark; the number scanner treats it as an inherent,
optional and unique component of a being formed number.
|\xintexpr 0.^2+2^.0\relax| is interpreted as |0^2+2^0| and
thus produces \dtt{\xintexpr 0.^2+2^.0\relax}.
Since release |1.2| an isolated decimal mark is illegal
input in the \xintexprname parsers (it remains legal as argument to the
macros of \xintfracname).
\operdesc{e} scientific notation.
\operdesc{E} scientific notation. For output, see \csbxint{PFloatE}.
\operdesc{"} prefix for hexadecimal input. Only uppercase letters, and
one optional |.| separating integer and fractional hexadecimal parts.
This functionality
\centeredline{\fbox{requires to load explicitly package \xintbinhexname.}}%
\begin{everbatim*}
\xintexpr "FEDCBA9876543210\relax\newline
\xintexpr ".FEDCBA9876543210\relax\newline
\xintexpr 16^5-("F75DE.0A8B9+"8A21.F5746+16^-5)\relax
\end{everbatim*}
It is possible that in future the |"| prefix could be dropped in favour of
|0x| prefix. This would free |"| to be used for input of «string»-like
entities.
\end{description}
\precdesc{20}
The postfix operators |!| and the branching conditionals |?|, |??|.
\begin{description}
\operdesc{!} computes the factorial of an integer.
\operdesc{?} is used as |(stuff)?{yes}{no}|. It
evaluates |stuff| and chooses the |yes| branch if the result is
non-zero, else it executes |no|. After evaluation of |stuff| it acts as
a macro with two mandatory arguments within braces, chooses the
correct branch \emph{without evaluating the wrong one}. Once the braces
are removed, the parser scans and expands the uncovered material.
% so for
% example
% %
% \leftedline{|\xinttheiexpr (3>2)?{5+6}{7-1}2^3\relax|}
% %
% is legal and computes
% |5+62^3=|\dtt{\xinttheiexpr(3>2)?{5+(6}{7-(1}2^3)\relax}. It would be
% better practice to include here the |2^3| inside the branches. The
% contents of the branches may be arbitrary as long as once glued to what is
% next the syntax is respected: {|\xintexpr (3>2)?{5+(6}{7-(1}2^3)\relax|
% also works.}
\operdesc{??} is used as |(stuff)??{<0}{=0}{>0}|,
where |stuff| is anything, its sign is evaluated and depending on the sign
the correct branch is un-braced, the two others are discarded with no
evaluation of their contents.
% The un-braced branch will then be parsed as
% usual.
% %
% \leftedline{|\def\x{0.33}\def\y{1/3}|}
% %
% \leftedline{|\xinttheexpr (\x-\y)??{sqrt}{0}{1/}(\y-\x)\relax|%
% \dtt{=\def\x{0.33}\def\y{1/3}%
% \xinttheexpr (\x-\y)??{sqrt}{0}{1/}(\y-\x)\relax }}
% %
\end{description}
\precdesc{-} As unary operator, the minus sign inherits as precedence the
minimum of |12| (which is the precedence for addition and subtraction) and
of the (right-) precedence of the operators preceding it (if any).
\begin{everbatim*}
\xintexpr -3-4*-5^-7, (-3)-(4*(-(5^(-7))))\relax\newline
\xintexpr -3^-4*-5-7, (-((3^(-4))*(-5)))-7\relax\newline
|2^-10| gives \xintexpr 2^-10\relax\space
\end{everbatim*}and is thus perfectly legal, no need for parentheses.
The |+| character as prefix unary operator is simply ignored during
input parsing.
\precdesc{18}
\begin{description}
\operdesc{\string^}
\operdesc{\lowast\lowast} Both compute powers. They act in a right associative
way.\CHANGED{1.4g}
\begin{everbatim*}
\xintiiexpr 2^3^4\relax
\end{everbatim*}
\end{description}
% et:
% *2^-3^-4;
% (@_1) 0.991479137495678
% *2**-3**-4;
% (@_2) 0.991479137495678
% Python:
% >>> 2**-3**-4;
% 0.9914791374956781
\precdesc{16} see \hyperref[ssec:tacit multiplication]{Tacit multiplication}.
\precdesc{14}
\begin{description}
\operdesc{\lowast} multiplication
\operdesc{/} division:
\begin{itemize}
\item in \csbxint{eval}: exact division in the field of rational numbers (not
automatically reduced to lowest terms),
\item in \csbxint{floateval}: correct rounding of the exact division; the two
operands are, if necessary, float-rounded before the fraction is
evaluated and rounded (to obtain the correcty rounded |A/B|
without prior rounding of |A| and |B| see \func{qfloat}),
\item in \csbxint{iieval}: for compatibility with the legacy behaviour of
|/| in |\numexpr|, it rounds the exact fraction \emph{with half-integers
going towards the infinity of the same sign}.
\end{itemize}
The division is left-associative. Example:
\begin{everbatim*}
\xintexpr reduce(100/50/2)\relax
\end{everbatim*}
\operdesc{//} floored division (and thus produces an integer, see
\func{divmod} for details)
\operdesc{/:} the associated modulo (see \func{divmod} and \func{mod})
Left-associativity applies to the division operators:
\begin{everbatim*}
\xintexpr 100000/:13, 100000 'mod' 13\relax, \xintexpr 100000/:13/13\relax
\end{everbatim*}
Nothing special needs to be done in contexts such as \LaTeX3
|\ExplSyntaxOn| where |:| is of catcode letter, but if |:| is an active
character (for example in \LaTeX\ with babel+french)
one needs to use input such as |/\string :| (or replace it with usage of the function \func{mod}).
\operdesc{'mod'} is same as \oper{/:}.
\fbox{Attention:}\IMPORTANTf{} with \ctanpackage{polexpr} loaded, which
allows |'| in variable and function names, |'mod'| can not follow
a variable name. Add parentheses around the variable, or use |/:|.
\end{description}
\precdesc{12}
\begin{description}
\operdesc{+} addition
\operdesc{-} subtraction. According to the general left-associativity rule in
case of equal precedence, it is
left associative:
\begin{everbatim*}
\xintiiexpr 100-50-2\relax
\end{everbatim*}
\end{description}
\precdesc{10} Comparison operators are (as in Python) all at the same level of
precedence, use parentheses for disambiguation.
\begin{description}
\operdesc{<} |a**} |a>b| evaluates to \dtt{1} if the strict inequality holds to \dtt{0}
if not.
\operdesc{==} |a==b| evaluates to \dtt{1} if equality holds to \dtt{0}
if not.
\operdesc{<=} |a<=b| evaluates to \dtt{1} if left hand side is at most equal
to right hand side, to \dtt{0}
if not.
\operdesc{>=} |a>=b| evaluates to \dtt{1} if left hand side is at least equal
to right hand side, to \dtt{0}
if not.
\operdesc{!=} |a!=b| evaluates to \dtt{1} if they differ, to \dtt{0}
if not.
\end{description}
Comparisons\NewWith{1.4b} can be chained arbitrarily, e.g., |x < y <= z !=
t| is equivalent to |x < y 'and' y <= z 'and' z != t| (and also to |all(x 1}{true}{\error}, \xintifboolexpr{1<=2>=3<4>1}{\error}{false},
\xintifboolexpr{3 != 3! == 6 != 4! == 24}{true}{\error}
\end{everbatim*}
\precdesc{8}
\begin{description}
\operdesc{\Ampersand\Ampersand} logical conjunction. Evaluates to \dtt{1} if
both sides are non-zero, to \dtt{0} if not.
\operdesc{'and'} same as \verb+&&+. See
also the \func{all} multi-arguments function.
\fbox{Attention:}\IMPORTANTf{} with \ctanpackage{polexpr} loaded, which
allows |'| in variable and function names, |'and'| can not follow
a variable name. Add parentheses around the variable, or use |&&|.
\end{description}
\precdesc{6}
\begin{description}
\operdesc{\string|\string|} logical (inclusive) disjunction. Evaluates to
\dtt{1} if one or both sides are non-zero, to \dtt{0} if not.
\operdesc{'or'} same as as \verb+||+. See also the \func{any} multi-arguments
function.
\fbox{Attention:}\IMPORTANTf{} with \ctanpackage{polexpr} loaded, which
allows |'| in variable and function names, |'or'| can not follow
a variable name. Add parentheses around the variable, or use \verb=||=.
\operdesc{'xor'} logical (exclusive) disjunction.
\fbox{Attention:}\IMPORTANTf{} with \ctanpackage{polexpr} loaded, which
allows |'| in variable and function names, |'xor'| can not follow a variable
name. Add parentheses around the variable, or use the \func{xor} function syntax.
\operdesc{\strut..}
\operdesc{..[}
\operdesc{{]..}} Syntax for arithmetic
progressions. See \autoref{ssec:arithseq}.
\operdesc{:} This is a separator involved in |[a:b]| Python-like slicing syntax.
\end{description}
\precdesc{4}
\begin{description}
\operdesc{\empty[}
\operdesc{\empty]}
Involved in Python-like slicing |[a:b]| and extracting |[N]| syntax. And its
extension à la NumPy |[a:b,N,c:d,...,:]|. Ellipsis |...| is not yet implemented.
The «step» parameter as in |[a:b:step]| is not yet implemented.
\end{description}
\precdesc{3}
\begin{description}
\operdesc{,}
The comma separates expressions (or function arguments).%
%
\footnote{The comma
is really like a binary operator, which may be called ``join''. It has
lowest precedence of all (apart the parentheses) because when it is
encountered all postponed operations are executed in order to finalize its
\emph{first} operand; only a new comma or a closing parenthesis or the end
of the expression will finalize its \emph{second} operand.}
%
\begin{everbatim*}
\xintiiexpr 2^3,3^4,5^6\relax
\end{everbatim*}
\end{description}
\precdesc{2}
\begin{description}
\operdesc{[}
\operdesc{]} The bracketers construct nestable «array-like»
structures. Arbitrary (heterogeneous) nesting is allowed. For output related
matters see \csbxint{thealign} (its usage is optional, without it rendering
is «one-dimensional»). Output shape of non-homogeneous arrays is to
be considered unstable at this time.
\end{description}
\precdesc{1}
\begin{description}
\operdesc{(}
\operdesc{)}
The parentheses serve as mandatory part of the syntax for functions, and to
disambiguate precedences.%
%
\footnote{It is not apt to describle the
opening parenthesis as an operator, but the closing parenthesis is analogous
to a postfix unary operator. It has lowest precedence which means
that when it is encountered all postponed operations are executed to finalize
its operand. The start of this operand was decided by the opening
parenthesis.}
%
They do not construct any nested structure.
\operdesc{;} The semi-colon as involved as part of the syntax of \func{iter},
\func{rseq}, \func{ndseq}, \func{ndmap} has the same
precedence as a closing parenthesis.
\end{description}
\item[|\relax|] This is the expression terminator for \csbxint{expr} et al.
It may arise from expansion during the parsing itself. As alternative to
\csbxint{expr} (et al.) use
\csbxint{eval} (et al.) which have the usual macro interface (with one mandatory
argument).
\end{description}
The |;| also serves as syntax terminator for \csbxint{defvar} and
\csbxint{deffunc}. It can in this rôle not arise from expansion as the
expression body up to it is fetched by a delimited macro. But this is done in
a way which does not require any specific hiding for inner semi-colons as
involved in the syntax of \func{iter}, etc...
\subsection{Built-in functions}\label{ssec:builtinfunctions}
See \autoref{tab:functions} whose elements are hyperlinked to the
corresponding definitions.
Functions are at the same top level of priority. All functions even
\func{?} and \func{!} require parentheses around their arguments.
% Table of functions
\begin{table}[htbp]
\capstart
\centering
\xintAssignArray\xintCSVtoList{!, ?, \textasciigrave\lowast\textasciigrave, \textasciigrave+\textasciigrave,
abs, add, all, any, acos, acosd, Arg, Argd, asin, asind, atan, atand,
atan2, atan2d,
binomial, bool,
ceil, cos, cosd, cot, cotd, cotg, csc, cscd,
divmod, even, exp,
factorial, first, flat, float, float\string_dgt, floor, frac, gcd,
if, ifint, ifone, ifsgn, ilog10, iquo, irem, isint, isone, iter, iterr, inv,
last, lcm, len, log, log10, max, min, mod, mul,
ndmap, ndseq, ndfillraw,
not, num, nuple, odd,
pArg, pArgd, pfactorial, pow, pow10, preduce,
qfloat, qfrac, qint, qrand, qraw,
random, randrange, rbit, reduce, reversed, round, rrseq, rseq,
sec, secd, seq, sgn, sin, sinc, sind, sqr, sqrt, sqrtr,
subs, subsm, subsn,
tan, tand, tg, togl, trunc, unpack,
xor, zip}
\to\Functions
\cnta\Functions{0}
\cntb\xinttheexpr ceil(\cnta/7)\relax\space
\newcommand\builtinfunction[1]{\expandafter\expandafter\expandafter\func
\expandafter\expandafter\expandafter{\Functions{#1}}}%
\centeredline{\begin{tabular}{|*{7}{p{2cm}|}}
\hline
\xintFor* #1 in {\xintSeq{1}{\cntb}}\do
{\builtinfunction{#1}&
\builtinfunction{#1+\cntb}&%
\builtinfunction{#1+2*\cntb}&%
\builtinfunction{#1+3*\cntb}&%
\builtinfunction{#1+4*\cntb}&%
\builtinfunction{#1+5*\cntb}&%
\ifnumgreater{#1+6*\cntb}{\cnta}
{}
{\builtinfunction{#1+6*\cntb}}%
\\\hline}%
\end{tabular}}
\caption{Functions (click on names)}\label{tab:functions}
\etoctoccontentsline {table}{\protect\emph{Table of functions in expressions}}
\etocsetnexttocdepth{subsubsection}
\localtableofcontents
\end{table}
Miscellaneous notes:
\begin{itemize}[nosep]
\item since release |1.3d| \func{gcd} and \func{lcm} are extended to apply
to fractions too, and do NOT require the loading of \xintgcdname,
\item The randomness related functions \func{random}, \func{qrand} and
\func{randrange} require that the \TeX\ engine provides the
\csa{uniformdeviate} or \csa{pdfuniformdeviate} primitive. This is
currently the case for |pdftex|, |(u)ptex|, |luatex|, and also for
|xetex| since \TeX Live 2019.\IMPORTANT
\item \func{togl} is provided for the case |etoolbox| package is loaded,
\item \func{bool}, \func{togl} use delimited macros to fetch their argument and the
closing parenthesis must be explicit, it can not arise from
on the spot expansion. The same holds for \func{qint}, \func{qfrac},
\func{qfloat}, \func{qraw}, \func{random} and \func{qrand}.
\item Also \hyperlink{ssec:dummies}{functions with dummy variables} use
delimited macros for some tasks. See the relevant explanations there.
\item Functions may be called with \emph{oples} as arguments as long as
the total length is the number of arguments the function expects.
\end{itemize}
\subsubsection{Functions with no argument}
\begin{description}
% [parsep=0pt,align=left,
% leftmargin=0pt, itemindent=0pt,
% labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt,
% listparindent=\leftmarginiii]
\funcdesc[]{random} returns a random float |x| verifying |0 <= x < 1|. It
obeys the prevailing precision as set by \csbxint{Digits}: i.e.\@ with |P|
being the precision the random float multiplied by |10^P| is an integer,
uniformly distributed in the |0..10^P-1| range.
This description implies that if |x| turns out to be |<0.1| then
its (normalized) mantissa has |P-1| digits and a trailing zero, if |x<0.01|
it has |P-2| digits and two trailing zeros, etc... This is what is observed
also with Python's |random()|, of course with |10| replaced there by radix
|2|.%
\begin{everbatim*}
\pdfsetrandomseed 12345
\xintDigits:=37\relax
\xintthefloatexpr random()\relax\newline
\xintthefloatexpr random()\relax\par
\end{everbatim*}
\funcdesc[]{qrand} returns a random float |0 <= x < 1| using \dtt{16} digits of
precision (i.e.\@ |10^{16}x| is an integer). This is provided when speed is a
at premium as it is optimized for precision being precisely \dtt{16}.%
\begin{everbatim*}
% still with 37 digits as prevailing float precision
\xintthefloatexpr qrand(), random()\relax\newline
\xintDigits:=16\relax
\xintthefloatexpr qrand(), random()\relax\par
\end{everbatim*}
One can use both |qrand()| and |random()| inside the |\xintexpr| parser too.
But inside the integer only |\xintiiexpr| parser they will cause some
low-level error as soon as they get involved in any kind of computation as
they use an internal format not recognized by the integer-only parser.
See further \func{randrange}, which generates random integers.
Currently there is no |uniform()| function%
%
\footnote{Because I am not sure how to handle rounding issues: should the
computation proceed exactly and a rounding be done only at very end?}
%
but it can be created by user:
\begin{everbatim*}
\xintdeffloatfunc uniform(a, b):= a + (b-a)*random();
\romannumeral\xintreplicate{10}%
{%
\xintthefloatexpr uniform(123.45678, 123.45679)\relax\newline
}%
\end{everbatim*}
\funcdesc[]{rbit} returns a random |0| or |1|.\NewWith{1.4}
\end{description}
\subsubsection{Functions with one argument}
\begin{description}
% [parsep=0pt,align=left,
% leftmargin=0pt, itemindent=0pt,
% labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt,
% listparindent=\leftmarginiii]
\funcdesc{num} truncates to the nearest integer (truncation towards zero). It
has the same sign as |x|, except of course with |-1**