From 4701e1a772599af5699534ae4090999a79e04ecf Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 19 Feb 2020 22:11:40 +0000 Subject: xint (19feb20) git-svn-id: svn://tug.org/texlive/trunk@53846 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/generic/xint/Makefile | 2 +- Master/texmf-dist/source/generic/xint/xint.dtx | 18998 ++++++++++++----------- 2 files changed, 9673 insertions(+), 9327 deletions(-) (limited to 'Master/texmf-dist/source/generic') diff --git a/Master/texmf-dist/source/generic/xint/Makefile b/Master/texmf-dist/source/generic/xint/Makefile index c8bdeb9bf21..0c18379fe15 100644 --- a/Master/texmf-dist/source/generic/xint/Makefile +++ b/Master/texmf-dist/source/generic/xint/Makefile @@ -1,5 +1,5 @@ # Makefile for building and installing xint -# (C) 2014-2019 Jean-Francois Burnol +# (C) 2014-2020 Jean-Francois Burnol # distributed under LPPL 1.3c. # Tested with GNU Make 3.81 on Mac OS X Mavericks, diff --git a/Master/texmf-dist/source/generic/xint/xint.dtx b/Master/texmf-dist/source/generic/xint/xint.dtx index 0962cf0553e..49fbd503512 100644 --- a/Master/texmf-dist/source/generic/xint/xint.dtx +++ b/Master/texmf-dist/source/generic/xint/xint.dtx @@ -3,27 +3,27 @@ % Extract all files via "etex xint.dtx" and do "make help" % or follow instructions from extracted README.md. %<*dtx> -\def\xintdtxtimestamp {Time-stamp: <31-01-2020 at 16:51:45 CET>} +\def\xintdtxtimestamp {Time-stamp: <19-02-2020 at 09:09:07 CET>} % %<*drv> %% --------------------------------------------------------------- -\def\xintdocdate {2020/01/31} -\def\xintbndldate{2020/01/31} -\def\xintbndlversion {1.4} +\def\xintdocdate {2020/02/19} +\def\xintbndldate{2020/02/19} +\def\xintbndlversion {1.4a} % %% README %% CHANGE LOG -%% xint 1.4 -%% 2020/01/31 +%% xint 1.4a +%% 2020/02/19 % -% Source: xint.dtx 1.4 2020/01/31 (doc 2020/01/31) +% Source: xint.dtx 1.4a 2020/02/19 (doc 2020/02/19) % Author: Jean-Francois Burnol % Info: Expandable operations on big integers, decimals, fractions % License: LPPL 1.3c % %<*!readme&!changes&!dohtmlsh&!makefile> %% --------------------------------------------------------------- -%% The xint bundle 1.4 2020/01/31 +%% The xint bundle 1.4a 2020/02/19 %% Copyright (C) 2013-2020 by Jean-Francois Burnol %%% xintkernel: Paraphernalia for the xint packages %%% xinttools: Expandable and non-expandable utilities @@ -123,8 +123,8 @@ Documentation Requirements ============ -Attention, release `1.4` requires the `\expanded` primitive available -in all major TeX engines since TeXLive 2019. +Attention, since release `1.4` `xintexpr` requires the `\expanded` +primitive (it is provided by all major TeX engines since TeXLive 2019). License ======= @@ -153,6 +153,37 @@ See `xint.pdf` for contact information. %-------------------------------------------------------- %<*changes>------------------------------------------------------- +`1.4a (2020/02/19)` +---- + +### Breaking changes + + - **xintexpr**: the macros implementing customization of + `\xintthealign` have modified meanings and names. + +### New features + + - **xintexpr**: `\xintthespaceseparated` (serves to provide + suitable input to PS-Tricks `\listplot`). + + - **xintexpr**: the optional argument `[D]` to `\xintieval/\xintiexpr` + can be negative, with the same meaning as the non-negative case, i.e. + *quantization* to an integer multiple of `10^(-D)`. + + The same applies to the functions `trunc()` and `round()`. And to + the `\xintTrunc`, `\xintRound`, `\xintiTrunc`, and `\xintiRound` macros + of **xintfrac**. + +### Bug fixes + + - **xintexpr**: usage of `round()` and `trunc()` within `\xintdeffunc` + got broken at `1.4`. + + - **xintexpr**: `add()` and `mul()` were supposedly accepting the + `omit`, `abort` and `break()` keywords since `1.4` but this was + broken. + + `1.4 (2020/01/31)` ---- @@ -2559,6 +2590,13 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin-left : 10%; \definecolor{JOLI}{RGB}{225,95,0} \definecolor{BLUE}{RGB}{0,0,255} \definecolor{niceone}{RGB}{38,128,192} +\definecolor{sedate}{RGB}{193,132,1} +\definecolor{saddlebrown}{rgb}{.545,.27,.075} +\definecolor{jfbrown}{RGB}{165,100,10}% + + + + \usepackage{eso-pic}% après xcolor sinon Option clash for package xcolor. \ifnum\dosourcexint=1 @@ -2843,6 +2881,8 @@ pdfpagemode=UseNone,% % Margin Notes % ============ +% Nothing here can be used in vertical mode directly. + \makeatletter \def\MyMarginNote {\@ifnextchar[\@MyMarginNote{\@MyMarginNote[]}}% \let\inmarg\MyMarginNote @@ -2914,6 +2954,22 @@ pdfpagemode=UseNone,% \vtop{\noindent Changed at #1!}\ }}}% \vskip\dp\strutbox }\strut\@esphack} +\def\DNU#1{\@bsphack + \vadjust{\vskip-\dp\strutbox + \hbox{\smash{\hbox to 0pt {\hss\color[named]{Red}% + \normalfont\small\bfseries + \hsize 1.5cm\rightskip.5cm minus.5cm + \vtop{\noindent Do not use! #1}\ }}}% + \vskip\dp\strutbox }\strut\@esphack} + +\def\UNSTABLE#1{\@bsphack + \vadjust{\vskip-\dp\strutbox + \hbox{\smash{\hbox to 0pt {\hss\color[named]{Red}% + \normalfont\small\bfseries + \hsize 1.5cm\rightskip.5cm minus.5cm + \vtop{\noindent Unstable! #1}\ }}}% + \vskip\dp\strutbox }\strut\@esphack} + \def\DEPRECATED #1{\@bsphack \vadjust{\vskip-\dp\strutbox \hbox{\smash{\hbox to 0pt {\hss\color[named]{PineGreen}% @@ -3008,7 +3064,11 @@ pdfpagemode=UseNone,% % ========================= \def\restoreMicroFont {\def\MicroFont {\ttbfamily\makestarlowast - \ifinlefted\else\ifineverb\else\color[named]{Blue}\fi\fi}} +% \ifinlefted\else\ifineverb\else\color[named]{verbatim}\fi\fi +% \ifinlefted\else\color[named]{saddlebrown}\fi +% \ifinlefted\else\color[named]{sedate}\fi + \ifinlefted\else\color[named]{jfbrown}\fi +}} \restoreMicroFont % Notice that \macrocode uses \macro@font which stores the \MacroFont meaning @@ -3016,7 +3076,11 @@ pdfpagemode=UseNone,% % not the meaning at \begin{document}. Comprenne qui pourra... \def\restoreMacroFont {\def\MacroFont {\ttbfamily - \ifinlefted\else\ifineverb\else\color[named]{Blue}\fi\fi}} +% \ifinlefted\else\ifineverb\else\color[named]{Blue}\fi\fi +% \ifinlefted\else\color[named]{Blue}\fi +% \ifinlefted\else\color[named]{sedate}\fi + \ifinlefted\else\color[named]{Brown}\fi +}} \restoreMacroFont % \verb @@ -3122,12 +3186,14 @@ pdfpagemode=UseNone,% \makeatletter \catcode`_ 11 -\def\everbatimtop {\MacroFont\small } +% Je modifie Mardi 18 février 2020 \MacroFont +% pour essayer couleur de foreground, +% je supprime donc le \ifineverb de \MacroFont. +% \newif\ifineverb +\def\everbatimtop {\MacroFont \small} \let\everbatimbottom\relax \let\everbatimhook\relax -\newif\ifineverb - \def\everbatim {\s@everbatim\@everbatim } \@namedef{everbatim*}{\s@everbatim\expandafter\@everbatimx\expandafter {\the\newlinechar}} @@ -3143,7 +3209,7 @@ pdfpagemode=UseNone,% \expandafter\let\csname endeverbatim*\endcsname \endeverbatim \def\s@everbatim {% - \ineverbtrue +% \ineverbtrue \everbatimtop % put there size changes \topsep \z@skip \partopsep \z@skip @@ -3337,8 +3403,8 @@ pdfpagemode=UseNone,% {{\char92\mbox{xint}\-\endlinechar-1 \makestarlowast \scantokens\expandafter{\detokenize{#1}}}}} -% \func, \funcdesc, \keyword, \keyworddesc, \prec, \precdesc -% ========================================================== +% \func, \funcdesc, \keyword, \keyworddesc, \prec, \precdesc, \oper, \operdesc +% ============================================================================ \newcommand\func[1]{\hyperlink{\detokenize{func-#1}}{#1}()} \newcommand\funcdesc[2][x]{\item[#2({#1})]\hypertarget{\detokenize{func-#2}}{}}% @@ -3348,17 +3414,21 @@ pdfpagemode=UseNone,% \let\prec\relax % sinon, c'est \mathchar"321E \newcommand\prec[1]{\hyperlink{\detokenize{prec-#1}}{#1}} -\newcommand\precdesc[1]{\item[$#1$]\hypertarget{\detokenize{prec-$#1$}}{}}% +\newcommand\precdesc[1]{\item[\texttt{#1}]\hypertarget{\detokenize{prec-#1}}{}\leavevmode}% \newcommand\var[1]{\hyperlink{\detokenize{var-#1}}{#1}} \newcommand\vardesc[1]{\item[#1]\hypertarget{\detokenize{var-#1}}{}}% +\newcommand\oper[1]{\hyperlink{\detokenize{oper-#1}}{#1}} +\newcommand\operdesc[1]{\item[\texttt{#1}]\hypertarget{\detokenize{oper-#1}}{}}% + + % \xintname, \xintnameimp etc... % ============================== \xintForpair #1#2 in -{(xintbundle,bundle), +{(xint bundle,bundle), (xintkernel,kernel), (xinttools,tools), (xintcore,core),(xint,xint),(xintbinhex,binhex),(xintgcd,gcd),% @@ -3455,22 +3525,22 @@ pdfpagemode=UseNone,% % 31 janvier 2020 - \def\DOCuserguide + \def\DOCxintexprintro {\texorpdfstring - {\hyperref[sec:xintexprsyntax]{\relax{\color{joli}\MakeNameUp{Syntax reference}}}}% - {Syntax reference}% + {\hyperref[part:1]{\relax{\color{joli}\MakeNameUp{Start here}}}}% + {Start here}% \xspace }% \def\DOCxintexprmacros {\texorpdfstring - {\hyperref[sec:oldxintexpr]{\relax{\color{joli}\MakeNameUp{Older macros and doc}}}}% - {Older macros and doc}% + {\hyperref[sec:oldxintexpr]{\relax{\color{joli}\MakeNameUp{xintexpr}}}}% + {xintexpr}% \xspace }% \def\DOCexamples {\texorpdfstring - {\hyperref[sec:examples]{\relax{\color{joli}\MakeNameUp{Old examples}}}}% - {Old examples}% + {\hyperref[sec:examples]{\relax{\color{joli}\MakeNameUp{Examples}}}}% + {Examples}% \xspace }% % Vendredi 15 juin 2018 @@ -3479,13 +3549,11 @@ pdfpagemode=UseNone,% % tokens, so it fails to recognize the commas which of course are of catcode12 \def\xintRunningHeader{{\inheadertrue\catcode`,12\relax \DOCxintfrontpage, + \DOCxintexprintro, \xintexprname, - \DOCuserguide, - \DOCxintexprmacros, \xinttrigname, \xintlogname, - \DOCexamples, - \xintbundlename}} + \csname xint bundlename\endcsname}} \markboth{\makebox[0pt]{\xintRunningHeader}}{\makebox[0pt]{\xintRunningHeader}} % Skips safely. @@ -3724,47 +3792,33 @@ pdfpagemode=UseNone,% \etocdepthtag.toc {part1A} -\csname xintexprnameUp\endcsname +\csname Start herenameUp\endcsname \part{The \xintexprname package} -\RaisedLabel[12]{sec:expr} +\RaisedLabel[12]{part:1} \etocsetnexttocdepth{section} \localtableofcontents -\section {Release \texttt{\xintbndlversion } of \texttt{\xintbndldate}} +\section {Start here} -\subsection{Start here} - -To use with |etex|, |pdftex|, ..., i.e. with \TeX{} engines activating the -e\TeX{} extensions: +\begin{itemize} +\item To use with |etex|, |pdftex|, ..., i.e. with \TeX{} engines activating + the e\TeX{} extensions: \begin{everbatim} \input xintexpr.sty +\xinteval{sqrt(13, 60)}% get it with 60 digits (correctly rounded) \end{everbatim} -To use with the \LaTeX{} macro layer (|latex|, |pdflatex|, ...): +\item To use with the \LaTeX{} macro layer (|latex|, |pdflatex|, ...): \begin{everbatim} \usepackage{xintexpr} +% and here you have to wait for \begin{document}... +% or rather you can start playing immediately: +\typeout{\xinteval{sqrt(13, 60)}} \end{everbatim} +\end{itemize} -\medskip - -|1.4| is a major release with new features and breaking changes. They are -summarized at top of |CHANGES.html| file (|texdoc --list xint|) and it is -recommended to read it as it may contain information which will not be -duplicated here. - -\medskip - -The formatted source code is available in file |sourcexint.pdf| -(|texdoc sourcexint|). - -\begin{framed} - The main breaking change is that \xintexprname |1.4| requires the - |\expanded| primitive, available with all major \TeX{} engines since \TeX - Live 2019. But the supporting macro packages \xintcorename, \xintname, - \xintfracname, \xinttoolsname do not (yet). -\end{framed} - -\xintexprname is a package to do expandable computations, either exactly or in +\xintexprname is a package to do expandable computations, either exactly +(i.e.\@ with fractions) or in the sense of floating point numbers at an arbitrary (reasonable% % \footnote{Trigonometrical functions are currently supported only up to about @@ -3775,18 +3829,28 @@ the sense of floating point numbers at an arbitrary (reasonable% will not attempt to support floating point calculations efficiently beyond that limit.}% ) precision. It supports user definition of variables and functions. Its -interface allows multiple comma separated expressions. +interface allows multiple comma separated expressions and nested structures: +\begin{everbatim*} +\xinteval{1, 2, [3, [4, 5]], 6} +\end{everbatim*}is impressive. No? + + \medskip +I am thinking about providing a console interface (using |rlwrap etex| as +sadly the e-\TeX{} binaries are not linked with the |readline| library) which +would mimick sessions with Maple or Python. + +\medskip + +For a quick impression of the package abilities, check (not yet, else you will +never come back here) the tables of its built-in +\hyperref[tab:precedences]{operators} and \hyperref[tab:functions]{functions}. -Iterated commas are like only one. The parentheses serve only to disambiguate -operator precedences or to hand-over variables to functions. One can add 100 -paired parentheses to |1, 2, 3| and it will not change anything. On the -other hand brackets |[|, |]| allow to define nested \emph{lists}, for example -\begin{everbatim*} -\xinteval{1, 2, [3, [4, 5]], 6} -\end{everbatim*} -is a pretty impressive feast. + +\medskip +The formatted source code is available in file |sourcexint.pdf| +(|texdoc sourcexint|). \medskip @@ -3797,7 +3861,35 @@ sections, which was a hard decision to take, almost breaking the palimpsest quality of the document). Reports welcome.% % \footnote{Thanks to Jürgen Gilg for keeping the author motivated and - helping proof-reading the documentation.} + helping proof-read the documentation.} + +\subsection{The \texttt{1.4a} release of \texttt{2020/02/19}} + +It is mainly a bugfix release. Check |CHANGES.html| file (|texdoc --list +xint|). + +\subsection{The \texttt{1.4} release of \texttt{2020/01/31}} + +|1.4| was a major release with new features and breaking changes. See +|CHANGES.html| file (|texdoc --list xint|) which may contain information +not yet included in the PDF documentation. + +The main new feature was (initial) support for nested structures. For a quick +idea of already available related abilities check for example \func{ndseq} or +\csbxint{defufunc}. See also \csbxint{thealign}. However, please grant the +author a few decades to finish absorbing Python/NumPy. + +\begin{framed} + The main breaking change is that \xintexprname |1.4| requires the + |\expanded| primitive. It is available with all major \TeX{} engines + since \TeX Live 2019. + + The macro packages \xintcorename, \xintname, + \xintfracname, \xinttoolsname et al. do not (yet) require |\expanded|. + + It is probable also |\pdfstrcmp| (|\strcmp|) will be required at some point + but it has been provided by major \TeX{} engines for a long time already. +\end{framed} \subsection{License and installation instructions} @@ -3819,101 +3911,6 @@ will offer to display one of those files: \item |CHANGES.html|. \end{itemize} - - -\subsection{Quick overview of syntax elements} - -Here is a (partial) list of the recognized syntax elements: -\begin{itemize} -\item the comma (to separate distinct computations or arguments to a - function), -\item parentheses, -\item square brackets,\NewWith{1.4} -\item \hyperref[tab:precedences]{operators}: - \begin{itemize}[nosep] -\item |+|, |-|, |*|, |/|, -\item powers via |^| or equivalently |**|, see \xintlogname for allowing usage of - them with fractional exponents (half-integer exponents are allowed by - default by \csbxint{floateval}), -\item |//| for floored division (attention that |-3//2| is computed as - |-(3//2)|) and |/:| its associated modulo, -\item branching via |(x)?{x non zero}{x zero}| and |(x)??{x<0}{x=0}{x>0}| - syntax, -\item Boolean logic |!()|, |?()| (truth values), |&&| (equivalently |'and'|), \verb+||+ (equivalently - |'or'|), |'xor'|, -\item comparison operators |==|, |!=|, |<|, |>|, |<=|, |>=|, -\item factorial (exact or floating point, but only for integer arguments) via - the postfix operator |!|. - \end{itemize} -\item the |"| is used to prefix hexadecimal (only uppercase) input. This is - NOT activated by default: package \xintbinhexname \fbox{must} be explicitly - loaded, -%\item |'| for octal input (\emph{not yet}), -\item various \hyperref[tab:functions]{functions}: - \begin{itemize}[nosep] - \item rounding and truncating \func{round}, \func{trunc} to a given fixed - point precision or with \func{float} to a given floating point precision, - \item the square-root \func{sqrt} achieves correct rounding in arbitrary - precision, - \item \func{binomial}, \func{factorial}, \func{pfactorial}, - \item \func{gcd} and \func{lcm} both work with general fractions as input, - \item randomness related functions such as \func{random} and - \func{randrange} for random floats or integers; they require that \TeX\ - engine provides \csa{pdfuniformdeviate} or \csa{uniformdeviate} primitive, - \item trigonometrical functions \xinttrigname, - \item logarithm and exponential functions \xintlogname. - \item pseudo-functions whose syntax involves usage of dummy variables: - \xintFor #1 in {subs, subsm, subsn, rseq, seq, add, mul, iter, rrseq, iterr, - ndseq, ndmap}\do - {\func{#1}\xintifForLast{.}{, }} - \end{itemize} -\item built-in and user-defined \hyperref[ssec:uservariables]{variables} and \hyperref[ssec:userfunctions]{functions}. -\end{itemize} - - -The normal mode of operation of the parsers is to unveil the parsed material -token by token. Unveiling is a process combining brace removal (one level -generally) and \fexpan sion (think of it as a kind of adaptative |\edef|). -Thus all tokens may arise from expansion of macros or active characters. For -example a closing parenthesis does not have generally to be immediately -visible, it may arise later from expansion. Even the ending |\relax| may -arise from expansion. Even though the \csbxint{eval} user interface means that -the package has at some point the entire expression in its hands, it -immediately re-inserts it into token stream with an additional postfixed -|\relax| and from this point on has lost any ways to manipulate formally again -the whole thing; it can only re-discover it piece per piece. - -This general behaviour has significative exceptions mostly related to -«pseudo»-functions. A «pseudo»-function will grab some of its arguments via -delimited macros. For example |subs(expr1,x=expr2)| needs to see the comma, -equal sign and closing parenthesis. But it has mechanisms to allow |expr1| and -|expr2| to possess their own commas and parentheses. - -Inner semi-colons on the currently always can originate from expansion. -Defining functions or variables requires a visible semi-colon acting as -delimiter of the expression, but inner semi-colons do not need to be -hidden within braces or macros\NewWith{1.4}. The semi-colon catcode will be -set at the start of the process but of course this is too late if the whole -thing has already been grabbed in a macro. - -The expansion stops only when the ending |\relax| has been found; -it is then removed from the token stream, and the final computation result is -inserted. - -Some examples with dummy variables: -\begin{everbatim*} -\xintiiexpr add(i^5, i=100..200)\relax\par -\noindent\xintexpr add(x/(x+1), x = 1000..1014)\relax\par -\noindent\xintexpr reduce(add(x/(x+1), x = 1000..1014))\relax -\end{everbatim*} -\newline In this example, the fraction obtained by addition was thus already -irreducible, but this is not always the case: -\begin{framed} - By default, basic operations on fractions do not automatically reduce to - smallest terms the output: |A/B| multiplied by |C/D| - returns |AC/BD|, and |A/B| added to |C/D| uses |lcm(B, D)| as denominator. -\end{framed} - \subsection{Printing big numbers on the page}\label{ssec:printnumber} When producing very long numbers there is the question of printing them on the page, without going beyond the page limits. In this document, I have most @@ -3931,11 +3928,22 @@ It may be used like this: % \begin{everbatim*} \printnumber{\xintiieval{100!^3}}\newline -\end{everbatim*} +\end{everbatim*}% The rendering here uses extra decoration. +\clearpage +\expandafter\let\csname Start herenameUp\endcsname\undefined +\csname xintexprnameUp\endcsname +\section{\xintexprname syntax reference and user guide} +\RaisedLabel{sec:expr} + +\localtableofcontents + \subsection{Oples and nut-ples: terminology for a new \xintname generation} +\emph{Skip this on first reading, else you will never start using the + package.} \fbox{SKIP THIS!} (understood?) + In this section I will describe a mathematical terminology appropriate to understand the core functioning of the package in so far as it regards its numerical mode of operation. The description requires some adaptations to @@ -4098,7 +4106,7 @@ For example when applied to the \emph{not-ple} we always obtain the |nil|. Whereas as we saw slicing the \emph{not-ple} always gives back the \emph{not-ple}. Indexing is denoted in the syntax by postfixing by |[N]|. Thus for \emph{nut-ples} (which are analogous to Python objects), there is genuine -diffence between the |[N]| extractor and the |[N:N+1]| slicer. But for +difference between the |[N]| extractor and the |[N:N+1]| slicer. But for \emph{oples} which are either |nil|, a \emph{number}, or of length at least 2, there is no difference. @@ -4169,7 +4177,7 @@ $\{\{A_{00}A_{01}\}\{A_{10}A_{11}\}\}$ with atoms $A_{00}=\{1\}$, ..., being the \emph{leaves} of the tree associated to (or which is) the \emph{ople}. Numbers may be called the \emph{leaves} of the \textbf{input}, but once -converted to a structure in memory, the input becomes an \emph{ople} which is +parsed, the input becomes an \emph{ople} which is (morally) a tree whose leaves are \emph{atoms} (and the empty set). \medskip @@ -4178,15 +4186,6 @@ absolutely not needed to understand the rest of the manual, but I needed to write it for my own satisfaction. Believe me, you need this section if you want to write the underlying software! -\clearpage -\let\xintexprnameUp\undefined -\csname Syntax referencenameUp\endcsname -\section{\xintexprname syntax reference and user guide} -\RaisedLabel{sec:xintexprsyntax} - -\localtableofcontents - - \subsection{The three parsers} \xintexprname provides three numerical expression parsers and two subsidiary @@ -4205,28 +4204,63 @@ any pre-parsing. \item \csbxint{eval}\marg{expression} handles integers, decimal numbers, numbers in scientific notation and fractions. The algebraic computations are done \emph{exactly.} +\begin{everbatim*} +\xinteval{add(x/(x+1), x = 1000..1014)}\par +\end{everbatim*} +In this example, the fraction obtained by addition is already +irreducible, but this is not always the case: +\begin{snugframed} + By default, basic operations on fractions do not automatically reduce to + smallest terms the output: |A/B| multiplied by |C/D| + returns |AC/BD|, and |A/B| added to |C/D| uses |lcm(B, D)| as denominator. +\end{snugframed} + \item \csbxint{iieval}\marg{expression} does exact computations \emph{on (big) integers only.} The forward slash \dtt{/} does the \emph{rounded} integer division to match behaviour of |\numexpr|. +\begin{everbatim*} +\xintiieval{add((i/:7)?{omit}{i^5}, i=1000..1020)}% only add fifth powers of multiples of 7 +\end{everbatim*} + \item \csbxint{floateval}\marg{expression} does floating point computations with a given precision \dtt{P}, as specified via a prior assignment - |\xintDigits:=P\relax |. The default is \dtt{P=16} digits. The four basic + |\xintDigits:=P\relax |. +\begin{everbatim*} +\begingroup +\xintDigits:=64; +\xintfloateval{sqrt(3)} +\endgroup +\end{everbatim*} + + The default is with \dtt{P=16} digits. The four basic operations and the square root realize \emph{correct rounding.}\footnote{when the inputs are already floating point numbers with at most |P|-digits mantissas.} - It can be used with an optional argument |[Q]| and then do a float rounding - to mantissas of |Q| digits as the final step (this makes sense only if - |Q0|: the nearest fixed point number with |D| digits after the + decimal mark, + \item if |D=0|: the nearest integer, + \item if |D<0|: the nearest multiple of |10^(-D)| (i.e. \emph{quantization}, + this case is new with |1.4a|).\NewWith{1.4a} + \end{itemize} + ATTENTION: the optional argument |[D]| is to be located \emph{within} the braces at the start of the expression. \item \csbxint{theboolexpr}\meta{expression}|\relax| does all computations like \csbxint{eval} but converts the (itemwise) results to |True| or |False|. This @@ -4241,14 +4275,14 @@ These macros are wrappers for a more core syntax: \item \csbxint{iexpr}\meta{expression}|\relax|, \item \csbxint{boolexpr}\meta{expression}|\relax|. \end{itemize} -This core syntax can be used directly in typesetting flow. But in an |\edef| they -expand to some braced nested data prefixed with some non-expandable -«typesetting» macros. When using \csbxint{eval} in an |\edef|, the -\csa{XINTexprprint} typesetter is activated and the expansion gives explicit -digits and other characters such as those of scientific notation or -brackets. - -It is possible to use the core syntax +This core syntax can be used directly in typesetting flow.\NewWith{1.4} But in an |\edef| +they expand to some braced nested data prefixed with some |\protected| +«typesetter» macros. When using \csbxint{eval} (in contrast to +\csbxint{expr}), the protection of the «typesetter» is removed and the expansion +gives explicit digits and other characters such as those of scientific +notation or brackets. + +It is possible to use the core syntax\NewWith{1.4} \csbxint{expr}\marg{expression}|\relax| also in so-called moving arguments, because when written out to a file they use only standard catcodes and the output will get retokenized and will expand as expected. @@ -4261,28 +4295,56 @@ As alternative to \csbxint{eval}\marg{expression}, an equivalent is can prefix all other core parsers. And one can also use \csbxint{theexpr} as shortcut for \csbxint{the}\csbxint{expr}. -Notice that in this documentation I will most of the time refer to -\csbxint{eval} and \csbxint{expr}. But beware that doing exact computations -with fractions leads very quickly to very big results (and furthermore one -needs to use explicitly the |reduce()| function to convert the fractions into -smallest terms). Thus most probably what you want is \csbxint{floateval} and +Throughout this documentation I will most of the time refer to \csbxint{eval} +and \csbxint{expr}. But beware that doing exact computations with fractions +leads very quickly to very big results (and furthermore one needs to use +explicitly the |reduce()| function to convert the fractions into smallest +terms). Thus most probably what you want is \csbxint{floateval} and \csbxint{floatexpr}. +\subsection{Expansion} + +As mentioned already, the parsers are compatible with expansion-only +context. + +Also, they expand the expression piece by piece: +the normal mode of operation of the parsers is to unveil the parsed material +token by token. Unveiling is a process combining brace removal (one level +generally) and \fexpan sion. + +For example a closing parenthesis does not have generally to be immediately +visible, it may arise later from expansion. Even the ending |\relax| may +arise from expansion. Even though the \csbxint{eval} user interface means that +the package has at some point the entire expression in its hands, it +immediately re-inserts it into token stream with an additional postfixed +|\relax| and from this point on has lost any ways to manipulate formally again +the whole thing; it can only re-discover it piece per piece. + +This general behaviour has significative exceptions mostly related to +«pseudo»-functions. A «pseudo»-function will grab some of its arguments via +delimited macros. For example |subs(expr1,x=expr2)| needs to see the comma, +equal sign and closing parenthesis. But it has mechanisms to allow |expr1| and +|expr2| to possess their own commas and parentheses. + +Inner semi-colons on the other hand currently always can originate from expansion. +Defining functions or variables requires a visible semi-colon acting as +delimiter of the expression, but inner semi-colons do not need to be +hidden within braces or macros\NewWith{1.4}. + +The expansion stops only when the ending |\relax| has been found +(it is then removed from the token stream). + +For catcode related matters see \csbxint{exprSafeCatcodes}. + A word of warning on the bracketed optional argument of respectively -\csbxint{floatexpr} and \csbxint{iexpr}. If defining macros handing over an -argument to one of these two parsers, the argument may accidentally start with -a left square bracket |[| and this will break the parser. The fix is to use in -the macro definition |\xintfloatexpr\empty| for example. The extra |\empty| -token will prevent the parser thinking there is an optional argument and it -will then disappear during expansion. +\csbxint{floatexpr} and \csbxint{iexpr}. When defining macros which will hand +over some argument to one of these two parsers, the argument may potentially +start with a left square bracket |[| (e.g. argument could be |[1, 2, 3]|) and +this will break the parser. The fix is to use in the macro definition +|\xintfloatexpr\empty|. This extra |\empty| token will prevent the parser +thinking there is an optional argument and it will then disappear during +expansion. -With \csbxint{thealign} one can get nested data use a \TeX{} alignment in the -output. Attention, this must be followed by \csbxint{expr} et al., never by -\csbxint{theexpr} or \csbxint{eval}. -Here is an example : -\begin{everbatim*} -\xintthealign\xintexpr ndseq(1/(i+j), i = 1..10; j=1..10)\relax -\end{everbatim*} \subsection{\csh{xintthealign} and output related customizations} \label{xintthealign} @@ -4292,46 +4354,96 @@ Here is an example : \label{xintfloatexprPrintOne} \label{xintboolexprPrintOne} +With \csbxint{thealign} one can get nested data use a \TeX{} alignment in the +output. Attention, this must be followed by \csbxint{expr} et al., never by +\csbxint{theexpr} or \csbxint{eval}. +Here is an example : +\begin{everbatim*} +\xintthealign\xintexpr ndseq(1/(i+j), i = 1..10; j=1..10)\relax +\end{everbatim*} -This is hopefully more or less self-explanatory: +It is possible to customize the behaviour of |\xintthealign|.\CHANGED{1.4a} +The helper macros, apart from |\xintexpralignbegin| and |\xintexpralignend| +will be subjected to a complete (|\expanded|) expansion (once). The package +uses here |\protected| with no strong reason, as the replacement tokens are +not expanding anyhow, but the idea is that this allows to define a macro in an +|\edef| and later change the meaning of the auxiliary macros depending on what +one wants to do with the expansion result. See also further down the \LaTeX{} +example with a matrix environment, where |\noexpand| rather than |\protected| +is used. \begin{everbatim} -\def\xintexprEmptyItem{[]} -% this is a macro from xintfrac.sty, must understand its raw format -\let\xintexprPrintOne\xintFracToSci -\def\xintiiexprPrintOne #1{#1} -% this is a macro from xintfrac.sty, must understand its raw format -\def\xintfloatexprPrintOne#1#2{\xintPFloat[#1]{#2}} -\def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{True}{False}} -% The package uses \protected here for no strong reason, but why not \protected\def\xintexpralignbegin {\halign\bgroup\tabskip2ex\hfil##&&##\hfil\cr}% \protected\def\xintexpralignend {\crcr\egroup}% -\protected\def\xintexpraligncr {\cr}% +\protected\def\xintexpralignlinesep {,\cr}% separates "lines" +\protected\def\xintexpralignleftsep {&}% at left of first item in a "line" (after brackets) +\protected\def\xintexpraligninnersep {,&}% at the left of non-first items +\protected\def\xintexpralignrightsep {&}% at right of last item in a "line" (before brackets) \protected\def\xintexpralignleftbracket {[}% \protected\def\xintexpralignrightbracket{]}% -\protected\def\xintexpraligninnercomma {,}% -\protected\def\xintexpralignoutercomma {,}% -\protected\def\xintexpraligntab {&}% -% Use for example this for outputting to a file. Better then without \protected. +\end{everbatim} +Although we will try to keep stable the way «regular arrays» are +rendered,\UNSTABLE{} the |\xintthealign| macro (and its associated customizability) is +considered work-in-progress and may experience breaking changes. + +Use for example this for outputting to a file or a terminal: +\begin{everbatim} +% Better here without \protected. % We assume here \newlinechar has the LaTeX setting. \def\xintexpralignbegin {}% \def\xintexpralignend {}% -\def\xintexpraligncr {^^J}% +\def\xintexpralignlinesep {,^^J}% separates "lines" +\def\xintexpralignleftsep { }% at left of first item in a "line" (after brackets) +\def\xintexpraligninnersep {, }% at the left of non-first items +\def\xintexpralignrightsep { }% at right of last item in a "line" (before brackets) \def\xintexpralignleftbracket {[}% \def\xintexpralignrightbracket{]}% -\def\xintexpraligninnercomma {,}% -\def\xintexpralignoutercomma {,}% -\def\xintexpraligntab { }% \end{everbatim} +And here is an example using a |pmatrix| environment. +\begin{everbatim*} +\[ +\def\xintexpralignbegin {\begin{pmatrix}}% +\def\xintexpralignend {\end{pmatrix}}% +\def\xintexpralignlinesep {\noexpand\\}% needed to counteract an internal \expanded +\def\xintexpraligninnersep {&}% +\let\xintexpralignleftbracket\empty \let\xintexpralignleftsep\empty +\let\xintexpralignrightbracket\empty \let\xintexpralignrightsep\empty +% by default amsmath matrices can have 10 columns at most +% (cf amsmath documentation for what to do to allow more) +l.c.m.=\xintthealign\xintiiexpr ndmap(lcm, 1..12; 1..10)\relax +\] +\end{everbatim*} + +The way individual items are formatted (whether or not using +|\xintthealign|) is also customizable: +\begin{everbatim} +\def\xintexprEmptyItem{[]} +% The used macro (here \xintFracToSci) must understand the xintfrac.sty raw format +\let\xintexprPrintOne\xintFracToSci +\def\xintFracToSciE{e} +% In the integer-only parser, internal format coincides simply with the digit tokens +% Attention this may change in future +\def\xintiiexprPrintOne #1{#1} +% The used macro (here \xintPFloat) must understand the xintfrac.sty raw format +\def\xintfloatexprPrintOne#1#2{\xintPFloat[#1]{#2}} +% Same here +\def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{True}{False}} +\end{everbatim} +Attention! The above macros convert from \xintexprname internal numeric data +format to «printed» output; they are thus susceptible to require adjustments +if the internal data format changes, which may happen at each release. Of course +the default for |\xintexprPrintOne| etc... will be adjusted accordingly, but +user custom definitions may break. + \subsection{Built-in operators and their precedences} -\def\MicroFont{\ttbfamily\makestarlowast\color[named]{DarkOrchid}} \makeatletter \def\@floatboxreset{\@setminipage}% faudra contrôler celui-là \makeatother \begin{table}[htbp] +\edef\Ampersand{\string&}% \edef\restorehtdpstrutbox {\ht\strutbox\the\ht\strutbox\dp\strutbox\the\dp\strutbox} \ht\strutbox12pt\dp\strutbox5pt @@ -4339,54 +4451,73 @@ This is hopefully more or less self-explanatory: \centering\begin{tabular}{|c|p{.5\textwidth}|} \hline \multicolumn{2}{|p{.6\textwidth}|}{\prec{$\infty$}: - at this top level the non-operator syntax elements whose parsing - is always done prior to executing operators preceding them: + at this top level the syntax elements whose + execution + is done prior to operators preceding them: \begin{itemize}[nosep] \item \hyperref[ssec:builtinfunctions]{built-in} or \hyperref[ssec:userfunctions]{user-defined} functions, \item \hyperref[ssec:uservariables]{variables}, - \item the |*| unpacking operator, - \item and the intrinsic constituents of numbers: decimal mark |.|, |e| and |E| of scientific notation, hexadecimal prefix |"|. + \item the \oper{\empty*} unpacking operator, + \item and intrinsic constituents of numbers: decimal mark \oper{\strut.}, + \oper{e} and \oper{E} of scientific notation, hexadecimal prefix + \oper{"}. \end{itemize}\par\kern-\baselineskip\relax}% \\\hline\hline - Precedence&``Operators'' at this level\strut\\ - \hline - \prec{$20$}& the factorial (postfix) operator |!| and the conditional branching operators |?| and |??|\strut\\\hline - \prec{$=$}& the minus sign |-| as unary operator acquires the - precedence level of the previous infix operator\strut\\\hline - \prec{$18$}&the power |^|, |**| operators\strut\\\hline - \prec{$16$}&the action of tacit multiplication\strut\\\hline - \prec{$14$}&the multiplication, division, and modulo operators |*|, |/|, - |//|, |/:| (aka |'mod'|)\strut - \\\hline - \prec{$12$}&the addition and subtraction |+|, |-|\strut\\\hline - \prec{$10$}&the comparison operators |<|, |>|, |==|, |<=|, |>=|, |!=|\strut\\\hline - \prec{$8$}&Boolean conjunction |&&| and its alias |'and'|\strut\\\hline - \prec{$6$}&Boolean disjunction \verb+||+ and |'or'|, and |'xor'|; also the - sequence generators |..|, |..[|, |]..|, and the Python slicer |:| have - this precedence\strut\\\hline - \prec{$4$}& the brackets for |NumPy| slicing syntax |[|, |]|\strut\\\hline - \prec{$3$}& the comma |,|\strut\\\hline - \prec{$2$}& the bracketers |[|, |]|\strut\\\hline - \prec{$1$}& the parentheses |(|, |)|, and the semi-colon |;| in the - \func{iter}, - \func{rseq}, etc... constructs\strut\\\hline\hline + Precedence&``Operators'' at this level\strut\\ + \hline + \prec{20}& postfix \oper{!} and branching \oper{?}, \oper{??} operators\strut\\\hline +% + \prec{-}& minus sign as unary operator\strut\\\hline +% + \prec{18}& \oper{\string^} and \oper{**} are a priori synonymous (but see + \xintlogname)\strut\\\hline +% + \prec{16}& \hyperref[ssec:tacit multiplication]{Tacit + multiplication} has an elevated precedence\strut\\\hline +% + \prec{14}& \oper{*}, \oper{/}, \oper{//} (floored division), + and \oper{/:} (associated modulo, alias + \oper{'mod'})\strut\\\hline +% + \prec{12}& \oper{+}, \oper{-}\strut\\\hline +% + \prec{10}& \oper{<}, \oper{>}, \oper{==}, \oper{<=}, \oper{>=}, + \oper{!=}\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 Actually operators have a left and a right precedence, which for most coincide. But for some there is a crucial distinction. The above - table is indicative, see |sourcexint.pdf|. Roughly all precedence levels - were doubled at |1.4| to make room. + table is indicative, and the actual numerical levels used internally may change. \item In case of equal precedence, the rule is left-associativity: the first encountered operation is executed first. \hyperref[ssec:tacit multiplication]{Tacit multiplication} has an elevated precedence level hence seemingly breaks left-associativity: |(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. - % \item List variants |^[|, |**[|, |]^|, |]**|, - % |*[|, |/[|, |]*|, |]/|, |+[|, |-[|, |]+|, |]-|, share the precedence - % level of their respective associated operators on numbers. \end{itemize} }\\\hline \end{tabular} @@ -4396,199 +4527,283 @@ when using variables. \restorehtdpstrutbox \end{table} -The \autoref{tab:precedences} is hyperlinked to the more detailed discussion -at each level. - -\begin{description}[parsep=0pt,align=left,itemindent=0pt, - leftmargin=\leftmarginii, labelwidth=\leftmarginii, labelsep=0pt, - labelindent=0pt, listparindent=\leftmarginiii] - -\precdesc{\infty} At this highest level of precedence, one finds: -\begin{itemize}[parsep=0pt,align=left,itemindent=0pt, - leftmargin=\leftmarginii, labelwidth=\leftmarginii, labelsep=0pt, - labelindent=0pt, listparindent=\leftmarginiii] -\item \hyperref[ssec:builtinfunctions]{functions} and - \hyperref[ssec:uservariables]{variables}: - we approximately describe the situation as - saying they have highest precedence. Functions (even the logic functions +The entries of \autoref{tab:precedences} are hyperlinked to the more detailed +discussion at each level. + +\begin{description} +% [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 consists 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.) -\item The |*| as 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, -\item the |.| as decimal mark; the number scanner treats it as - an inherent, optional and unique component of a being formed number. One can - do things such as - % - \leftedline{\restoreMicroFont|\xintexpr 0.^2+2^.0\relax|} - % - which is |0^2+2^0| and produces \dtt{\xintexpr 0.^2+2^.0\relax}. - - Since release |1.2| an isolated decimal mark |"."| is illegal - input in |\xintexpr..\relax|, although it remains legal as argument to the - macros of \xintfracname. -\item the |e| and |E|, for scientific notation are intrinsic constituents of - number denotations, - like the decimal mark. -\item the |"| for hexadecimal numbers: it is allowed only at locations where - the parser expects to start forming a numeric operand, once encountered it - triggers the hexadecimal scanner which looks for successive hexadecimal - digits as usual skipping spaces and expanding forward everything; letters - (only |ABCDEF|, not |abcdef|), an optional dot - (allowed directly in front) and an optional (possibly empty) fractional - part. The |"| functionality - \fbox{requires to load package \xintbinhexname}.% -% -\begin{everbatim*} -\xinttheexpr "FEDCBA9876543210\relax\newline -\xinttheiexpr 16^5-("F75DE.0A8B9+"8A21.F5746+16^-5)\relax + + \operdesc{\empty*} 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{FracToSciE}. + + \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*} -\end{itemize} -\precdesc{20} The postfix operators |!| and the branching conditionals |?|, |??|. - \begin{description}[parsep=0pt,align=left,itemindent=0pt, - leftmargin=\leftmarginii, labelwidth=\leftmarginii, labelsep=0pt, - labelindent=0pt, listparindent=\leftmarginiii] - - \item[{\color[named]{DarkOrchid}!}] computes the factorial of an integer. - Attention that the boolean equality test |==| must not follow directly - such a |!| because the parser will handle |!=| as the - boolean inequality test... the remaining |=| then causes a parsing error. - It is even worse if one uses a single |=| following the |!| because no - error arises but an un-intended interpretation. Use parentheses: + 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. + Attention that the boolean equality test |==| confuses + the parser if following directly |!| (e.g. |3! == 10|) + as spaces are ignored and \oper{!=} will be intepreted as + boolean inequality test, the second |=| causing then a low-level error. + Use parentheses in such cases: |(3!)==10|. - \item[{\color[named]{DarkOrchid}?}] is used as |(stuff)?{yes}{no}|. It + \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.} - - - \item[{\color[named]{DarkOrchid}??}] is used as |(stuff)??{<0}{=0}{>0}|, + 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 }} - % + 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{=} The minus sign |-| as prefix unary operator inherits the - precedence of the infix operator it follows. |\xintexpr -3-4*-5^-7\relax| - evaluates as |(-3)-(4*(-(5^(-7))))| and |-3^-4*-5-7| as - |(-((3^(-4))*(-5)))-7|. +\precdesc{-} As prefix unary operator it inherits the precedence of + the infix operator it follows. +\begin{everbatim*} +\xintexpr -3-4*-5^-7, (-3)-(4*(-(5^(-7))))\relax\newline +\xintexpr -3^-4*-5-7, (-((3^(-4))*(-5)))-7\relax\par +\end{everbatim*} + |2^-10| is perfectly accepted input, no need for parentheses. - |2^-10| is perfectly accepted input, no need for parentheses +\precdesc{18} +\begin{description} +\operdesc{\string^} +\operdesc{**} Both compute powers in left associative way. +\begin{everbatim*} +\xintiiexpr 2^2^3\relax +\end{everbatim*} + + Half-integer exponents are allowed in \csbxint{floateval} and use + \func{sqrt}. It is possible to allow arbitrary fractional exponents + (\autoref{ssec:poormanloghack}) but this currently achieves only a + reduced precision. See \csbxint{FloatPower} and \xintlogname for + additional information. +\end{description} +\precdesc{16} see \hyperref[ssec:tacit multiplication]{Tacit multiplication}. +\precdesc{14} +\begin{description} +\operdesc{*} multiplication +\operdesc{/} division: exact in \csbxint{eval}, correctly rounded in + \csbxint{floateval} (numerator and denominator are rounded before the + division is done), and rounded to an integer (like |\numexpr| does: + half-integers are rounded towards infinity of same sign) in + \csbxint{iieval}. The division is left-associative: +\begin{everbatim*} +\xintexpr reduce(100/50/2)\relax +\end{everbatim*} - \precdesc{18} The power operator |^|, or equivalently |**|. It is left - associative: {\restoreMicroFont|\xinttheiexpr 2^2^3\relax|} evaluates to - \xinttheiexpr 2^2^3\relax, not \xinttheiexpr 2^(2^3)\relax. See - \csbxint{FloatPower} for additional information. +\operdesc{//} floored division -\precdesc{16} see \hyperref[ssec:tacit multiplication]{Tacit multiplication}. +\operdesc{/:} the associated modulo -\precdesc{14} Multiplication and division |*|, |/|. The - division is left associative, too: - % - \begingroup\restoreMicroFont - % - |\xinttheiexpr 100/50/2\relax| evaluates to \xinttheiexpr 100/50/2\relax, - not \xinttheiexpr 100/(50/2)\relax. - % - \endgroup + Left-associativity applies generally to operators of same precedence. +\begin{everbatim*} +\xintexpr 100000/:13, 100000 'mod' 13\relax\newline +\xintexpr 100000/:13/13\relax +\end{everbatim*} - Also the floored division |//| and its associated modulo |/:| (equivalently |'mod'|, - quotes mandatory). +\operdesc{'mod'} is same as \oper{/:} - Also at this level the list operators |*[|, |/[|, |]*| and |]/|. +\end{description} - In an \csbxint{iiexpr}-ession, |/| does \emph{rounded} division, to behave - like the |/| of |\numexpr|. +\precdesc{12} +\begin{description} +\operdesc{+} addition - Infix operators all at the same level of precedence are - left-associative.\footnote{i.e. the first two operands are operated upon - first.} - Apply parentheses for disambiguation. +\operdesc{-} subtraction. According to the general left-associativity rule in +case of equal precedence, it is + left associative: \begin{everbatim*} -\xinttheexpr 100000//13, 100000/:13, 100000 'mod' 13, trunc(100000/13,10), - trunc(100000/:13/13,10)\relax +\xintiiexpr 100-50-2\relax \end{everbatim*} +\end{description} -\precdesc{12} Addition and subtraction |+|, |-|. According to the rule above, |-| - is left associative: - % - \begingroup\restoreMicroFont - % - |\xinttheiexpr 100-50-2\relax| evaluates to \xinttheiexpr 100-50-2\relax, - not \xinttheiexpr 100-(50-2)\relax. - % - \endgroup +\precdesc{10} Comparison operators are currently 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. -\precdesc{10} Comparison operators |<|, |>|, |==|, |<=|, |>=|, |!=| all - at the same level of precedence, use parentheses for disambiguation. + \operdesc{==} |a==b| evaluates to \dtt{1} if equality holds to \dtt{0} + if not. -\precdesc{8} Conjunction (logical and) |&&| or equivalently - |'and'| (quotes mandatory).% -% -\footnote{with releases earlier than |1.1|, only single - character operators |&| and \verb+|+ were available, because the parser - did not handle multi-character operators. Their usage in this rôle is now - deprecated,\IMPORTANT{} and they may be assigned some new meaning in the - future.} + \operdesc{<=} |a<=b| evaluates to \dtt{1} if left hand side is at most equal + to right hand side, to \dtt{0} + if not. -\precdesc{6} Inclusive disjunction (logical or) \verb+||+ - and equivalently |'or'| (quotes mandatory). + \operdesc{>=} |a>=b| evaluates to \dtt{1} if left hand side is at least equal + to right hand side, to \dtt{0} + if not. - Also the |'xor'| operator (quotes mandatory) is at this level. + \operdesc{!=} |a!=b| evaluates to \dtt{1} if they differ, to \dtt{0} + if not. + \end{description} - Also the list generation operators |..|, |..[|, |]..| are at this level. +\precdesc{8} +\begin{description} + \operdesc{\Ampersand\Ampersand} logical conjunction. Evaluates to \dtt{1} if + both sides are non-zero, to \dtt{0} if not. - Also the |:| for Python/NumPy nested slicing of nested lists. + \operdesc{'and'} idem. The (right) ticks are mandatory. See also the + \func{all} multi-arguments function. +\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. -\precdesc{4} The square brackets as involved in NumPy like slicing. The step -is not implemented yet. -\precdesc{3} The comma: {\restoreMicroFont with |\xinttheexpr 2^3,3^4,5^6\relax| - one obtains as output \xinttheexpr 2^3,3^4,5^6\relax{}.}\footnote{The comma + \operdesc{'or'} idem. See also the \func{any} multi-arguments function. + + \operdesc{'xor'} logical (exclusive) disjunction. See also the \func{xor} + multi-arguments function. + + \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.} -\precdesc{2} The square brackets as |nut-ple| constructors. -\precdesc{1} The parentheses. The semi-colon |;| in an |iter| or - |rseq| has the same precedence as a closing parenthesis.\footnote{It is not - apt to describle the opening parenthesis as an operator, but the closing - parenthesis is more closely like a postfix unary operator. It has lowest - precedence because when it is encountered all postponed operations are - executed to finalize its operand. The start of this operand was decided by - the opening parenthesis.} +% +\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. It also serves as syntax terminator for + \csbxint{defvar} and \csbxint{deffunc}. Inner semi-colons do not need to be + braced to avoid being mistaken for the terminator (but they may be which + speeds up by micro-second the parsing). +\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 use + \csbxint{eval} et al. which proceed as macros expecting one mandatory + argument. +\end{description} -\restoreMicroFont \subsection{Built-in functions}\label{ssec:builtinfunctions} @@ -4907,8 +5122,8 @@ $\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax definitions done via \csbxint{deffunc} (see explanations there) to functions usable in \csbxint{floateval}. - \funcdesc{nuple} (WIP) is currently same as |[...]|. Do not use. Reserved - for possible alternative meaning in future.\NewWith{1.4} + \funcdesc{nuple} is currently same as |[...]|.\DNU{(1.4)} Reserved for + possible alternative meaning in future. \begin{everbatim*} \xinteval{nuple(1,2,3)} \end{everbatim*} @@ -5007,28 +5222,34 @@ $\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax % labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt, % listparindent=\leftmarginiii] - \funcdesc[{x[, n]}]{round} Rounds its first argument to a fixed point number, having a - number of digits - after decimal mark given by the second argument. For example - |round(-2^9/3^5,12)=|\dtt{\xinttheexpr round(-2^9/3^5,12)\relax.} - \funcdesc[{x[, n]}]{trunc} Truncates its first argument to a fixed point number, having - a number of digits - after decimal mark given by the second argument. For example - |trunc(-2^9/3^5,12)=|\dtt{\xinttheexpr trunc(-2^9/3^5,12)\relax.} + \funcdesc[{x[, n]}]{round} Rounds its first argument to an integer multiple + of |10^(-n)| (i.e. it \emph{quantizes}). The case of negative |n| is new with + |1.4a|. Positive |n| corresponds to conversion to a fixed point number with + |n| digits after decimal mark. +\begin{everbatim*} +\xinteval{round(-2^30/3^5,12), round(-2^30/3^5,-3)} +\end{everbatim*} + \funcdesc[{x[, n]}]{trunc} Truncates its first argument to an integer + multiple of |10^(-n)|. The case of negative |n| is new with + |1.4a|. +\begin{everbatim*} +\xinteval{trunc(-2^30/3^5,12), trunc(-2^30/3^5,-3)} +\end{everbatim*} + \funcdesc[{x[, n]}]{float} Rounds its first argument to a floating point number, with a - precision given by the second argument. - |float(-2^9/3^5,12)=|\dtt{\xinttheexpr float(-2^9/3^5,12)\relax.} + precision given by the second argument, which must be positive. +\begin{everbatim*} +\xinteval{float(-2^30/3^5,12), float(-2^30/3^5, 1)} +\end{everbatim*} % AUCTeX EXTREMEMENT PENIBLE AVEC L'INDENTATION FORCEE SOUS M-q - Note for this example and the earlier ones that when the surrounding - parser is \csbxint{floatexpr}|...\relax| the fraction first argument (here - |2^9/3^5|) will already have been computed as floating point number (with - numerator and denominator handled separately first), even before the - second argument is seen and a fortiori before the |round|, |trunc| or - |float| is executed. The general float precision is the one governing - these initial steps. To avoid that, use |\xintexpr2^9/3^5\relax| wrapper. - Then the rounding or truncation will be applied on the exact fraction. + For this example and earlier ones if the parser had been + \csbxint{floateval}, not \csbxint{eval}, the first argument (here + |2^30/3^5|) would already have been computed as floating point number with + numerator and denominator rounded separately first to the prevailing + precision. To avoid that, use |\xintexpr2^9/3^5\relax| wrapper. + Then the rounding or truncation will be applied to the exact fraction. \funcdesc[{x[, n]}]{sfloat} It is the same as \func{float}, but in case of a short (non-fractional) input it gets stored internally @@ -5242,14 +5463,26 @@ The arguments must be (expand to) short integers. The arguments must (expand to) short integers. See \autoref{xintiiPFactorial} for the behaviour if the arguments are negative. -\funcdesc[macro, n-uple]{ndfillraw} (WIP) DO NOT USE.\NewWith{1.4} The second argument is -|[N1, N2, ..., Nk]|. The construct fills an |N1xN2x...xNk| hyperrectangular -nested list by evaluating the |macro| as many times as needed. Useful to generate either -constant or random -arrays. But, attention, |macro| is any \TeX{} macro, if one wants to evaluate -some expression one needs explicitly adding |\xinteval{..}|. Beware spaces or -other things this goes directly into internal data storage. - \end{description} +\funcdesc[\TeX-macro, n-uple]{ndfillraw} The second argument is |[N1, N2, ..., +Nk]|.\NewWith{1.4} The construct fills an |N1xN2x...xNk| hyperrectangular +nested list by evaluating the given |macro| as many times as needed. The +expansion result goes directly into internal data and must thus comply with +what is expected internally for an individual numeric leaf (at |1.4|, +\xintfracname raw format worked for |\xintexpr| or |\xintfloatexpr|, but not +|\xintiiexpr|, and this may have changed since).\DNU{} This is an experimental +function serving to generate either constant or random arrays. Attention that +% +% BORDEL \textbf{\sffamily...} NON, {\bfseries\sffamily ...} NON +% LaTeX Font Warning: Font shape `T1/cmss/b/n' undefined +% (Font) using `T1/cmss/m/n' instead on input line 1826. +% +% ceci est ok {\fontseries{bx}\sffamily\TeX-macro} +% https://github.com/latex3/latex2e/issues/277 +{\fontseries{bx}\sffamily \TeX-macro} +stands here for any expandable \TeX{} +\emph{macro}, and an |\xintexpr|-ession at this location thus requires an +explicit |\xinteval| wrapping. +\end{description} \subsubsection{Functions with 3 or 4 arguments} @@ -5307,9 +5540,9 @@ depending on internal data representation). % labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt, % listparindent=\leftmarginiii] - \funcdesc[stuff]{qraw} DO NOT USE. It allows to inject directly a nested \TeX-braced - list conforming to internal data structures manipulated by the package. Can - break at any release. + \funcdesc[stuff]{qraw} It\DNU{} injects directly tokens to represent + internally numerical data. Will break at any release modifying the internal + data format specifications (which are not always documented). \funcdesc[x, y, ...]{all} inserts a logical |AND| in-between its arguments and evaluates the resulting logical assertion (as with all functions, all arguments are @@ -5407,31 +5640,34 @@ the case here. \subsubsection{Functions requiring dummy variables} \hypertarget{ssec:dummies}{} -The pseudo-functions \xintFor #1 in {add, mul, seq, subs, subsm, subsn, ndmap, ndseq, rseq, iter, rrseq, - iterr} \do {\func{#1}\xintifForLast{}{, }} use delimited macros to -identify the ``|,=|'' part. This is done in a way -allowing nesting via correctly balanced parentheses. The || must not -have been assigned a value before via \csbxint{defvar}. - -This |,=| must be visible when the parser has finished absorbing the -function name and the opening parenthesis. For \func{rseq}, \func{iter}, -\func{rrseq} and \func{iterr} this is delayed to after the parser has -assimilated a starting part delimited by a semi-colon; this mandatory segment -may be generated entirely by expansion and the |,=| may appear during -this expansion. - -After |,=|, the expansion and parsing will generate a list of values -(for example from an |a..b| specification, there may be multiple ones -themselves separated by commas). After this step is complete the parser will -know the values which will be assigned to ||. The special -|=++| syntax offers a variant not pre-computing the iterated -over list (which currently must thus proceed by steps of one.) +The pseudo-functions \xintFor #1 in {subs, seq, subsm, subsn, iter, add, mul, + rseq, iterr, rrseq, iterr, ndseq, ndmap, ndfillraw} \do +{\func{#1}\xintifForLast{}{, }} use delimited macros for some tasks: +\begin{itemize} +\item for all of them, whenever a |=| chunk must be parsed into a + (non-assigned) variable name, then the equal sign must be visible, +\item and if the syntax is with «|,=|» the initial comma also must be + visible (spaces do not matter), +\item for all of them but \func{ndmap} and \func{ndfillraw} the final closing + parenthesis must be visible. +\end{itemize} +Although delimited macros involving commas are used to locate «|,=| part may also be created from the expansion +which will generate the initial comma separated values delimited by a +semi-colon. + +Prior to |1.4|, semi-colons needed to be braced or otherwise hidden when +located in an expression parsed by \csbxint{defvar} or \csbxint{deffunc},\NewWith{1.4} to +not be confused with the expression terminator. This is not needed anymore. + \func{seq}, \func{rseq}, \func{iter}, \func{rrseq}, \func{iterr} and also \func{add}, \func{mul}, but not \func{subs} admit the \keyword{omit}, \keyword{abort}, and \keyword{break}|()| keywords. This is a -new feature for \func{add} and \func{mul}.\NewWith{1.4} - +new feature for \func{add} and \func{mul}. In the case of a potentially infinite list generated by the |++| syntax, use of @@ -5441,8 +5677,8 @@ All lowercase and uppercase Latin letters are pre-configured for usage as dummy variables. In Unicode engines one can use \csbxint{newdummy} to turn any letter into a usable dummy variable. -Further, since |1.4|, \csbxint{newdummy} works to turn a multi-letter word -into a dummy variable.\NewWith{1.4} +Since |1.4|,\NewWith{1.4} \csbxint{newdummy} works (in all engines) to turn a multi-letter +word into a dummy variable. \begin{description} % [parsep=0pt,align=left, @@ -5470,21 +5706,41 @@ results. Or one can use \func{seq}. See the documentation of \funcdesc[expr, letter=values]{add} addition \begin{everbatim*} -\xinttheiiexpr add(x^3,x=1..50), add(x(x+1), x=1,3,19)\relax +\xintiiexpr add(x^3,x=1..20), add(x(x+1), x=1,3,19)\relax\newline +\xintiiexpr add((odd(x))?{x^3}{omit}, x = 1..20)\relax\par % add only odd cubes +\end{everbatim*} + +\noindent At |1.4|,\NewWith {1.4a} the keywords \keyword{omit}, \keyword{abort} and +\keyword{break}|()| are allowed. But this was broken and got fixed at |1.4a|. +The |@| special variable holds the so-far accumulated value. Initially its +value is zero. +\begin{everbatim*} +\xintiiexpr add(1 + @, i=1..10)\relax % iterates x <- 2x+1 +\end{everbatim*} + +The meaning of \keyword{break}|()| is specific: its argument serves as last +operand for the addition, not as ultimate value. +\begin{everbatim*} +\xintiiexpr add((x>10)?{break(1000)}{x}, x = 1..15)\relax \end{everbatim*} -\noindent At |1.4|, the keywords \keyword{omit}, \keyword{abort} and -\keyword{break}|()| are allowed.\NewWith {1.4} - See |`+`| for syntax without a dummy variable. \funcdesc[expr, letter=values]{mul} multiplication \begin{everbatim*} -\xinttheiiexpr mul(x^2, x=1,3,19), mul(2n+1,n=1..10)\relax +\xintiiexpr mul(x^2, x=1,3,19), mul(2n+1,n=1..10)\relax \end{everbatim*} -\noindent At |1.4|, the keywords \keyword{omit}, \keyword{abort} and -\keyword{break}|()| are allowed.\NewWith {1.4} +\noindent At |1.4|,\NewWith {1.4a} the keywords \keyword{omit}, \keyword{abort} and +\keyword{break}|()| are allowed. But this was broken and got fixed at |1.4a|. +The |@| special variable holds the so-far accumulated value. Initially its +value is one. + +The meaning of \keyword{break}|()| is specific: its argument serves as last +operand for the multiplication, not as ultimate value. +\begin{everbatim*} +\xintiieval{mul((i==100)?{break(i^4)}{i}, i = 98, 99, 100)} +\end{everbatim*} See |`*`| for syntax without a dummy variable. @@ -5652,8 +5908,15 @@ legal. The || must be a \TeX-allowable integer. \begin{everbatim*} First Fibonacci number at least |2^31| and its index % we use iterr to refer via @1 and @2 to the previous and previous to previous. -\xinttheiiexpr iterr(0,1; (@1>=2^31)?{break(i)}{@2+@1}, i=1++)\relax +\xinttheiiexpr iterr(0,1; (@1>=2^31)?{break(@1, i)}{@2+@1}, i=1++)\relax \end{everbatim*} + +Note: the above example, up to |1.3f| used |break(i)| in place of current +|break(@1, i)|. This syntax looks in retrospect as having been a bug. +Starting with |1.4| the example does have to be written with |break(@1, i)|, +as |break(i)| conforming to intuition will only print the last |i| value. And +if one also wants the previous Fibonacci number one only has to use |break(@2, +@1, i)| for example. \end{description} @@ -5669,8 +5932,8 @@ major modern \TeX{} installations since more than ten years now. -\subsection{One-dimensional sequence generators} - +\subsection{Generators of arithmetic progressions} +\label{ssec:arithseq} \begin{itemize} \item |a..b| constructs the \textbf{small} integers from the ceil $\lceil @@ -5817,7 +6080,7 @@ NumPy's concepts (of basic slicing/indexing): \item slicing and itemizing apply also to non-bracketed objects i.e. \emph{oples}, \item the leaves do not have to be all at the same depth, \item there are never any out-of-range index errors: out-of-range indices - generate the |nil| variable (at the suitable depth). + are silently ignored. \end{itemize} \begin{everbatim*} @@ -6141,9 +6404,6 @@ with the (already evaluated) function arguments, and the parser \emph{will substitution, but with parentheses and comma separated arguments (which can be arbitrary expressions themselves). - - - \subsubsection{\csh{xintdeffunc}} \label{xintdeffunc} @@ -6174,9 +6434,9 @@ have gained experience in using this interface...): signs. A function name must start with a letter. It may be a single letter (see \autoref{sssec:overload}). \item The variable names used in the function signature may be multi-letter - words. It is also allowed for them to already be in use for previously + words.\NewWith{1.4} It is also allowed for them to already be in use for previously declared variables. Their meanings will get restored for usage after the - function declaration.\NewWith{1.4} + function declaration. \item A function can have at most nine arguments. It can be defined as a function with no arguments. \item Recursive definitions are possible; for them to not generate error or @@ -6184,9 +6444,9 @@ have gained experience in using this interface...): |??| is \emph{mandatory}.\CHANGED{1.4} \item If a function is used in another definition it will check if it is applied to numerical arguments and if this is the case will expand - fully. Prior to |1.4| one needed deprecated \csa{xintdefefunc} for this. But + fully.\CHANGED{1.4} Prior to |1.4| one needed deprecated \csa{xintdefefunc} for this. But the latter is now but an alias for \csa{xintdeffunc}, the two have been - merged.\CHANGED{1.4} + merged. \item The previous item has an exception for functions with no arguments; they never expand immediately in other function definitions (else they would be almost like variables). This provides a way to define functions with @@ -6531,7 +6791,7 @@ $$ For some hair-raising experience check the \csbxint{verbosetrue} output in the log... here is an alternative with two (three, counting |dprod()|) helper functions: -\begin{everbatim} +\begin{everbatim*} % annoying that Tr also starts Trace, but Spur is available % well Sp also starts Spectrum. Big problems. \xintdeffunc Tr(M) := @@ -6545,25 +6805,27 @@ functions: [dprod(r3, c1), dprod(r3, c2), dprod(r3, c3)]]; \xintdeffunc MatMul(A, B) := MatMul_a(*A, *Tr(B)); -\end{everbatim} +\end{everbatim*} And once we have the transpose and the scalar product of vectors, we can simply use \func{ndmap} for a lean syntax (this would extend to arbitrary dimension): \begin{everbatim*} -\xintdeffunc Tr(M) := - [[M[0,0], M[1,0], M[2,0]], - [M[0,1], M[1,1], M[2,1]], - [M[0,2], M[1,2], M[2,2]]]; \xintdeffunc MatMul(A, B) = ndmap(dprod, *A; *Tr(B)); \xintdefvar mat1212 = MatMul(mat12, mat12); -$$ - M_1\cdot M_2 \cdot M_1 \cdot M_2 = - \vcenter{\xintthealign \xintexpr mat1212\relax} -$$ -$$ - \det(M_1\cdot M_2 \cdot M_1 \cdot M_2) = \xinteval{reduce(DetMat(mat1212))} -$$ +\begingroup +\def\xintexprPrintOne #1{\xintFrac{#1}}% (no need for \protected with \xintFrac) +\def\xintexpralignbegin {\begin{pmatrix}}% +\def\xintexpralignend {\end{pmatrix}}% +\def\xintexpralignlinesep {\noexpand\\[2\jot]}% needed to counteract an internal \expanded +\def\xintexpraligninnersep {&}% +\let\xintexpralignleftbracket\empty \let\xintexpralignleftsep\empty +\let\xintexpralignrightbracket\empty \let\xintexpralignrightsep\empty +$$ \xintthealign \xintexpr mat1\relax \cdot \xintthealign \xintexpr mat2\relax \cdot + \xintthealign \xintexpr mat1\relax \cdot \xintthealign \xintexpr mat2\relax = + \xintthealign \xintexpr mat12\relax ^2 = \xintthealign \xintexpr mat1212\relax$$ +$$ \det(M_1\cdot M_2 \cdot M_1 \cdot M_2) = \xinteval{reduce(DetMat(mat1212))}$$ +\endgroup \end{everbatim*} \subsubsection{Example with the \textsc{Rump} test} @@ -6647,7 +6909,7 @@ If function |A| needs function |B| which needs function |A| start by giving to |B| some dummy definition, define |A|, then define |B| properly. TODO: add some example here... -\subsection {Links to some advanced (but old) examples within this document} +\subsection {Links to some (old) examples within this document} \label{sec:awesome} \begin{itemize} @@ -6695,10473 +6957,10468 @@ run.% \clearpage +\etocdepthtag.toc {part1B} + +\let\xintexprnameUp\undefined +\csname xinttrignameUp\endcsname + \def\n{|{N}|} \def\m{|{M}|} \def\x{|{x}|} +\section{Macros of the \xinttrigname package} +\RaisedLabel{sec:trig} -\etocdepthtag.toc {part1B} +\localtableofcontents -\expandafter\let\csname Syntax referencenameUp\endcsname\undefined -\csname Older macros and docnameUp\endcsname -\section{Macros of the \xintexprname package (legacy documentation)}% -\RaisedLabel{sec:oldxintexpr} +This package provides trigonometric functions for use with \xintexprname. +The sole macro is \csbxint{reloadxinttrig}. -\localtableofcontents +This package was first included in release |1.3e| (|2019/04/05|) of +\xintexprname. It is automatically loaded by \xintexprname. -The \xintexprname package was first released with version |1.07| -(|2013/05/25|) of the \xintname bundle. It was substantially enhanced with -release |1.1| from |2014/10/28|. +\textbf{Acknowledgements:} I finally decided to release some such functions +under friendly pressure of Jürgen \textsc{Gilg} and Thomas \textsc{Söll}, let +them both be thanked here. -The |1.4| release from |2020/01/31| maintains the same general architecture -but needed adapting all the code base for the switch from |\csname| to -|\expanded| techniques. On this occasion the mechanism for defining functions -was substantially strengthened. The parser core mechanisms were improved too. +\subsection{\csh{xintreloadxinttrig}}\label{xintreloadxinttrig} -The package loads automatically \xintfracname and \xinttoolsname. +The library is loaded automatically by \xintexprname, thus with the default +value of \csbxint{theDigits} which is \dtt{16}. But it can handle a precision +of up to about \fbox{\dtt{60}} digits (make this \dtt{59} at most for the +inverse functions). For this, execute for example \csbxint{SetDigits*}|{48}|. -This section is limited to some information which has not already been covered -in \autoref{sec:xintexprsyntax}. +\begin{framed} + Since |1.3f|, the starred variants \csbxint{Digits*}|:=P;| and + \csbxint{SetDigits*}\marg{num. expression} execute \csbxint{reloadxinttrig} + to let the package re-configure itself. -\subsection{The \csh{xintexpr} expressions} -\label{xintexpr} -\label{xinttheexpr} -\label{thexintexpr} -\label{xintthe} + The non-starred variants do not execute \csbxint{reloadxinttrig} (to avoid + adding artificial overhead to existing documents).\IMPORTANTf{} +\end{framed} -An \xintexprname{}ession is a construct -\csbxint{expr}\meta{expandable\_expression}|\relax|\etype{x} where the -expandable expression is read and completely expanded from left to right. +Absence of guard digits (whether in the used hard-coded constants or in +passing over values from one auxiliary function to the next) due to high level +(user) interface used for the programming means that the produced values are +definitely expected to be wrong in the last digit or last two digits. I should +actually give some estimate of the actual maximal error in |ulps| unit, but I +have not done the complete analysis for lack of time. -An |\xintexpr...\relax| \emph{must} end in a |\relax| (which will be absorbed). -Contrarily to a |\numexpr| expression, it is printable\CHANGED{1.4} as is without a prefix -|\the| or |\number| (don't use them with |\xintexpr| this will raise an -error). +Final computation results should thus probably be printed via +\csbxint{floateval}|{[-2]....}| in order to strip off (with rounding) the last +two digits, if one does not like seeing those non-meaningful figures in the +last one or two positions (I don't say those last two figures are +\emph{systematically} off). For example, to achieve \dtt{16} digits of +precision one should work with a precision of 18 digits (being careful to have +issued \csbxint{reloadxinttrig}) and round results using +\csbxint{floateval}|{[-2]....}|. -But one can use |\xintthe| prefix if one does need the explicit digits and -other characters as in the final typesetted result. +Another approach is to use \csbxint{ieval}|{[D]...}| for conversion to +a fixed point format. -As an alternative and equivalent syntax to -\begin{everbatim} -\xintexpr round(, D)\relax -\end{everbatim} -there is -\begin{everbatim} -\xintiexpr [D] \relax -\end{everbatim} -The parameter |D| must be zero or positive.\footnote{|D=0| - corresponds to using |round()| not |round(,0)| which - would leave a trailing dot. Same for |trunc|. There is also function |float| - for floating point rounding to \csbxint{theDigits} or the given number of - significant digits as second argument.} Perhaps some future version will -give a meaning to using a negative |D|.\footnote{Thanks to KT for this - suggestion. Sorry for the delay in implementing it... matter of formatting - the output and corresponding choice of user interface are still in need of - some additional thinking.} +In future, lower level coding will probably replace the high-level interface, +or at least the macros produced by the high-level interface will be hacked +into to tell the float macros to work at a somewhat elevated precision. -\begin{itemize} -\item the expression may contain arbitrarily many levels of nested parenthesized - sub-expressions, -\item the expression may contain explicitely or from a macro expansion a - sub-expression |\xintexpr...\relax|, which itself may contain a - sub-expressions etc\dots -\item to let sub-contents evaluate as a sub-unit it should thus be either - \begin{enumerate} - \item parenthesized, - \item or a sub-expression |\xintexpr...\relax|. - \end{enumerate} - \item to use an expression as argument to macros from \xintfracname, - or more generally to macros which expand their arguments, one must use the - |\xinttheexpr...\relax| or |\xintthe\xintexpr...\relax| forms. - \item one should not use |\xintthe\xintexpr...\relax| as a sub-constituent of - another expression but only the - |\xintexpr...\relax| form which is more efficient in this context. - \item each \xintexprname{}ession, whether prefixed or not with |\xintthe|, is - completely expandable and obtains its result in two expansion steps. -\end{itemize} +\subsection{Constants} -The information now following is possibly in need of updates. +They are the correct rounding to \csbxint{theDigits} precision of the +mathematically exact ones. Their values get incorporated into the +trigonometrical functions at the time of their definitions during loading or +reloading of the package. They are left free to use, or modified, or +\csbxint{unassignvar}'d, as this will have no impact whatsoever on the +functions. -\begin{itemize}[parsep=0pt, labelwidth=\leftmarginii, - itemindent=0pt, listparindent=\leftmarginiii, leftmargin=\leftmarginii] -\item An expression is built the standard way with opening and closing - parentheses, infix operators, and (big) numbers, with possibly a fractional - part, and/or scientific notation (except for \csbxint{iiexpr} which only - admits big integers). All variants work with comma separated expressions. On - output each comma will be followed by a space. A decimal number must have - digits either before or after the decimal mark. +\begin{description} +\vardesc{twoPi} what could that be? +\vardesc{threePiover2} +\vardesc{Pi} +\vardesc{Piover2} +\vardesc{oneRadian} this is one radian in degrees: $180/\pi$ +\vardesc{oneDegree} this is one degree in radian: $\pi/180$ +\vardesc{invfact2} this is $1/2!$ +\vardesc{invfact3} this is $1/3!$ +\item[\dots] +\vardesc{invfact44} this is $1/44!$ +\end{description} -\item As everything gets expanded, the characters |.|, |+|, |-|, |*|, |/|, |^|, - |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, |=|, |(|, |)|, |"|, |]|, |[|, |@| - and the comma |,| should not (if used in the expression) be active. For - example, the French language in |Babel| system, for pdf\LaTeX, activates |!|, - |?|, |;| and |:|. Turn off the activity before expressions using such characters. +For a (very) slight optimization of usage, it is recommended to convert them +to macro form, for example: +\begin{everbatim*} +\edef\oneDegree{\xintfloatexpr oneDegree\relax} +\xintfloateval{sin(37\oneDegree)}\newline +\xintfloateval{sind(37)}\newline +\end{everbatim*} +By the way, the above value differs by |1ulp| from correct rounding of exact +one (which looks \dtt{...520482}79917...), see \autoref{ssec:trignotes}. - Alternatively the macro \csbxint{exprSafeCatcodes} resets all - characters potentially needed by \csbxint{expr} to their standard catcodes - and \csbxint{exprRestoreCatcodes} restores the former status. +\subsection{Functions} -\item Count registers and |\numexpr|-essions are accepted (LaTeX{}'s counters - can be inserted using |\value|) natively without |\the| or |\number| as - prefix. Also dimen registers and control sequences, skip registers and - control sequences (\LaTeX{}'s lengths), |\dimexpr|-essions, - |\glueexpr|-essions are automatically unpacked using |\number|, discarding - the stretch and shrink components and giving the dimension value in |sp| - units ($1/65536$th of a \TeX{} point). Furthermore, tacit multiplication is - implied, when the (count or dimen or glue) register or variable, or the - (|\numexpr| or |\dimexpr| or |\glueexpr|) expression is immediately prefixed - by a (decimal) number. See \autoref{ssec:tacit multiplication} for the complete rules - of tacit multiplication.\IMPORTANT +\subsubsection{Direct trigonometry} -\item With a macro |\x| defined like this: - % - \leftedline{|\def\x {\xintexpr \a + \b \relax}| or |\edef\x {\xintexpr - \a+\b\relax}|} - % - one may then do |\xintthe\x|, either for printing the result on the page or - to use it in some other macros expanding their arguments. The |\edef| does - the computation immediately but keeps it in a protected form. - Naturally, the |\edef| is only possible if |\a| and |\b| are already - defined. With both approaches the |\x| can be inserted in other expressions, - as for example (assuming naturally as we use an |\edef| that in the - `yet-to-be computed' case the |\a| and |\b| now have some suitable meaning): - % - \leftedline {|\edef\y {\xintexpr \x^3\relax}|} +With the variable in radians: -\item There is also \csbxint{boolexpr}| ... \relax| and - \csbxint{theboolexpr}| ... \relax|. +\begin{description} +\funcdesc{sin} sine +\funcdesc{cos} cosine +\funcdesc{tan} tangent +\funcdesc{cot} cotangent +\funcdesc{sec} secant +\funcdesc{csc} cosecant +\end{description} -\item See also - \csbxint{ifboolexpr} (\autoref{xintifboolexpr}) and the - \func{bool} and \func{togl} functions - in \autoref{sec:expr}. Here is an example. Well in fact the - example ended up using only \csbxint{boolexpr} so it - was modified to use \csbxint{ifboolexpr}. -\catcode`| 12 % -\begin{everbatim*} -\xintdeffunc A(p,q,r) = p && (q || r) ; -\xintdeffunc B(p,q,r) = p || (q && r) ; -\xintdeffunc C(p,q,r) = xor(p, q, r) ; +With the variable in degrees: -{\centering\normalcolor -\begin{tabular}{ccrclcl} - \xintFor* #1 in {{False}{True}} \do {% - \xintFor* #2 in {{False}{True}} \do {% - \xintFor* #3 in {{False}{True}} \do {% - #1 &AND &(#2 &OR )&is&\textcolor[named]{OrangeRed} - {\xintifboolexpr{A(#1,#2,#3)}{true}{false}}\\ - #1 &OR &(#2 &AND )&is&\textcolor[named]{OrangeRed} - {\xintifboolexpr{B(#1,#2,#3)}{yes}{no}}\\ - #1 &XOR & #2 &XOR  &is&\textcolor[named]{OrangeRed} - {\xintifboolexpr{C(#1,#2,#3)}{oui}{non}}\\ -}}} -\end{tabular} -} -\end{everbatim*}\catcode`| 13 +\begin{description} +\funcdesc{sind} sine +\funcdesc{cosd} cosine +\funcdesc{tand} tangent +\funcdesc{cotd} cotangent +\funcdesc{secd} secant +\funcdesc{cscd} cosecant +\end{description} -\item See also \csbxint{ifsgnexpr}. +Only available with the variable in radians: +\begin{description} +\funcdesc{tg} tangent +\funcdesc{cotg} cotangent +\funcdesc{sinc} cardinal sine $\sinc(x) = \sin(x)/x$ +\end{description} -\item There is \csbxint{floatexpr}| ... \relax| where the algebra is done - in floating point approximation (also for each intermediate result). Use the - syntax |\xintDigits:=N\relax| to set the precision. Default: $16$ digits. - % - \leftedline{|\xintthefloatexpr 2^100000\relax:| \dtt{\xintthefloatexpr - 2^100000\relax }} - % - The square-root operation can be used in |\xintexpr|, it is computed - as a float with the precision set by |\xintDigits| or by the optional - second argument: - % -\begin{everbatim*} -\xinttheexpr sqrt(2,60)\relax\newline -Here the [60] is to avoid truncation to |\xinttheDigits| of precision on output.\newline -\printnumber{\xintthefloatexpr [60] sqrt(2,60)\relax} -\end{everbatim*} +\subsubsection{Inverse trigonometry} - Floats are quickly indispensable when using the power function, as exact - results will easily have hundreds, even thousands of digits. - % -\begin{everbatim*} -\xintDigits:=48\relax \xintthefloatexpr 2^100000\relax -\end{everbatim*} +With the value in radians: - Only integer and (in |\xintfloatexpr...\relax|) half-integer exponents are - allowed. +\begin{description} +\funcdesc{asin} arcsine +\funcdesc{acos} arccosine +\funcdesc{atan} arctangent +\funcdesc[x, y]{Arg} the main branch of the argument of the complex number +|x+iy|, from $-\pi$ (excluded) to $\pi$ (included). As the output is rounded +-\var{Pi} is a possible return value. +\funcdesc[x, y]{pArg} the branch of the argument of the complex number +|x+iy| with values going from $0$ (included) to $2\pi$ (excluded). Inherent +rounding makes \var{twoPi} a possible return value. +\funcdesc[y, x]{atan2} it is |Arg(x, y)|. Note the reversal of the arguments, +this seems to be the most frequently encountered convention across languages. +\end{description} -\item if one uses \emph{macros} within |\xintexpr..\relax| one should - obviously take into account that the parser will \emph{not} see the macro - arguments, hence one cannot use the syntax there, except if the arguments - are themselves wrapped as |\xinttheexpr...\relax| and assuming the macro - \fexpan ds these arguments. -\end{itemize} -\subsection{\texorpdfstring{\texttt{\protect\string\numexpr}}{\textbackslash - numexpr} or \texorpdfstring{\texttt{\protect\string\dimexpr}}{\textbackslash - dimexpr} expressions, count and dimension registers and variables} -\label{ssec:countinexpr} +With the value in degrees: -Count registers, count control sequences, dimen registers, dimen control -sequences (like |\parindent|), skips and skip control sequences, |\numexpr|, -|\dimexpr|, |\glueexpr|, |\fontdimen| can be inserted directly, they will be -unpacked using |\number| which gives the internal value in terms of scaled -points for the dimensional variables: $1$\,|pt|${}=65536$\,|sp| (stretch and -shrink components are thus discarded). +\begin{description} +\funcdesc{asind} arcsine +\funcdesc{acosd} arccosine +\funcdesc{atand} arctangent +\funcdesc[x, y]{Argd} the main branch of the argument of the complex number +|x+iy|, from $-180$ (excluded) to $180$ (included). Inherent rounding of +output can cause |-180| +to be returned. +\funcdesc[x, y]{pArgd} the branch of the argument of the complex number +|x+iy| with values going from $0$ (included) to $360$ (excluded). Inherent rounding of +output can cause |360| to be returned. +\funcdesc[y, x]{atan2d} it is |Argd(x, y)|. Note the reversal of the arguments, +this seems to be the most frequently encountered convention across languages. +\end{description} -Tacit multiplication (see \autoref{ssec:tacit multiplication}) is implied, -when a number or decimal number prefixes such a register or control sequence. -\LaTeX{} lengths are skip control sequences and \LaTeX{} counters should be -inserted using |\value|. +\subsubsection{Conversion functions (optional definitions left to user + decision)} -Release |1.2| of the |\xintexpr| parser also recognizes and prefixes with -|\number| the |\ht|, |\dp|, and |\wd| \TeX{} primitives as well as the -|\fontcharht|, |\fontcharwd|, |\fontchardp| and |\fontcharic| \eTeX{} -primitives. +Python provides functions |degrees()| and |radians()|. But as most of the +\xinttrigname functions are already defined for the two units, I felt this was +not really needed. It is a oneliner to add them: +\begin{everbatim} +\xintdeffloatefunc radians(x) := x * oneDegree; +\xintdeffloatefunc degrees(x) := x * oneRadian; +\xintdefefunc radians(x) := float_(x * oneDegree); +\xintdefefunc degrees(x) := float_(x * oneRadian); +\end{everbatim} -In the case of numbered registers like |\count255| or |\dimen0| (or |\ht0|), -the resulting digits will be re-parsed, so for example |\count255 0| is like -|100| if |\the\count255| would give |10|. The same happens with inputs such -as |\fontdimen6\font|. And |\numexpr 35+52\relax| will be exactly as if |87| -as been encountered by the parser, thus more digits may follow: |\numexpr -35+52\relax 000| is like |87000|. If a new |\numexpr| follows, it is treated -as what would happen when |\xintexpr| scans a number and finds a non-digit: it -does a tacit multiplication. -\begin{everbatim*} -\xinttheexpr \numexpr 351+877\relax\numexpr 1000-125\relax\relax{} is the same -as \xinttheexpr 1228*875\relax. -\end{everbatim*} +The \csbxint{expr}-variants above do an exact multiplication. The +\func{float\string_} explicit rounding is a bit superfluous as anyhow trigonometrical +functions do this initial rounding of their arguments. -Control sequences however (such as |\parindent|) are picked up as a whole by -|\xintexpr|, and the numbers they define cannot be extended extra digits, a -syntax error is raised if the parser finds digits rather than a legal -operation after such a control sequence. +The conversion factors above are without guard digits. Probably better to work +overall with an elevated precision and print final results at a lower +precision. -A token list variable must be prefixed by |\the|, it will not be unpacked -automatically (the parser will actually try |\number|, and thus fail). Do not -use |\the| but only |\number| with a dimen or skip, as the |\xintexpr| parser -doesn't understand |pt| and its presence is a syntax error. To use a dimension -expressed in terms of points or other \TeX{} recognized units, incorporate it in -|\dimexpr...\relax|. +\subsection{Important implementation notes} +\label{ssec:trignotes} -Regarding how dimensional expressions are converted by \TeX{} into scaled points -see also \autoref{sec:Dimensions}. +\begin{itemize} +\item The package is almost entirely implemented using the high level user + interface of \xintexprname, using + \csbxint{deffloatefunc} (and \csbxint{deffloatvar}), the main two exceptions + being for: + \begin{enumerate}[nolistsep] + \item the range reduction for the |sind()| and |cosd()| functions which + required for optimized efficiency the coding at some more core level. + \item some changes at core level added at |1.3e| to + facilitate the transfer of the defined functions from the float parser to + the exact parser. + \end{enumerate} + Also, to avoid problems if the package is reloaded at a time the user has + used some letter variables as assigned variables, |1.3e| added + \csbxint{ensuredummy} and \csbxint{restorevariable}. +\item It is not possible from this interface to (easily) let the computation + proceed with a temporarily elevated precision (``guard digits''). Expect + thus some errors in the last places; basically one should use the optional + rounding argument of either \csbxint{floateval} or \csbxint{ieval} to reduce + the number of digits of printed values by about two digits, if one + hopes to get correct rounding (most of the time). +\item Currently, \xintname is lacking some dedicated internal representation + of floats which means that most operations re-parse the digit tokens of their + arguments to count them\dots\ this does not contribute to efficiency (you + can load the module under |\xintverbosetrue| regime and see how the nested + macros look like and get an idea of how many times some rather silly + re-counting of mantissa lengths will get done!) +\item One should not overwrite some function names which are employed as + auxiliaries: |sin_aux|, |cos_aux|, |sin_|, |cos_|, |sind_|, |cosd_|, + |asin_l|\dots others\dots |asin_a|, |asind_a|, |atan_a|, |atand_a|, + |atan_b|, |atand_b|. If you redefine any one of them, you break the + whole thing. +\item Floats with large exponents are integers and are multiple of \dtt{1000}; + hence modulo \dtt{360} all such ``angles'' are multiple of \dtt{40} degrees. + Needless to say that considering usage of the |sind()| and |cosd()| functions + with such large float numbers is meaningless. +\item Regarding |sin()| and |cos()|, \xinttrigname converts their argument to + degrees by multiplication by (pre-rounded) $180/\pi$, then does range + reduction modulo $360$ and finally goes back to radians in the appropriate + octants to use usual Taylor series (roughly said). For large floats, the + output value will thus be one of |sind(40n)|, |cosd(40n)|, |n=0..8|. If the + unit in the last place of original variable was for example \dtt{1e9} the + final result means nothing at all: the unit in the last place interval + extends above possibly astronomical numbers of intervals of length $2\pi$. -\subsection{Catcodes and spaces} + This intrinsic problem is not a by-product of conversion problems to and + from degrees, it is an in-built inadequacy of the concept of floating point + numbers to provide meaning to evaluating trigonometrical functions. The + argument should be treated as a uniformly distributed random variable modulo + $2\pi$, and the sine and cosine values should be random variables realizing + the value distribution of these mathematical functions. Clearly this adds + some (rather severe) implementation complications such as deciding how to + make the transition to randomness. Too lazy for that. -Active characters may (and will) break the functioning of \csbxint{expr}. -Inside an expression one may prefix, for example a |:| with |\string|. Or, for -a more radical way, there is \csbxint{exprSafeCatcodes}. This is a -non-expandable step as it changes catcodes. + Opting for a random value also raises the question of how to deal with + multiple such evaluations at the same argument in a single expression. I + would argue again that as it is evil to consider meaningless quantities, it + is not a problem if new compilations give different results, or even single + compilation gives different results in various parts of the same formula, + that's the whole point of randomness! As said already, I got too lazy to + consider seriously implementing such a non-standard philosophy, despite its + compelling soundness. +\item Did I say the implementation was done at very high level (for the most + part), hence has ample room for optimization? This is particularly the case + for the handling of small inputs by functions such as sine or arcsine. +\end{itemize} -\subsubsection{\csh{xintexprSafeCatcodes}} -\label{xintexprSafeCatcodes} +\subsection{Some example evaluations} -This macro sets the catcodes of many characters to safe values. This is used -internally by \csbxint{NewExpr} (restoring the catcodes on exit), hence it -does not have to be protected against active characters when used at -top-level. +\noindent +\begin{everbatim*} +\xintDigits* := 50\relax % target 48 digits via 2 guard digits +$sind(17)\approx\xintfloateval{[-2] sind(17)}$\newline +$cosd(17)\approx\xintfloateval{[-2] cosd(17)}$\newline +$tand(17)\approx\xintfloateval{[-2] tand(17)}$\newline +$sind(43)\approx\xintfloateval{[-2] sind(43)}$\newline +$cosd(43)\approx\xintfloateval{[-2] cosd(43)}$\newline +$tand(43)\approx\xintfloateval{[-2] tand(43)}$\newline +$asind(0.3)\approx\xintfloateval{[-2] asind(0.3)}$\newline +$acosd(0.3)\approx\xintfloateval{[-2] acosd(0.3)}$\newline +$atand(3)\approx\xintfloateval{[-2] atand(3)}$\newline +$tan(atan(7))\approx\xintfloateval{[-2] tan(atan(7))}$\newline +$asind(sind(25))\approx\xintfloateval{[-2] asind(sind(25))}$\par\medskip +\noindent\xintDigits* := 26\relax % target 24 digits via 2 guard digits +$sind(17)\approx\xintfloateval{[-2] sind(17)}$\newline +$cosd(17)\approx\xintfloateval{[-2] cosd(17)}$\newline +$tand(17)\approx\xintfloateval{[-2] tand(17)}$\newline +$sind(43)\approx\xintfloateval{[-2] sind(43)}$\newline +$cosd(43)\approx\xintfloateval{[-2] cosd(43)}$\newline +$tand(43)\approx\xintfloateval{[-2] tand(43)}$\newline +$asind(0.3)\approx\xintfloateval{[-2] asind(0.3)}$\newline +$acosd(0.3)\approx\xintfloateval{[-2] acosd(0.3)}$\newline +$atand(3)\approx\xintfloateval{[-2] atand(3)}$\newline +$tan(atan(7))\approx\xintfloateval{[-2] tan(atan(7))}$\newline +$asind(sind(25))\approx\xintfloateval{[-2] asind(sind(25))}$\par +\xintDigits* := 16\relax +\end{everbatim*} -Also \csbxint{defvar}, \csbxint{deffunc}, ..., use it before fetching their -semi-colon delimited arguments, so they can be used (also in the document -body) for example with Babel+French which makes the semi-colon active in the -(\LaTeX) document body. +\clearpage +\let\xinttrignameUp\undefined +\csname xintlognameUp\endcsname +\def\n{|{N}|} +\def\m{|{M}|} +\def\x{|{x}|} -As \csbxint{NewExpr} and \csbxint{deffunc} and variants use internally some -|\scantokens|, they will (reasonably) succeed in sanitizing catcodes in the -expressions, even if all is from the replacement text of some macro whose -definition was done under some special catcode regime. +\section{Macros of the \xintlogname package} +\RaisedLabel{sec:log} -But \csbxint{deffunc}, \csbxint{defvar} and variants need the (catcode other) -semi-colon as delimiter. Thus make sure the semi-colon has its normal catcode -when using \csbxint{deffunc} inside some macro definition. +This package provides logarithms, exponentials and fractional powers for use +with \xintexprname. -The macros \csbxint{deffunc} and variants ignore completely the colon in |:=| -(which furthermore is optional) so it can have any (reasonable) frozen catcode. +This package was first included in release |1.3e| (|2019/04/05|) of +\xintexprname. It is automatically loaded by \xintexprname. -The macros \csbxint{defvar} and variants are also compatible with any -reasonable frozen catcode of the colon |:| in |:=|, and the colon presence is -only optional. +Currently, the functions \func{log10}, \func{pow10}, \func{log}, \func{exp}, +and \func{pow} use at their core two fast expandable macros handling base 10 +logarithms and powers for mantissas of 9 digit tokens. They are +defined by package \href{https://ctan.org/pkg/poormanlog}{poormanlog} which is +automatically imported. The error is believed to be at most \dtt{2ulp} (see +its |README|). The package \href{https://ctan.org/pkg/poormanlog}{poormanlog} +has no dependencies and can be imported by any other \TeX\ macro file. -\begin{framed} - It is important to ALWAYS shortly let \csbxint{exprSafeCatcodes} be followed - by \csbxint{exprRestoreCatcodes}.\IMPORTANTf{} If one uses twice - \csbxint{exprSafeCatcodes} then the next \csbxint{exprRestoreCatcodes} will - restore the ancient catcode regime at time of the first one. -\end{framed} +Although the precision is thus limited to about \dtt{8} or \dtt{9} digits this +is amply enough for plots. -\subsubsection{\csh{xintexprRestoreCatcodes}} -\label{xintexprRestoreCatcodes} +\localtableofcontents -Restores the catcodes to the earlier state. More precisely, -\csbxint{exprSafeCatcodes} sets a toggle (with local scope). If the toggle is -set already it does not restore the current catcodes. The next -\csa{xintexprRestoreCatcodes} unsets the toggle. -So, in case of nesting, the -catcodes are restored to what they were when the \emph{first} un-paired -\csbxint{exprSafeCatcodes} got executed. +\subsection{\csh{poormanloghack}} +\label{ssec:poormanloghack} -\bigskip +\begin{description} +\item[\string\poormanloghack\string{**\string}] use it to let the |**| operator be remapped to the + \func{pow} function. +\item[\string\poormanloghack\string{\string^\string}] use it to let the |^| operator be remapped to the + \func{pow} function. +\end{description} +If used, they obey \TeX\ scoping as usual. +\begin{everbatim*} +\begingroup +\poormanloghack{**}\xintfloateval{[8]1.234**5.678}\newline +\poormanloghack{^}\xintfloateval{[8]1.234^5.678}\par +\endgroup +\end{everbatim*} -Spaces inside an |\xinttheexpr...\relax| should mostly be -innocuous (except inside macro arguments). +Notice that in \csbxint{floateval} those (equivalent) operators already +natively handle half-integer exponents. Once remapped to the \func{pow} +function they will become less precise than the original ones for half-integer +and integer exponents. -|\xintexpr| and |\xinttheexpr| are for the most part agnostic regarding -catcodes: (unbraced) digits, binary operators, minus and plus signs as -prefixes, dot as decimal mark, parentheses, may be indifferently of catcode -letter or other or subscript or superscript, ..., it doesn't matter.% -% -\footnote{Furthermore, although \csbxint{expr} uses \csa{string}, it is - escape-char agnostic. It should work with any \csa{escapechar} setting - including -1.} +\subsection{Functions} -The characters |+|, |-|, |*|, |/|, |^|, |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, -|=|, |(|, |)|, |"|, |[|, |]|, |;|, the dot and the comma should not be active if -in the expression, as everything is expanded along the way. If one of them is -active, it should be prefixed with |\string|. +All those functions achieve only about \dtt{8} or \dtt{9} digits of precision. +Notice in particular that the digits beyond the ninth printed by \func{log} +have no significance (here we suppose |10| within brackets, immediately after |\xintiexpr| -is allowed: it instructs the expression to do its final rounding to the -nearest value with that many digits after the decimal mark, \emph{i.e.}, -|\xintiexpr [D] \relax| is equivalent (in case of a single -expression) to |\xintexpr round(, D)\relax|. -|\xintiexpr [0] ...| is the same as |\xintiexpr ...|. + Since |1.2| ``big numbers'' must have less than about \dtt{19950} digits: + the maximal number of digits for addition is at \dtt{19968} digits, and it + is \dtt{19959} for multiplication. The reasonable range of use of the + package is with numbers of up to a few hundred digits.\footnotemark -If truncation rather than rounding is needed use (in case of a single -expression, naturally) |\xintexpr trunc(...)\relax| for truncation to an -integer or |\xintexpr trunc(...,D)\relax| for truncation to a decimal number -with |D>0| digits after the decimal mark (works only here for single scalar -value). + \TeX\ does not know off-hand how to print on the page such very long + numbers, see \autoref{ssec:printnumber}. +\end{framed} +\footnotetext{For example multiplication of integers having from \dtt{50} to + \dtt{100} digits takes roughly of the order of the millisecond on a 2012 + desktop computer. I compared this to using Python3: using timeit module on a + wrapper defined as |return w*z| with random integers of \dtt{100} digits, I + observe on the same computer a computation time of roughly $4.10^{-7}$s per + call. And with |return str(w*z)| then this becomes more like $16.10^{-7}$s + per call. And with |return str(int(W)*int(Z))| where |W| and |Z| are + strings, this becomes about $26.10^{-7}$s (I am deliberately ignoring + Python's Decimal module here...) Anyway, my sentence from earlier version of + this documentation: \emph{this is, I guess, at least about 1000 times slower + than what can be expected with any reasonable programming language,} is + about right. I then added: \emph{nevertheless as compilation of a typical + \LaTeX\ document already takes of the order of seconds and even dozens of + seconds for long ones, this leaves room for reasonably many computations + via \xintexprname or via direct use of the macros of + \xintname/\xintfracname.}} -Perhaps in the future some meaning will be given to using negative value for -the optional parameter |D|.\footnote{Thanks to Kpym for this suggestion.} +Integers with only $10$ digits and starting with a $3$ already exceed the +\TeX{} bound; and \TeX{} does not have a native processing of floating point +numbers (multiplication by a decimal number of a dimension register is allowed +--- this is used for example by the +\href{http://mirrors.ctan.org/graphics/pgf/base}{pgf} basic math engine.) -\subsection{\csh{xintiiexpr}, \csh{xinttheiiexpr}} -\label{xintiiexpr}\label{xinttheiiexpr}\label{thexintiiexpr} +\TeX{} elementary operations on numbers are done via the non-expandable +\emph{\char92advance, \char92multiply, \emph{and} \char92divide} assignments. +This was changed with \eTeX{}'s |\numexpr| which does expandable computations +using standard infix notations with \TeX{} integers. But \eTeX{} did not +modify the \TeX{} bound on acceptable integers, and did not add floating point +support. -This variant\etype{x} does not know fractions. It deals almost only with long -integers. Comma separated lists of expressions are allowed. +The \href{https://ctan.org/pkg/bigintcalc}{bigintcalc} package by +\textsc{Heiko Oberdiek} provided expandable macros (using some of |\numexpr| +possibilities, when available) on arbitrarily big integers, beyond the \TeX{} +bound. It does not provide an expression parser.% +% +\footnote{One can currently use package + \href{http://ctan.org/pkg/bnumexpr}{bnumexpr} to associate the |bigintcalc| + macros with an expression parser. This may be unavailable in future if + |bnumexpr| becomes more tightly associated with future evolutions or + variants of \xintcorename.} +% +\xintname did it again using more of |\numexpr| for higher speed, and in a +later evolution added handling of exact fractions, of scientific numbers, and +an expression parser. Arbitrary precision floating points operations were +added as a derivative, and not part of the initial design goal. -\begin{framed} - It maps |/| to the \emph{rounded} quotient. The operator - |//| is, like in |\xintexpr...\relax|, mapped to \emph{truncated} division. - The Euclidean quotient (which for positive operands is like the truncated - quotient) was, prior to release |1.1|, associated to |/|. The function - |quo(a,b)| can still be employed. -\end{framed} +The concept of signed infinities, signed zeroes, |NaN|'s, error +traps\dots,\footnote{The latter exist as work-in-progress for some time in the + source code.} have not been implemented, only the notion of `scientific +notation with a given number of significant figures'.% +% +\footnote{multiplication of two floats with |P=\xinttheDigits| digits is + first done exactly then rounded to |P| digits, rather than using a + specially tailored multiplication for floating point numbers which + would be more efficient (it is a waste to evaluate fully the + multiplication result with |2P| or |2P-1| digits.)} -The \csbxint{iiexpr}-essions use the `ii' macros for addition, subtraction, -multiplication, power, square, sums, products, Euclidean quotient and -remainder. +The \LaTeX3 project has implemented expandably floating-point computations with +\dtt{16} significant figures +(\href{https://ctan.org/pkg/l3kernel}{l3fp}), including +functions such as exp, log, sine and cosine.\footnote{at the time of writing (2014/10/28) the + \href{https://ctan.org/pkg/l3kernel}{l3fp} (exactly represented) floating + point numbers have their exponents limited to $\pm$\dtt{9999}.} +% -The |round|, |trunc|, |floor|, |ceil| functions are still available, and are -about the only places where fractions can be used, but |/| within, if not -somehow hidden will be executed as integer rounded division. To avoid this one -can wrap the input in \dtt{qfrac}: this means however that none of the normal -expression parsing will be executed on the argument. +More directly related to the \xintname bundle there is the \liiibigint{} +package, also devoted to big integers and in development a.t.t.o.w (2015/10/09, +no division yet). It is part of the experimental trunk of the +\href{http://latex-project.org}{\LaTeX3 Project} and provides an expression +parser for expandable arithmetic with big integers. Its author Bruno +\textsc{Le Floch} succeeded brilliantly into implementing expandably the +Karatsuba multiplication algorithm and he achieves \emph{sub-quadratic growth + for the computation time}. This shows up very clearly with numbers having +thousands of digits, up to the maximum which a.t.t.o.w is at $8192$ digits. -To understand the illustrative examples, recall that |round| and |trunc| have -a second (non negative) optional argument. In a normal \csbxint{expr}-essions, -|round| and |trunc| are mapped to \csbxint{Round} and \csbxint{Trunc}, in -\csbxint{iiexpr}-essions, they are mapped to \csbxint{iRound} and -\csbxint{iTrunc}. +The \liiibigint{} multiplication from late |2015| is observed to be roughly +|3x--4x| faster than the one from \csbxint{iiexpr} in the range of \dtt{4000} +to \dtt{5000} digits integers, and isn't far from being |9x| faster at +\dtt{8000} digits. On the other hand \csbxint{iiexpr}'s multiplication is +found to be on average roughly |2.5x| faster than \liiibigint's for numbers up +to \dtt{100} digits and the two packages achieve about the same speed at +\dtt{900} digits: but each such multiplication of numbers of \dtt{900} digits +costs about one or two tenths of a second on a 2012 desktop computer, whereas +the order of magnitude is rather the |ms| for numbers with \dtt{50--100} +digits.\footnote{I have tested this again on |2016/12/19|, but the macros have + not changed on the \liiibigint{} side and barely on the \xintcorename side, + hence I got again the same results\dots} -\begin{everbatim*} -\xinttheiiexpr 5/3, round(5/3,3), trunc(5/3,3), trunc(\xintDiv {5}{3},3), -trunc(\xintRaw {5/3},3)\relax{} are problematic, but -% -\xinttheiiexpr 5/3, round(qfrac(5/3),3), trunc(qfrac(5/3),3), floor(qfrac(5/3)), -ceil(qfrac(5/3))\relax{} work! -\end{everbatim*} +Even with the superior \liiibigint{} Karatsuba multiplication it takes about +|3.5s| on this 2012 desktop computer for a single multiplication of two +\dtt{5000}-digits numbers. Hence it is not possible to do routinely such +computations in a document. I have long been thinking that without the +expandability constraint much higher speeds could be achieved, but perhaps I +have not given enough thought to sustain that optimistic stance.\footnote{The + \href{https://ctan.org/pkg/apnum}{apnum} package implements + (non-expandably) arbitrary precision fixed point algebra and (v1.6) + functions exp, log, sqrt, the trigonometrical direct and inverse functions.} -On the other hand decimal numbers and scientific numbers can be used directly -as arguments to the |num|, |round|, or any function producing an integer. +I remain of the opinion that if one really wants to do computations with +\emph{thousands} of digits, one should drop the expandability requirement. +Indeed, as clearly demonstrated long ago by the +\href{https://ctan.org/pkg/pi}{pi computing file} by \textsc{D. Roegel} one +can program \TeX{} to compute with many digits at a much higher speed than +what \xintname achieves: but, direct access to memory storage in one form or +another seems a necessity for this kind of speed and one has to renounce at +the complete expandability.% +% +\footnote{The Lua\TeX{} project possibly makes endeavours such as \xintname + appear even more insane that they are, in truth: \xintname is able to handle + fast enough computations involving numbers with less than one hundred digits + and brings this to all engines.} -\begin{framed} - Scientific numbers will be - represented with as many zeroes as necessary, thus one does not want to - insert \dtt{num(1e100000)} for example in an \csa{xintiiexpr}ession! -\end{framed} +\subsection{Floating point evaluations} +\label{ssec:floatingpoint} +Floating point macros are provided by package \xintfracname to work with a +given arbitrary precision |P|. The default value is $P=16$ meaning that the +significands of the produced (non-zero) numbers have \dtt{16} decimal digits. +The syntax to set the precision to |P| is % -\begin{everbatim*} -\xinttheiiexpr num(13.4567e3)+num(10000123e-3)\relax % should (num truncates) compute 13456+10000 -\end{everbatim*} +\centeredline{|\xintDigits:=P\relax|} % +The value is local to the group or environment (if using \LaTeX). To query the +current value use \csbxint{theDigits}. -The |reduce| function is not available and will raise an error. The |frac| -function also. The |sqrt| function is mapped to \csbxint{iiSqrt} which gives -a truncated square root. The |sqrtr| function is mapped to \csbxint{iiSqrtR} -which gives a rounded square root. - -One can use the Float macros if one is careful to use |num|, or |round| -etc\dots on their output. - -\begin{everbatim*} -\xinttheiiexpr \xintFloatSqrt [20]{2}, \xintFloatSqrt [20]{3}\relax % no operations +Most floating point macros accept an optional first argument |[P]| which then +sets the target precision and replaces the |\xintDigits| assigned value (the +|[P]| must be repeated if the arguments are themselves \xintfracname macros +with arguments of their own.) In this section |P| refers to the prevailing +|\xinttheDigits| float precision or to the target precision set in this way as +an optional argument. -\noindent The next example requires the |round|, and one could not put the |+| inside it: +\csbxint{floatexpr}|[Q]...\relax| also admits an optional argument |[Q]| but +it has an altogether different meaning: the computations are always done with +the prevailing |\xinttheDigits| precision and the optional argument |Q| is +used for the final rounding. This makes sense only if |Q<\xinttheDigits| and +is intended to clean up the result from dubious last digits (when |Q<0| it +indicates rather by how many digits one should reduce the mantissa lengths via a +final rounding). -\xinttheiiexpr round(\xintFloatSqrt [20]{2},19)+round(\xintFloatSqrt [20]{3},19)\relax -(the second argument of |round| and |trunc| tells how many digits from after the -decimal mark one should keep.) -\end{everbatim*} + -The whole point of \csbxint{iiexpr} is to gain some speed in -\emph{integer-only} algorithms, and the above explanations related to how to -nevertheless use fractions therein are a bit peripheral. We observed -(2013/12/18) of the order of $30$\% speed gain when dealing with numbers with -circa one hundred digits (1.2: this info may be obsolete). -\subsection{\csh{xintboolexpr}, \csh{xinttheboolexpr}} -\label{xintboolexpr}\label{xinttheboolexpr}\label{thexintboolexpr} -Equivalent\etype{x} to doing |\xintexpr ...\relax| and returning $True$ if the -result does not vanish, and $False$ if the result is zero. As |\xintexpr|, this -can be used on comma separated lists of expressions, and even bracketed lists. -\CHANGED{1.4} +\begin{framed} + The |IEEE 754|\footnotemark\ requirement of \emph{correct rounding} for + addition, subtraction, multiplication, division and square root is achieved + (in arbitrary precision) by the macros of \xintfracname hence also by the + infix operators |+|, |-|, |*|, |/|. -It can be customized, one only needs to modify the following: -\begin{everbatim} -\def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{True}{False}}% -\end{everbatim} -Not only are |True| and |False| usable in input, also |true| and |false| are -pre-declared variables. + This means that for operands given with at most |P| significant digits + (and arbitrary exponents) the output coincides exactly with the rounding + of the exact theoretical result (barring overflow or underflow). -Maybe obsolete: -There is slight quirk in case it is used as a sub-expression: the boolean -expression needs at least one logic operation else the value is not -standardized to |1| or |0|, for example we get from -\begin{everbatim*} -\xinttheexpr \xintboolexpr 1.23\relax\relax\newline -\end{everbatim*}which is to be compared with -\begin{everbatim*} -\xinttheboolexpr 1.23\relax -\end{everbatim*} +{\footnotesize Due to a typographical oversight, this documentation + (up to |1.2j|) adjoined |^| and |**| to the above list of + infix operators. But as + is explained in \autoref{xintFloatPower}, what is guaranteed regarding + integer powers is an error of at most |0.52ulp|, not the correct rounding. + Half-integer powers are computed as square roots of integer powers.\par }% -% A related issue existed with -% |\xinttheexpr \xintiexpr 1.23\relax\relax|, which was fixed with |1.1| -% release, and I decided back then not to add the needed overhead also to the -% |\xintboolexpr| context, as one only needs to use |?(1.23)| for example or -% involve the |1.23| in any logic operation like |1.23 'and' 3.45|, or involve -% the |\xintboolexpr ..\relax | itself with any logical operation, contrarily to -% the sub-|\xintiexpr| case where |\xinttheexpr 1+\xintiexpr 1.23\relax\relax| -% did behave contrarily to expectations until |1.1|. + The rounding mode is ``round to nearest, ties away from zero''. + It is not customizable. + Currently \xintfracname has no notion of |NaN|s or signed infinities or signed + zeroes, but this is intended for the future. +\end{framed} +% +\footnotetext{The |IEEE 754-1985| standard was for hardware implementations of + binary floating-point arithmetic with a specific value for the precision + ($24$ bits for single precision, $53$ bits for double precision). The newer + {\texttt{IEEE 754-2008}} + (\url{https://en.wikipedia.org/wiki/IEEE_floating_point}) normalizes five + basic formats, three binaries and two decimals ($16$ and $34$ decimal + digits) and discusses extended formats with higher precision. These + standards are only indirectly relevant to libraries like \xintname dealing + with arbitrary precision.% +} -\subsection{\csh{xintfloatexpr}, - \csh{xintthefloatexpr}} -\label{xintfloatexpr}\label{xintthefloatexpr}\label{thexintfloatexpr} -\csbxint{floatexpr}|...\relax|\etype{x} is exactly like |\xintexpr...\relax| -but with the four binary operations and the power function are mapped to -\csa{xintFloatAdd}, \csa{xintFloatSub}, \csa{xintFloatMul}, \csa{xintFloatDiv} -and \csa{xintFloatPower}, respectively.\footnote{Since |1.2f| the \string^ - handles half-integer exponents, contrarily to \csa{xintFloatPower}.} +Since release +|1.2f|, square root extraction achieves correct rounding in arbitrary +precision. -The target precision for the computation is from the -current setting of |\xintDigits|. Comma separated lists of expressions are -allowed. +The power +function in the expression parsers accepts integer exponents and also +half-integer exponents for float expressions.\footnote{Half-integer exponents + work inside expressions, but not via the \csbxint{FloatPower} macro.} +A preliminary implementation of fractional powers is available see +\xintlogname. Trigonometrical functions are available (\xinttrigname). -An optional parameter within brackets is allowed: -\begin{itemize} -\item if positive it instructs the macro to round the result to that many - digits of precision. It thus makes sense to employ it only if this parameter is - less than the \csbxint{theDigits} precision. -\item if negative it means to trim off that many digits (of course, in the - sense of rounding - the values to shorter mantissas). Don't use it to trim all digits (or more than all)! -\end{itemize} -Since |1.2f| all float operations first round their arguments; a parsed number -is not rounded prior to its use as operand to such a float operation. +The maximal floating point decimal exponent is currently +\dtt{\number"7FFFFFFF} which is the maximal number handled by \TeX. The +minimal exponent is its opposite. But this means that overflow or underflow +are detected only via low-level |\numexpr| arithmetic overflows which are +basically un-recoverable. Besides there are some border effects as the +routines need to add or subtract lengths of numbers from exponents, possibly +triggering the low-level overflows. In the future not only the Precision but +also the maximal and minimal exponents |Emin| and |Emax| will be specifiable +by the user. -|\thexintfloatexpr| is synonym to |\xintthefloatexpr|. +Since |1.2f|, the float macros round their inputs to the target precision |P| +before further processing. Formerly, the initial rounding was done to |P+2| +digits (and at least |P+3| for the power operation.) -|\xintDigits:=36\relax|\xintDigits:=36\relax -% -\leftedline{|\xintthefloatexpr - (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax|} -% -\leftedline{\dtt{\xintthefloatexpr - (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax}} -% 0.00564487459334466559166166079096852897 +The more ambitious model would be for the computing macros to obey the +intrinsic precision of their inputs, i.e. to compute the correct rounding to +|P| digits of the exact mathematical result corresponding to inputs allowed to +have their own higher precision.% % -\leftedline{|\xintthefloatexpr\xintexpr - (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax\relax|} +\footnote{The |MPFR| library + \url{http://www.mpfr.org/} implements this but it does not know fractions!} % -\leftedline{\dtt{\xintthefloatexpr\xintexpr - (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax\relax}} +This would be feasible by \xintfracname which after all knows how to compute +exactly, but I have for the time being decided that for reasons of efficiency, +the chosen model is the one of rounding inputs to the target precision first. -\xintDigits := 16; +The float macros of \xintfracname have to handle inputs which +not only may have much more digits than the target float precision, but may +even be fractions: in a way this means infinite precision. -The latter is the rounding of the exact result. The former one has -its last three digits wrong due to the cumulative effect of rounding errors -in the intermediate computations, as compared to exact evaluations. +From releases |1.08a| to |1.2j| a fraction input $AeM/BeN$ had its numerator +and denominator $A$ and $B$ truncated to |Q+2| digits of precision, then the +substituted fraction was correctly rounded to |Q| digits of precision (usually +with |Q| set to |P+2|) and then the operation was implemented on such rounded +inputs. But this meant that two fractions representing the same rational +number could end up being rounded differently (with a difference of one unit +in the last place), if it had numerators and denominators with at least |Q+3| +digits. +Starting with release |1.2k| a fractional input $AeM/BeN$ is handled +intrinsically: the fraction, independently of its representation $AeM/BeN$, is +\emph{correctly rounded} to |P| digits during the input parsing. Hence the +output depends only on its arguments as mathematical fractions and not on +their representatives as quotients. +Notice that in float expressions, the |/| is treated as operator, and is +applied to arguments which are generally already |P|-floats, hence the above +discussion becomes relevant in this context only for the special input form +|qfloat(A/B)| or when using a sub-expression |\xintexpr A/B\relax| embedded in +the float expression with |A| or |B| having more digits than the prevailing +float precision |P|. -I recall here from \autoref{ssec:floatingpoint} that with release |1.2f| the -float macros for addition, subtraction, multiplication and division round -their arguments first to |P| significant places with |P| the asked-for -precision of the output; and similarly the power macros and the -square root macro. This does not modify anything for computations with -arguments having at most |P| significant places already. -\subsection{\csh{xinteval}, \csh{xintieval}, \csh{xintiieval}, - \csh{xintfloateval}} -\label{xinteval}\label{xintieval}\label{xintiieval}\label{xintfloateval} -\csbxint{eval}\etype{x} is an \fexpan dable macro which is basically defined -like this (DON'T BELIEVE THIS; it has been entirely revamped at |1.4|): -\begin{everbatim} -\def\xinteval#1{\romannumeral-`0\xinttheexpr#1\relax}% OLD DEFINITION < 1.4 -\end{everbatim} -thus expands in two steps (its exact definition differs from the one given -above in order to achieve a slight optimization). -\begin{everbatim*} -\xinteval{add(x^2, x = 100..110), add(x^3, x = 100..110)} -\end{everbatim*} -\csbxint{ieval}\etype{x} is similarly related to \csbxint{theiexpr}. Its optional -argument must be located inside the braces: -\begin{everbatim*} -\xintieval{[7] 355/113} -\end{everbatim*} -\csbxint{iieval}\etype{x} is similarly related to \csbxint{theiiexpr}. -\begin{everbatim*} -\xintiieval{add(x^2, x = 100..110), add(x^3, x = 100..110)} -\end{everbatim*} +\subsection{Expansion matters} -\csbxint{floateval}\etype{x} is similarly related to \csbxint{thefloatexpr}. Its optional -argument must be located inside the braces: -\begin{everbatim*} -\xintfloateval{[7] 355/113} -\end{everbatim*} - -When negative it tells how many digits to remove from the prevailing precision -(\csbxint{theDigits}): -\begin{everbatim*} -\xintfloateval{[-2] 355/113} has \xinttheDigits\ minus 2 digits. -\end{everbatim*} +\subsubsection{Full expansion of the first token} +\label{ssec:expansions} -These macros are useful when one uses some extra wrapper doing some parsing of -its input, like the |\num| macro of -\href{http://ctan.org/pkg/siunitx}{siunitx}, which would choke on some of the -syntax elements allowed inside \csb{xintexpr}|...\relax| (for example -brackets). -As shown in the above examples, these macros, like the underlying parsers -accept arbitrarily many comma separated expressions. +The whole business of \xintname is to build upon |\numexpr| and handle +arbitrarily large numbers. Each basic operation is thus done via a macro: +\csbxint{iiAdd}, \csbxint{iiSub}, \csbxint{iiMul}, \csbxint{iiDivision}. In +order to handle more complex operations, it must be possible to nest these +macros. +% +An expandable macro can not execute a |\def| or an |\edef|. But the macro must +expand its arguments to find the digits it is supposed to manipulate. \TeX{} +provides a tool to do the job of (expandable !) repeated expansion of the +first token found until hitting something non expandable, such as a digit, a +|\def| token, a brace, a |\count| token, etc... is found. A space token also +will stop the expansion (and be swallowed, contrarily to the non-expandable +tokens). +By convention in this manual \fexpan sion (``full expansion'' or ``full first +expansion'') will be this \TeX{} process of expanding repeatedly the first +token seen. For those familiar with \LaTeX3 (which is not used by \xintname) +this is what is called in its documentation full expansion (whereas expansion +inside |\edef| would be described I think as ``exhaustive'' expansion). -\subsection{Using an expression parser within another one} +Most of the package macros, and all those dealing with computations% +% +\footnote{except \csbxint{XTrunc}.}, +% +are expandable in the strong sense that they expand to their final result via +this \fexpan sion. This will be signaled in their descriptions via a +\etype{}star in the margin. -This was already illustrated before. In the following: -\begin{everbatim*} -\xintfloatexpr \xintexpr add(1/i, i=1234..1243)\relax ^100\relax -\end{everbatim*}, -the inner sum is computed exactly. Then it will be rounded to |\xinttheDigits| -significant digits, and then its power will be evaluated as a float operation. -One should avoid the "|\xintthe|" parsers in inner positions as this induces -digit by digit parsing of the inner computation result by the outer parser. -Here is the same computation done with floats all the way: -\begin{everbatim*} -\xintfloatexpr add(1/i, i=1234..1243)^100\relax -\end{everbatim*} +These macros not only have this property of \fexpan dability, they all begin +by first applying \fexpan sion to their arguments. Again from \LaTeX3's +conventions this will be signaled by a% +% +\ntype{{\setbox0 \hbox{\Ff}\hbox to \wd0 {\hss f\hss}}} +% +margin annotation next to the description of the arguments. -Not surprisingly this differs from the previous one which was exact until -raising to the |100|th power. +\subsubsection{Summary of important expandability aspects} -The fact that the inner expression occurs inside a bigger one has nil -influence on its behaviour. There is the limitation though that the outputs -from \csbxint{expr} and \csbxint{floatexpr} can not be used directly in -\csbxint{theiiexpr} integer-only parser. But one can do: -\begin{everbatim*} -\xintiiexpr round(\xintfloatexpr 3.14^10\relax)\relax % or trunc -\end{everbatim*} +\begin{enumerate} +\item the macros \fexpan d their arguments, this means that they expand the + first token seen (for each argument), then expand, etc..., until something + un-expandable such as a\strut{} digit or a brace is hit against. This + example +% + \leftedline{|\def\x{98765}\def\y{43210}| |\xintiiAdd {\x}{\x\y}|} +% + is \emph{not} a legal construct, as the |\y| will remain untouched by + expansion and not get converted into the digits which are expected by the + sub-routines of |\xintiiAdd|. It is a |\numexpr| which will expand it and an + arithmetic overflow will arise as |9876543210| exceeds the \TeX{} bounds. + The same would hold for |\xintAdd|. + \begingroup\slshape + To the contrary \csbxint{theiiexpr} and others have no issues with + things such as |\xinttheiiexpr \x+\x\y\relax|.\hfill + \endgroup -\subsection{The \csh{xintthecoords} macro} -\label{xintthecoords} +\item\label{fn:expansions} using |\if...\fi| constructs \emph{inside} the + package macro arguments requires suitably mastering \TeX niques + (|\expandafter|'s and/or swapping techniques) to ensure that the \fexpan sion + will indeed absorb the \csa{else} or closing \csa{fi}, else some error will + arise in further processing. Therefore it is highly recommended to use the + package provided conditionals such as \csbxint{ifEq}, \csbxint{ifGt}, + \csbxint{ifSgn},\dots\ or, for \LaTeX{} users and when dealing + with short integers the + \href{https://ctan.org/pkg/etoolbox}{etoolbox}% +% +\footnote{\url{https://ctan.org/pkg/etoolbox}} + expandable conditionals (for small integers only) such as \texttt{\char92 + ifnumequal}, \texttt{\char92 ifnumgreater}, \dots . Use of + \emph{non-expandable} things such as \csa{ifthenelse} is impossible inside the + arguments of \xintname macros. -It converts a comma separated list into the format for list of coordinates as -expected by the |TikZ| |coordinates| syntax.% + \begingroup\slshape + One can use naive |\if..\fi| things inside an \csbxint{theexpr}-ession + and cousins, as long as the test is + expandable, for example\upshape % -\footnote{The implementation had to work around the -problem that |TikZ| seemingly allows only a maximal number of about one -hundred expansion steps for the list to be entirely produced.}% +\leftedline{|\xinttheiexpr\ifnum3>2 143\else 33\fi + 0^2\relax|$\to$\dtt{\xinttheiexpr \ifnum3>2 143\else 33\fi 0^2\relax + =1430\char`\^2}} % -\begin{everbatim*} -\begin{figure}[htbp] -\centering\begin{tikzpicture}[scale=10]\xintDigits:=8\relax - \clip (-1.1,-.25) rectangle (.3,.25); - \draw [blue] (-1.1,0)--(1,0); - \draw [blue] (0,-1)--(0,+1); - \draw [red] plot[smooth] coordinates {% -%%% (\xintthecoords converts output of next expression into (x1, y1) (x2, y2)... format) - \xintthecoords\xintfloatexpr -%%% This syntax -1+[0..4]/2 is currenty dropped at xint 1.4 -%%% seq((x^2-1,mul(x-t,t=-1+[0..4]/2)),x=-1.2..[0.1]..+1.2)\relax -%%% Use this: - seq((x^2-1,mul(x-t,t=seq(-1+u/2, u=0..4))),x=-1.2..[0.1]..+1.2) - \relax - }; -\end{tikzpicture} -\caption{Coordinates with \cs{xintthecoords}.} -\end{figure} -\end{everbatim*} - -% Notice: if x goes no take exactly value 1 or -1, the origin appears slightly -% off the curve, not MY fault!!! - -As examplified above, \csbxint{thecoords} is to be used followed immediately -by either \csbxint{floatexpr} or \csbxint{iexpr} or \csbxint{iiexpr}. + \endgroup +\item after the definition |\def\x {12}|, one can not use + {\color{blue}|-\x|} as input to one of the package macros: the \fexpan sion + will act only on the minus sign, hence do nothing. The only way is to use the + \csbxint{Opp} macro (or \csbxint{iiOpp} which is integer only) + which obtains the opposite of a given number. -The next\IMPORTANT{} -paragraph is probably obsoleted by |1.4| as |\xintexpr| does use -scienttific notation on output however with a possible denominator. + \begingroup\slshape + Again, this is otherwise inside an \csbxint{theexpr}-ession or + \csbxint{thefloatexpr}-ession. There, the + minus sign may prefix macros which will expand to numbers (or parentheses + etc...) + \endgroup -As |TikZ| will not understand the |A/B[N]| format which is used on output by -|\xintexpr|, |\xintthecoords\xintexpr| has no use inside a |TikZ| picture but -may have other usages; the reason for the spaces in output is to allow if -necessary to print on the page for examination and give \TeX\ a change to -establish line-breaks. +\def\x {12}% +\def\AplusBC #1#2#3{\xintAdd {#1}{\xintMul {#2}{#3}}}% -\begin{everbatim*} -\edef\x{\xintthecoords \xintexpr rrseq(1/2,1/3; @1+@2, x=1..20)\relax } -\meaning\x +++ -\end{everbatim*} +\item \label{item:xpxp} With the definition +% +\leftedline{|\def\AplusBC #1#2#3{\xintAdd {#1}{\xintMul {#2}{#3}}}|} +% +one obtains an + expandable macro producing the expected result, not in two, but rather in + three steps: a first expansion is consumed by the macro expanding to its + definition. As the package macros expand their arguments until no more is + possible (regarding what comes first), this |\AplusBC| may be used inside + them: {|\xintAdd {\AplusBC {1}{2}{3}}{4}|} does work and returns + \dtt{\xintAdd {\AplusBC {1}{2}{3}}{4}}. -\subsection{\csh{xintifboolexpr}, \csh{xintifboolfloatexpr}, \csh{xintifbooliiexpr}} -\label{xintifboolexpr} -\label{xintifboolfloatexpr} -\label{xintifbooliiexpr} + If, for some reason, it is important to create a macro expanding in two steps + to its final value, one may either do: +% +\smallskip +% +\leftedline {|\def\AplusBC #1#2#3{\romannumeral-`0\xintAdd {#1}{\xintMul + {#2}{#3}}}|} +% +or use the \emph{lowercase} form of \csa{xintAdd}: +% +\smallskip +% +\leftedline {|\def\AplusBC #1#2#3{\romannumeral0\xintadd {#1}{\xintMul + {#2}{#3}}}|} -\csh{xintifboolexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does -\csbxint{theexpr}|\relax| and then executes the \meta{YES} or the -\meta{NO} branch depending on whether the outcome was non-zero or zero. Thus -one can read \emph{if bool expr} as meaning \emph{if not zero}: -\centeredline{if \meta{expr}-ession does not vanish do \meta{YES} else do - \meta{NO}} + and then \csa{AplusBC} will share the same properties as do the + other \xintname `primitive' macros. -The expression is not limited to using only comparison operators and Boolean -logic (|<|, |>|, |==|, |!=|, |&&|, \verb+||+, \func{all}, \func{any}, -\func{xor}, \func{bool}, \func{togl}, ...), it can be the most general -computation. +\item +The |\romannumeral0| and |\romannumeral-`0| things above look like an invitation +to hacker's territory; if it is not important that the macro expands in two +steps only, there is no reason to follow these guidelines. Just chain +arbitrarily the package macros, and the new ones will be completely expandable +and usable one within the other. -\csh{xintifboolfloatexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does -\csbxint{thefloatexpr}\meta{expr}|\relax| and then executes the \meta{YES} or the -\meta{NO} branch depending on whether the outcome was non zero or zero. +Since release |1.07| the \csbxint{NewExpr} macro automatizes the creation of +such expandable macros: +% +\leftedline{|\xintNewExpr\AplusBC[3]{#1+#2*#3}|} +% +creates the |\AplusBC| macro doing the above and expanding in two expansion +steps. -\csh{xintifbooliiexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does -\csbxint{theiiexpr}\meta{expr}|\relax| and then executes the \meta{YES} or the -\meta{NO} branch depending on whether the outcome was non zero or zero. +\item In the expression parsers of \xintexprname such as + \csbxint{expr}|..\relax|, \csbxint{floatexpr}|..\relax| the contents are + expanded completely from left to right until the ending |\relax| is found + and swallowed, and spaces and even (to some extent) catcodes do not matter. -The expression argument must be a single one, comma separated sub-expressions -will cause low-level errors. +\item For all variants, prefixing with \csbxint{the} allows to print the + result or use it in other contexts. Shortcuts \csbxint{theexpr}, + \csbxint{thefloatexpr}, \csbxint{theiiexpr}, \dots\ are available. -\subsection{\csh{xintifsgnexpr}, \csh{xintifsgnfloatexpr}, \csh{xintifsgniiexpr}} -\label{xintifsgnexpr} -\label{xintifsgnfloatexpr} -\label{xintifsgniiexpr} +\end{enumerate} -\csh{xintifsgnexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates -the \csbxint{expr}ession and chooses the branch corresponding to its sign. +\subsection {Input formats for macros}\label{ssec:inputs} -\csh{xintifsgnfloatexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates -the \csbxint{floatexpr}ession and chooses the branch corresponding to its sign. +Macros can have different types of arguments (we do not consider here the +\csbxint{expr}-parsers but only the macros of +\xintcorename/\xintname/\xintfracname). In a macro description, a +margin annotation signals what is the argument type. +\begin{enumerate} +\item \TeX\ integers\ntype{\numx} are handled inside a |\numexpr..\relax| + hence may be count registers or variables. Beware that |-(1+1)| is not legal + and raises an error, but |0-(1+1)| is. Also |2\cnta| with |\cnta| a |\count| + isn't legal. Integers must be kept less than \dtt{\number "7FFFFFFF} in + absolute value, although the \emph{scaling} operation |(a*b)/c| computes the + intermediate product with twice as many bits. -\csh{xintifsgniiexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates -the \csbxint{iiexpr}ession and chooses the branch corresponding to its sign. + The slash |/| does a \fbox{rounded} division which is a fact of life of + |\numexpr| which I have found very annoying in at least nine cases out of + ten, not to say ninety-nine cases out of one hundred. Besides, it is at odds + with \TeX's |\divide| which does a truncated division (non-expandably). -The expression argument must be a single one, comma separated sub-expressions -will cause low-level errors. + But to follow-suit |/| also does rounded integer division in + \csbxint{iiexpr}|..\relax|, and the operator |//| does there the truncated + division. -\subsection{The \csh{xintNewExpr}, \csh{xintNewIIExpr}, - \csh{xintNewFloatExpr}, \csh{xintNewIExpr}, and \csh{xintNewBoolExpr} - macros} -\label{xintNewExpr} -\label{xintNewIIExpr} -\label{xintNewFloatExpr} -\label{xintNewIExpr} -\label{xintNewBoolExpr} +\item the strict format\ntype{f} applies to macros handling big integers but + only \fexpan ding their arguments. After this \fexpan sion the input should + be a string of digits, optionally preceded by a unique minus sign. The first + digit can be zero only if it is the only digit. A plus sign is not accepted. + |-0| is not legal in the strict format. Macros of \xintname with a double + |ii| require this `strict' format for the inputs. -\csbxint{NewExpr} macro is used as: -% -\leftedline{|\xintNewExpr{\myformula}[n]|\marg{stuff}, where} -\begin{itemize} -\item \meta{stuff} will be inserted inside |\xinttheexpr . . . \relax|, -\item |n| is an integer between zero and nine, inclusive, which is the number - of parameters of |\myformula|, -\item the placeholders |#1|, |#2|, ..., |#n| are used inside \meta{stuff} in - their usual r\^ole,% -% -\catcode`# 12 -\footnote{if \csa{xintNewExpr} is used inside a macro, - the |#|'s must be doubled as usual.} - \footnote{the |#|'s will in pratice have their usual - catcode, but category code other |#|'s are accepted too.} -\catcode`# 6 -% -\item the |[n]| is \emph{mandatory}, even for |n=0|.% -\footnote{there is some use for \csa{xintNewExpr}|[0]| compared to an - \csa{edef} as \csa{xintNewExpr} has some built-in catcode protection.} -\item the macro |\myformula| is defined without checking if it already exists, - \LaTeX{} users might prefer to do first |\newcommand*\myformula {}| to get a - reasonable error message in case |\myformula| already exists, -\item the protection against active characters is done automatically (as long - as the whole thing has not already been fetched as a macro argument and - the catcodes correspondingly already frozen). -\end{itemize} +\item the extended integer format\ntype{\Numf} applies when the macro parses + its arguments via \csbxint{Num}. The input may then have arbitrarily many + leading minus and plus signs, followed by leading zeroes, and further + digits. With \xintfracname loaded, \csbxint{Num} is extended to + accept fractions and its action is to truncate them to integers. -It (if it succeeds) will be a completely expandable macro entirely built-up using |\xintAdd|, -|\xintSub|, |\xintMul|, |\xintDiv|, |\xintPow|, etc\dots as corresponds to the -expression written with the infix operators. -Macros created by |\xintNewExpr| can thus be nested. + At |1.2o| many macros from \xintcorename/\xintname which + used. All these macros have now been removed at |1.3|. +\item the fraction input format\ntype{\Ff} applies to the arguments of + \xintfracname macros handling genuine fractions. It allows two types + of inputs: general and restricted. The restricted type is parsed faster, + but... is restricted. + \begin{description} + \item[general:] inputs of the shape |A.BeC/D.EeF|. Example: \begin{everbatim*} - \xintNewFloatExpr \FA [2]{(#1+#2)^10} - \xintNewFloatExpr \FB [2]{sqrt(#1*#2)} -\begin{enumerate}[nosep] - \item \FA {5}{5} - \item \FB {30}{10} - \item \FA {\FB {30}{10}}{\FB {40}{20}} -\end{enumerate} +\noindent\xintRaw{+--0367.8920280e17/-++278.289287e-15}\newline +\xintRaw{+--+1253.2782e++--3/---0087.123e---5}\par +\end{everbatim*} + The input parser does not reduce fractions to smallest terms. + Here are the rules of this general fraction format: + \begin{itemize} + \item everything is optional, absent numbers are treated as zero, here are + some extreme cases: +\begin{everbatim*} +\xintRaw{}, \xintRaw{.}, \xintRaw{./1.e}, \xintRaw{-.e}, \xintRaw{e/-1} \end{everbatim*} + \item |AB| and |DE| may start with pluses and minuses, then leading + zeroes, then digits. + \item |C| and |F| will be given to |\numexpr| and can be anything + recognized as such and not provoking arithmetic overflow (the lengths of + |B| and |E| will also intervene to build the final exponent naturally + which must obey the \TeX{} bound). + \item the |/|, |.| (numerator and/or denominator) and |e| + (numerator and/or denominator) are all optional components. + \item each of |A|, |B|, |C|, |D|, |E| and |F| may arise from \fexpan sion + of a macro. + \item the whole thing may arise from \fexpan sion, however the |/|, |.|, + and |e| should all come from this initial expansion. The |e| of + scientific notation is mandatorily lowercased. + \end{itemize} + \item[restricted:] inputs either of the shape |A[N]| or |A/B[N]|, which + represents the fraction |A/B| times |10^N|. The whole thing or + each of |A|, |B|, |N| (but then not |/| or |[|) may arise from \fexpan + sion, |A| (after expansion) \emph{must} have a unique optional minus sign + and no leading zeroes, |B| (after expansion) if present \emph{must} be a + positive integer with no signs and no leading zeroes, |[N]| if present + will be given to |\numexpr|. Any deviation from the rules above will + result in errors. + \end{description} + Notice that |*|, |+| and |-| contrarily to the |/| (which is treated simply + as a kind of delimiter) are not acceptable within arguments of this + type\ntype{\Ff} (see \autoref{sec:useofcount} + for some exceptions to this.) +\end{enumerate} -The documentation is much shortened here because \csbxint{NewExpr} and \csbxint{deffunc} -are very much related one with the other. +Generally speaking, there should be no spaces among the digits in the inputs +(in arguments to the package macros). Although most would be harmless in most +macros, there are some cases where spaces could break havoc.% +\footnote{The \csbxint{Num} macro does not remove spaces between digits beyond + the first non zero ones; however this should not really alter the subsequent + functioning of the arithmetic macros, and besides, since \xintcorename 1.2 + there is an initial parsing of the entire number, during which spaces will + be gobbled. However I have not done a complete review of the legacy code to + be certain of all possibilities after |1.2| release. One thing to be aware + of is that \csa{numexpr} stops on spaces between digits (although it + provokes an expansion to see if an infix operator follows); the exponent for + \csbxint{iiPow} or the argument of the factorial \csbxint{iiFac} are only + subjected to such a \csa{numexpr} (there are a few other macros with such + input types in \xintname). If the input is given as, say |1 2\x| where + \csa{x} is a macro, the macro \csa{x} will not be expanded by the + \csa{numexpr}, and this will surely cause problems afterwards. Perhaps a + later \xintname will force \csa{numexpr} to expand beyond spaces, but I + decided that was not really worth the effort. Another immediate cause of + problems is an input of the type |\xintiiAdd{\x}{\y}|, because the + space will stop the initial expansion; this will most certainly cause an + arithmetic overflow later when the \csa{x} will be expanded in a + \csa{numexpr}. Thus in conclusion, damages due to spaces are unlikely if + only explicit digits are involved in the inputs, or arguments are single + macros with no preceding space.} +So the best is to avoid them entirely. -\begin{framed} - ATTENTION! +This is entirely otherwise inside an |\xintexpr|-ession, where spaces are +ignored (except when they occur inside arguments to some macros, thus +escaping the |\xintexpr| parser). See the \autoref{sec:expr}. - The original spirit of \csbxint{NewExpr} was to define a (possibly very big) - macro using only \xintfracname, and this means in particular that it must be - used only with arguments compatible with the \xintfracname input - format.\IMPORTANTf +There are also some slighly more obscure expansion types: in particular, the +\csbxint{ApplyInline} and \csbxint{For*} macros from \xinttoolsname apply a +special iterated \fexpan sion, which gobbles spaces, to the non-braced items +(braced items are submitted to no expansion because the opening brace stops +it) coming from their list argument; this is denoted by a special +symbol\ntype{{\lowast f}} in the margin. Some other macros such as +\csbxint{Sum} from \xintfracname first do an \fexpan sion, then treat each +found (braced or not) item (skipping spaces between such items) via the +general fraction input parsing, this is signaled as +here\ntype{f{$\to$}{\lowast\Ff}} in the margin where the signification of the +\lowast{} is thus a bit different from the previous case. - Thus an |\xintexpr| declared variable has no chance to work, it must be - wrapped explicitly in |\xinteval{...}| to be fetched as argument to a macro - constructed by \csbxint{NewExpr}. -\end{framed} +A few macros from \xinttoolsname do not expand, or expand only once their +argument\ntype{n{{\color{black}\upshape, resp.}} o}. This is also +signaled in the margin with notations \`a la \LaTeX3. -They share essentially the same limitations. -Notice though that \csbxint{NewFloatExpr} accepts and recognizes the optional -argument |[Q]| of \csbxint{floatexpr}, contrarily to \csbxint{deffloatfunc}. -Use an |\empty| in case the contents are not known in advance. +\subsection{Output formats of macros} +\label{ssec:outputs} +We do not consider here the \csbxint{expr}-parsers but only the macros from \xintcorename, \xintname and \xintfracname. Macros of other +components of the bundle may have their own output formats, for example for +continuous fractions with \xintcfracname. +There are mainly three types of outputs:% -Historical note: prior to |1.4|, \xintexprname used a |\csname..\endcsname| -encapsulation technique which impacted the string pool memory. The -\csbxint{NewExpr} was designed as a method to pre-parse the expression and -produce one single, gigantic, nested usage of the relevant \xintfracname -macros. This way, only those macros were expanded which had nil impact on the -\TeX{} string pool. +\begin{itemize}[nosep,listparindent=\leftmarginiii] +\item arithmetic macros from \xintcorename/\xintname deliver integers + in the strict format as described in the previous section. +\item arithmetic macros from \xintfracname produce on output the strict +fraction format |A/B[N]|, which stands for |(A/B)|$\times$|10^N|, where |A| +and |B| are integers, |B| is positive, and |N| is a ``short'' integer. The +output is not reduced to smallest terms. The |A| and |B| may end with zeroes +(\emph{i.e}, |N| does not represent all powers of ten). The denominator |B| is +always strictly positive. There is no |+| sign. The |-| is always first if +present (i.e. the denominator on output is always positive.) The output will +be expressed as such a fraction even if the inputs are both integers and the +mathematical result is an integer. The |B=1| is not removed.% +% +\footnote{refer to the documentation of \csbxint{PRaw} for an alternative.} +\item macros with |Float| in their names produce on output scientific +format with |P=|\nobreak\csbxint{theDigits} digits, a lowercase |e| and an +exponent |N|. The first digit is not zero, it is preceded by an optional minus +sign and is followed by a dot and |P-1| digits. Trailing zeroes are not +trimmed. There is one exceptional case: +\begin{itemize}[nosep] +\item if the value is mathematically zero, it is output as |0.e0|, + i.e. zeros after the decimal mark are removed and the exponent is always |0|. +\end{itemize} +Future versions of the package may modify this. +\end{itemize} -Later on it was found that this mechanism could be employed to define -functions. Basically underneath |98%| of \csbxint{NewExpr} and -\csbxint{deffunc} are using the same shared code. -\xintDigits:= 16\relax +\subsection{Count registers and variables}\label{sec:useofcount} -\subsection{Analogies and differences of \csh{xintiiexpr} with \csh{numexpr}} +Inside |\xintexpr..\relax| and its variants, a count register or count control +sequence is automatically unpacked using |\number|, with tacit multiplication: +|1.23\counta| is like |1.23*\number\counta|. There +is a subtle difference between count \emph{registers} and count +\emph{variables}. In |1.23*\counta| the unpacked |\counta| variable defines a +complete operand thus |1.23*\counta 7| is a syntax error. But |1.23*\count0| +just replaces |\count0| by |\number\count0| hence |1.23*\count0 7| is like +|1.23*57| if |\count0| contains the integer value |5|. -\csbxint{iiexpr}|..\relax| is a parser of expressions knowing only (big) -integers. There are, besides the enlarged range of allowable inputs, some -important differences of syntax between |\numexpr| and |\xintiiexpr| and -variants: -\begin{itemize} -\item Contrarily to |\numexpr|, the |\xintiiexpr| parser will stop expanding - only after having encountered (and swallowed) a \emph{mandatory} |\relax| - token. -\item In particular, spaces between digits (and not only around infix - operators or parentheses) do not stop |\xintiiexpr|, contrarily to the - situation with |numexpr|: |\the\numexpr 7 + 3 5\relax| expands (in one - step)% +Regarding now the package macros, there is first the case of arguments having to +be short integers: this means that they are fed to a |\numexpr...\relax|, hence +submitted to a \emph{complete expansion} which must deliver an integer, and +count registers and even algebraic expressions with them like +|\mycountA+\mycountB*17-\mycountC/12+\mycountD| are admissible arguments (the +slash stands here for the rounded integer division done by |\numexpr|). This +applies in particular to the number of digits to truncate or round with, to the +indices of a series partial sum, \dots + +The macros allowing the extended format for long numbers or dealing with +fractions will \emph{to some extent} allow the direct use of count +registers and even infix algebra inside their arguments: a count +register |\mycountA| or |\count 255| is admissible as numerator or also as +denominator, with no need to be prefixed by |\the| or |\number|. It is possible +to have as argument an algebraic expression as would be acceptable by a +|\numexpr...\relax|, under this condition: \emph{each of the numerator and + denominator is expressed with at most \emph{nine} + tokens}.% % -\footnote {The |\numexpr| triggers continued expansion after the space - following the |3| to check if some operator like |+| is upstream. But - after having found the |5| it treats it as and end-marker.} +\footnote{The |1.2k| and earlier versions manual claimed up to 8 + tokens, but low-level TeX error arose if the |\numexpr...\relax| occupied + exactly 8 tokens \emph{and} evaluated to zero. With |1.2l| and later, up to + 9 tokens are always safe and one may even drop the ending |\relax|. But + well, all these explanations are somewhat silly because prefixing by |\the| + or |\number| is always working with arbitrarily many tokens.} % - to \dtt{\detokenize\expandafter{\the\numexpr 7 + 3 5\relax}\unskip}, whereas - |\xintthe\xintiiexpr 7 + 3 5\relax| expands (in two steps) to - \dtt{\detokenize\expandafter\expandafter\expandafter {\xintthe\xintiiexpr 7 - + 3 5\relax}}.% % -\footnote {Since |1.2l| one can also use the underscore |_| to separate digits -for readability of long numbers.} - -\item Inside an |\edef|, an expression |\xintiiexpr...\relax| get fully - evaluated, whereas |\numexpr| without |\the| or |\number| prefix would not, - if not itself embedded in another |\the\numexpr| or similar context. -\item (ctd.) The private format to which |\xintiiexpr...\relax| (et al.) - evaluates may use |\xintthe| prefix to turn into explicit digits, - (for example in arguments to some macros which expand their arguments). The |\the| \TeX\ primitive prefix would - not work here. -\item (ctd.) One can embed a |\numexpr...\relax| (with its |\relax|!) inside an - |\xintiiexpr...\relax| without |\the| or |\number|, but the reverse situation - requires usage of |\xintthe| or \csbxint{eval} user interface, -\item |\numexpr -(1)\relax| is illegal. In contrast |\xintiiexpr -(1)\relax| is - perfectly legal and gives the expected result (what else ?). -\item |\numexpr 2\cnta\relax| is illegal (with |\cnta| a |\count| register.) - In contrast - |\xintiiexpr 2\cnta\relax| is perfectly legal and will do the tacit - multiplication. -\item |\the\numexpr| or |\number\numexpr| expands in one step, but - |\xintthe\xintiiexpr| or |\xinttheiiexpr| needs two steps. -\end{itemize} +\footnote{Attention! in the \LaTeX{} context a + \csa{value}\texttt{\{countername\}} will behave ok only if it is first in + the input, if not it will not get expanded, and braces around the name will + be removed and chaos\IMPORTANT{} will ensue inside a \csa{numexpr}. One + should enclose the whole input in \csa{the}\csa{numexpr}|...|\csa{relax} in + such cases.} +% +Important: a slash for rounded division in a |\numexpr| should be written with +braces |{/}| to not be confused with the \xintfracname delimiter between +numerator and denominator (braces will be removed internally and the slash +will count for one token). Example: +|\mycountA+\mycountB{/}17/1+\mycountA*\mycountB|, or |\count 0+\count +2{/}17/1+\count 0*\count 2|. +% +\leftedline{|\cnta 10 \cntb 35 \xintRaw + {\cnta+\cntb{/}17/1+\cnta*\cntb}|\dtt{->\cnta 10 \cntb 35 \xintRaw + {\cnta+\cntb{/}17/1+\cnta*\cntb}}} +% +For longer algebraic expressions using +count registers, there are two possibilities: +\begin{enumerate}[nosep] +\item let the numerator and the denominator be presented as |\the\numexpr...\relax|, +\item or as |\numexpr {...}\relax| (the braces are removed during processing; + they are not legal for |\numexpr...\relax| syntax.) +\end{enumerate} +\everb|@ +\cnta 100 \cntb 10 \cntc 1 +\xintPRaw {\numexpr {\cnta*\cnta+\cntb*\cntb+\cntc*\cntc+ + 2*\cnta*\cntb+2*\cnta*\cntc+2*\cntb*\cntc}\relax/% + \numexpr {\cnta*\cnta+\cntb*\cntb+\cntc*\cntc}\relax } +| +\cnta 100 \cntb 10 \cntc 1 +% +\leftedline{\dtt{\xintPRaw {\numexpr + {\cnta*\cnta+\cntb*\cntb+\cntc*\cntc+ + 2*\cnta*\cntb+2*\cnta*\cntc+2*\cntb*\cntc}\relax/% + \numexpr {\cnta*\cnta+\cntb*\cntb+\cntc*\cntc}\relax }}} -\subsection{Chaining expressions for expandable algorithmics} -\label{ssec:fibonacci} +\subsection{Dimension registers and variables} +\label{sec:Dimensions} -We will see in this section how to chain |\xintexpr|-essions with -|\expandafter|'s, like it is possible with |\numexpr|. For this it is -convenient to use |\romannumeral0\xintexpro| which is the once-expanded form of -|\xintexpr|, as we can then chain using only one |\expandafter| each time. +\meta{dimen} variables can be converted into (short) integers suitable for the +\xintname macros by prefixing them with |\number|. This transforms a dimension +into an explicit short integer which is its value in terms of the |sp| unit +($1/65536$\,|pt|). +When |\number| is applied to a \meta{glue} variable, the stretch and shrink +components are lost. -For example, here is the code employed -on the title page to compute (expandably, of course!) the 1250th Fibonacci -number: +For \LaTeX{} users: a length is a \meta{glue} variable, prefixing a +length macro defined by \csa{newlength} with \csa{number} will thus discard +the |plus| and |minus| glue components and return the dimension component as +described above, and usable in the \xintname bundle macros. + +This conversion is done automatically inside an +|\xintexpr|-essions, with tacit multiplication implied if prefixed by some +(integral or decimal) number. + +One may thus compute areas or volumes with no limitations, in units of |sp^2| +respectively |sp^3|, do arithmetic with them, compare them, etc..., and possibly +express some final result back in another unit, with the suitable conversion +factor and a rounding to a given number of decimal places. + +A \hyperref[tableofdimensions]{table of dimensions} illustrates that the +internal values used by \TeX{} do not correspond always to the closest +rounding. For example a millimeter exact value in terms of |sp| units is +\dtt{72.27/10/2.54*65536=\xinttheexpr trunc(72.27/10/2.54*65536,3)\relax ...} +and \TeX{} uses internally \dtt{\number\dimexpr 1mm\relax}|sp| (\TeX{} +truncates to get an integral multiple of the |sp| unit; see at the end of this +section the exact rules applied internally by \TeX). + +\begin{figure*}[ht!] +\phantomsection\label{tableofdimensions} +\begingroup\let\ignorespaces\empty + \let\unskip\empty + \def\T{\expandafter\TT\number\dimexpr} + \def\TT#1!{\gdef\tempT{#1}} + \def\E{\expandafter\expandafter\expandafter + \EE\xintexpr reduce(} + \def\EE#1!{\gdef\tempE{#1}} +\centeredline{\begin{tabular}{% + >{\bfseries\strut}c% + c% + >{\E}c<{)\relax!}@{}% + >{\xintthe\tempE}r@{${}={}$}% + >{\xinttheexpr trunc(\tempE,3)\relax...}l% + >{\T}c<{!}@{}% + >{\tempT}r% + >{\xinttheexpr round(100*(\tempT-\tempE)/\tempE,4)\relax\%}c} + \hline + Unit&% + definition&% + \omit &% + \multicolumn{2}{c}{Exact value in \texttt{sp} units\strut}&% + \omit &% + \omit\parbox{2cm}{\centering\strut\TeX's value in \texttt{sp} units\strut}&% + \omit\parbox{2cm}{\centering\strut Relative error\strut}\\\hline + cm&0.01 m&72.27/2.54*65536&&&1cm&&\\ + mm&0.001 m&72.27/10/2.54*65536&&&1mm&&\\ + in&2.54 cm&72.27*65536&&&1in&&\\ + pc&12 pt&12*65536&&&1pc&&\\ + pt&1/72.27 in&65536&&&1pt&&\\ + bp&1/72 in&72.27*65536/72&&&1bp&&\\ + \omit\hfil\llap{3}bp\strut\hfil&1/24 in&72.27*65536/24&&&3bp&&\\ + \omit\hfil\llap{12}bp\strut\hfil&1/6 in&72.27*65536/6&&&12bp&&\\ + \omit\hfil\llap{72}bp\strut\hfil&1 in&72.27*65536&&&72bp&&\\ + dd&1238/1157 pt&1238/1157*65536&&&1dd&&\\ + \omit\hfil\llap{11}dd\strut\hfil&11*1238/1157 pt&11*1238/1157*65536&&&11dd&&\\ + \omit\hfil\llap{12}dd\strut\hfil&12*1238/1157 pt&12*1238/1157*65536&&&12dd&&\\ + sp&1/65536 pt&1&&&1sp&&\\\hline + \multicolumn{8}{c}{\bfseries\large\TeX{} \strut dimensions}\\\hline +\end{tabular}} +\endgroup +\end{figure*} + +There is something quite amusing with the Didot point. According to the \TeX +Book, $1157$\,|dd|=$1238$\,|pt|. The actual internal value of $1$\,|dd| in \TeX{} is $70124$\,|sp|. We can use \xintcfracname to display the list of +centered convergents of the fraction $70124/65536$: +% +\leftedline{|\xintListWithSep{, }{\xintFtoCCv{70124/65536}}|} +% +\xintFor* #1 in {\xintFtoCCv{70124/65536}}\do {$\printnumber{#1}$, }% +and we don't find +$1238/1157$ therein, but another approximant $1452/1357$! + +And indeed multiplying $70124/65536$ by $1157$, and respectively $1357$, we find +the approximations (wait for more, later): +% +\leftedline{``$1157$\,|dd|''\dtt{=\xinttheexpr trunc(1157\dimexpr + 1dd\relax/\dimexpr 1pt\relax,12)\relax}\dots|pt|} +% +\leftedline{``$1357$\,|dd|''\dtt{=\xinttheexpr trunc(1357\dimexpr + 1dd\relax/\dimexpr 1pt\relax,12)\relax}\dots|pt|} +% +and we seemingly discover that $1357$\,|dd|=$1452$\,|pt| is \emph{far more + accurate} than +the \TeX Book formula $1157$\,|dd|=$1238$\,|pt|~! +The formula to compute $N$\,|dd| was +% +\leftedline{|\xinttheexpr trunc(N\dimexpr 1dd\relax/\dimexpr + 1pt\relax,12)\relax}|} +% + +What's the catch? The catch is that \TeX{} \emph{does not} compute $1157$\,|dd| +like we just did:% +% +\leftedline{$1157$\,|dd|=|\number\dimexpr 1157dd\relax/65536|% + \dtt{=\xintTrunc{12}{\number\dimexpr 1157dd\relax/65536}}\dots|pt|} +% +\leftedline{$1357$\,|dd|=|\number\dimexpr 1357dd\relax/65536|% + \dtt{=\xintTrunc{12}{\number\dimexpr 1357dd\relax/65536}}\dots|pt|} +% +We thus discover that \TeX{} (or rather here, e-\TeX{}, but one can check that +this works the same in \TeX82), uses $1238/1157$ as a conversion +factor (and necessarily intermediate computations simulate higher precision +than a priori available with integers less than $2^{31}$ or rather $2^{30}$ for +dimensions). Hence the $1452/1357$ ratio is irrelevant, an artefact +of the rounding (or rather, as we see, truncating) for one |dd| to be +expressed as an integral number of |sp|'s. +Let us now +use |\xintexpr| to compute the value of the Didot point in millimeters, if +the above rule is exactly verified: +% +\leftedline{|\xinttheexpr + trunc(1238/1157*25.4/72.27,12)\relax|% + \dtt{=\xinttheexpr trunc(1238/1157*25.4/72.27,12)\relax}|...mm|} +% +This fits very well with the possible values of the Didot point as listed in +the +\href{http://en.wikipedia.org/wiki/Point_%28typography%29#Didot}{Wikipedia Article}. +% +The value $0.376065$\,|mm| is said to be \emph{the traditional value in + European printers' offices}. So the $1157$\,|dd|=$1238$\,|pt| rule refers to +this Didot point, or more precisely to the \emph{conversion factor} to be used +between this Didot and \TeX{} points. + +The actual value in millimeters of exactly one Didot point as implemented in +\TeX{} is +% +\leftedline {|\xinttheexpr trunc(\dimexpr + 1dd\relax/65536/72.27*25.4,12)\relax|} +% +\leftedline{\dtt{=\xinttheexpr trunc(\dimexpr + 1dd\relax/65536/72.27*25.4,12)\relax}|...mm|} +% +The difference of circa $5$\AA\ is arguably tiny! + +% 543564351/508000000 + +By the way the \emph{European printers' offices \emph{(dixit Wikipedia)} + Didot} is thus exactly +% +\leftedline{|\xinttheexpr reduce(.376065/(25.4/72.27))\relax|% + \dtt{=\xinttheexpr reduce(.376065/(25.4/72.27))\relax}\,|pt|} +% +and the centered convergents of this fraction are \xintFor* #1 in +{\xintFtoCCv{543564351/508000000}}\do {\dtt{\printnumber{#1}}\xintifForLast{.}{, }} We do +recover the $1238/1157$ therein! + +\begin{framed} + Here is how \TeX\ converts |abc.xyz...|. First the decimal is + \emph{rounded} to the nearest integral multiple of |1/65536|, say |X/65536|. + The || is associated to a ratio |N/D|, which represents |/pt|. + For the Didot point the ratio is indeed |1238/1157|. \TeX\ \emph{truncates} + the fraction |XN/D| to an integer |M|. The dimension is represented by |M + sp|. + +\end{framed} + + +\subsection{\csh{ifcase}, \csh{ifnum}, ... constructs}\label{sec:ifcase} + +When using things such as |\ifcase \xintSgn{\A}| one has to make sure to leave +a space after the closing brace for \TeX{} to +stop its scanning for a number: once \TeX{} has finished expanding +|\xintSgn{\A}| and has so far obtained either |1|, |0|, or |-1|, a +space (or something `unexpandable') must stop it looking for more +digits. Using |\ifcase\xintSgn\A| without the braces is very dangerous, +because the blanks (including the end of line) following |\A| will be +skipped and not serve to stop the number which |\ifcase| is looking for. +% \begin{everbatim*} -\catcode`_ 11 -\def\Fibonacci #1{% \Fibonacci{N} computes F(N) with F(0)=0, F(1)=1. - \expandafter\Fibonacci_a\expandafter - {\the\numexpr #1\expandafter}\expandafter - {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter - {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter - {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter - {\romannumeral0\xintiiexpro 0\relax}} +\begin{enumerate}[nosep]\def\A{1} +\item \ifcase \xintSgn\A 0\or OK\else ERROR\fi +\item \ifcase \xintSgn\A\space 0\or OK\else ERROR\fi +\item \ifcase \xintSgn{\A} 0\or OK\else ERROR\fi +\end{enumerate} +\end{everbatim*} + +In order to use successfully |\if...\fi| constructions either as arguments to +the \xintname bundle expandable macros, or when building up a completely +expandable macro of one's own, one needs some \TeX nical expertise (see also +\autoref{fn:expansions} on page~\pageref{fn:expansions}). + +It is thus much to be recommended to use the expandable branching macros, +provided by \xintfracname succh as \csbxint{ifSgn}, \csbxint{ifZero}, +\csbxint{ifOne}, \csbxint{ifNotZero}, \csbxint{ifTrueAelseB}, \csbxint{ifCmp}, +\csbxint{ifGt}, \csbxint{ifLt}, \csbxint{ifEq}, +\csbxint{ifInt}... See their respective documentations. All these conditionals +always have either two or three branches, and empty brace pairs |{}| for +unused branches should not be forgotten. + +If these tests are to be applied to standard \TeX{} short integers, it is more +efficient to use (under \LaTeX{}) the equivalent conditional tests from the +\href{https://ctan.org/pkg/etoolbox}{etoolbox}% % -\def\Fibonacci_a #1{% - \ifcase #1 - \expandafter\Fibonacci_end_i - \or - \expandafter\Fibonacci_end_ii - \else - \ifodd #1 - \expandafter\expandafter\expandafter\Fibonacci_b_ii - \else - \expandafter\expandafter\expandafter\Fibonacci_b_i - \fi - \fi {#1}% -}% * signs are omitted from the next macros, tacit multiplications -\def\Fibonacci_b_i #1#2#3{\expandafter\Fibonacci_a\expandafter - {\the\numexpr #1/2\expandafter}\expandafter - {\romannumeral0\xintiiexpro sqr(#2)+sqr(#3)\expandafter\relax\expandafter}\expandafter - {\romannumeral0\xintiiexpro (2#2-#3)#3\relax}% -}% end of Fibonacci_b_i -\def\Fibonacci_b_ii #1#2#3#4#5{\expandafter\Fibonacci_a\expandafter - {\the\numexpr (#1-1)/2\expandafter}\expandafter - {\romannumeral0\xintiiexpro sqr(#2)+sqr(#3)\expandafter\relax\expandafter}\expandafter - {\romannumeral0\xintiiexpro (2#2-#3)#3\expandafter\relax\expandafter}\expandafter - {\romannumeral0\xintiiexpro #2#4+#3#5\expandafter\relax\expandafter}\expandafter - {\romannumeral0\xintiiexpro #2#5+#3(#4-#5)\relax}% -}% end of Fibonacci_b_ii -% code as used on title page: -%\def\Fibonacci_end_i #1#2#3#4#5{\xintthe#5} -%\def\Fibonacci_end_ii #1#2#3#4#5{\xinttheiiexpr #2#5+#3(#4-#5)\relax} -% new definitions: -\def\Fibonacci_end_i #1#2#3#4#5{{#4}{#5}}% {F(N+1)}{F(N)} in \xintexpr format -\def\Fibonacci_end_ii #1#2#3#4#5% - {\expandafter - {\romannumeral0\xintiiexpro #2#4+#3#5\expandafter\relax - \expandafter}\expandafter - {\romannumeral0\xintiiexpro #2#5+#3(#4-#5)\relax}}% idem. -% \FibonacciN returns F(N) (in encapsulated format: needs \xintthe for printing) -\def\FibonacciN {\expandafter\xint_secondoftwo\romannumeral-`0\Fibonacci }% -\catcode`_ 8 +\footnote{\url{https://ctan.org/pkg/etoolbox}} +package. + +\subsection{No variable declarations are needed} + + There is no notion of a \emph{declaration of a variable}. + + To do a computation and assign its result to some macro |\z|, the user will employ the |\def|, |\edef|, or |\newcommand| (in \LaTeX) + as usual, keeping in mind that two expansion steps are needed, thus |\edef| + is initially the main tool: +% +\begin{everbatim*} +\def\x{1729728} \def\y{352827927} \edef\z{\xintiiMul {\x}{\y}} +\meaning\z \end{everbatim*} +As an alternative to |\edef| the package provides |\oodef| which expands +exactly twice the replacement text, and |\fdef| which applies \fexpan sion to +the replacement text during the definition. +\begin{everbatim*} +\def\x{1729728} \def\y{352827927} \oodef\w {\xintiiMul\x\y} \fdef\z{\xintiiMul {\x}{\y}} +\meaning\w, \meaning\z +\end{everbatim*} + +In practice |\oodef| is slower than |\edef|, except for computations ending in +very big final replacement texts (thousands of digits). On the other hand +|\fdef|\IMPORTANT{} appears to be slightly faster than |\edef| already in the +case of expansions leading to only a few dozen digits. + +\xintexprname does provide an interface to declare and assign values to +identifiers which can then be used in expressions: \autoref{xintdefvar}. + + +\subsection{Possible syntax errors to avoid} + +\edef\x{\xintMul {3}{5}/\xintMul{7}{9}} + +Here is a list of imaginable input errors. Some will cause compilation errors, +others are more annoying as they may pass through unsignaled. +\begin{itemize} +\item using |-| to prefix some macro: |-\xintiiSqr{35}/271|.% +% +\footnote{to the + contrary, this \emph{is} + allowed inside an |\xintexpr|-ession.} +\item using one pair of braces too many |\xintIrr{{\xintiiPow {3}{13}}/243}| (the + computation goes through with no error signaled, but the result is completely + wrong). +\item things like |\xintiiAdd { \x}{\y}| as the space will cause \csa{x} to be + expanded later, most probably within a |\numexpr| thus provoking possibly an + arithmetic overflow. +\item using |[]| and decimal points at the same time |1.5/3.5[2]|, or with a + sign in the denominator |3/-5[7]|. The scientific notation has no such + restriction, the two inputs |1.5/-3.5e-2| and |-1.5e2/3.5| are equivalent: + |\xintRaw{1.5/-3.5e-2}|\dtt{=\xintRaw{1.5/-3.5e-2}}, + |\xintRaw{-1.5e2/3.5}|\dtt{=\xintRaw{-1.5e2/3.5}}. +\item generally speaking, using in a context expecting an integer (possibly + restricted to the \TeX{} bound) a macro or expression which returns a + fraction: |\xinttheexpr 4/2\relax| outputs \dtt{\xinttheexpr 4/2\relax}, + not $2$. Use |\xintNum {\xinttheexpr 4/2\relax}| or |\xinttheiexpr 4/2\relax| + (which rounds the result to the nearest integer, here, the result is already + an integer) or |\xinttheiiexpr 4/2\relax|. Or, divide in your head |4| by + |2| and insert the result directly in the \TeX{} source. +\end{itemize} + +\subsection{Error messages} + +In situations such as division by zero, the \TeX{} run will be interrupted +with some error message. The user is asked to hit the RETURN key thrice, which +will display additional information. In non-interactive +|nonstopmode| the \TeX{} run goes on uninterrupted and the error data will be +found in the compilation log. + +Here is an example interactive run: +\begin{everbatim} +! Undefined control sequence. + \xint/ + DivisionByZero (hit thrice) +l.11 \xintiiDivision{123}{0} + +? +! Undefined control sequence. + \xint/ + Division of 123 by 0 +l.11 \xintiiDivision{123}{0} + +? +! Undefined control sequence. + \xint/ + next: {0}{0} +l.11 \xintiiDivision{123}{0} + +? +[1] (./temptest.aux) ) +Output written on temptest.dvi (1 page, 216 bytes). +Transcript written on temptest.log. +\end{everbatim} + +This is an experimental feature, which is in preparation for next major +release.% +% +\footnote{The related macros checking or resetting error flags are implemented + in embryonic form but no user interface is provided with |1.2l| release.} +% +% +\footnote{The implementation is cloned from \LaTeX3.} + +% Deprecated macros also generate an (expandable) error message. Just hit the +% |RETURN| key once to proceed.\IMPORTANT\ Most deprecated macros at |1.2o| are +% listed either in \autoref{ssec:coredeprecated} or +% \autoref{ssec:xintdeprecated} or \autoref{ssec:xintdeprecatedNum}. All +% were removed at |1.3|. + +% obsoleted at xint 1.4 +% The expression parsers are at |1.2l| still using a slightly less evolved +% method which lets \TeX{} display an undefined control sequence name giving +% some indication of the underlying problem (we copied this method from the +% |bigintcalc| package). The name of the control sequence is the message. + +% \begin{multicols}{2}\parskip0pt\relax +% \begin{everbatim} +% \xintError:ignored +% \xintError:removed +% \xintError:inserted +% \xintError:unknownfunction +% \xintError:we_are_doomed +% \xintError:missing_xintthe! +% \end{everbatim} +% \end{multicols} + + +Some constructs in \xintexprname-essions use delimited macros and there is +thus possibility in case of an ill-formed expression to end up beyond the +|\relax| end-marker. Such a situation can also occur from a non-terminated +|\numexpr|: +\begin{everbatim} +\xintexpr 3 + \numexpr 5+4\relax followed by some LaTeX code... +\end{everbatim} +as the |\numexpr| will swallow the |\relax| whose presence is mandatory for +|\xintexpr|, errors will inevitably arise and may +lead to very cryptic messages; but nothing unusual or especially traumatizing +for the daring experienced \TeX/\LaTeX\ user, whose has seen zillions of +un-helpful error messages already in her daily practice of +\TeX/\LaTeX.\footnote{not to mention the \LaTeX\ error messages used by + Emacs AUC\TeX\ mode also for Plain \TeX\ runs...} + + +\subsection{Package namespace, catcodes} + + +The bundle packages needs that the \csa{space} and \csa{empty} control +sequences are pre-defined with the identical meanings as in Plain \TeX{} (or +\LaTeX2e which has the same macros). + +Private macros of \xintkernelname, \xintcorename, \xinttoolsname, +\xintname, \xintfracname, \xintexprname, \xintbinhexname, \xintgcdname, +\xintseriesname, and \xintcfracname{} use one or more underscores |_| as +private letter, to reduce the risk of getting overwritten. They almost +all begin either with |\XINT_| or with |\xint_|, a handful of these +private macros such as \csa{XINTsetupcatcodes}, \csa{XINTdigits} and +those with names such as |\XINTinFloat...| or |\XINTinfloat...| do not +have any underscore in their names (for obscure legacy reasons). + +\xintkernelname provides \hyperref[odef]{|\odef|}, \hyperref[oodef]{|\oodef|}, +\hyperref[fdef]{|\fdef|}: if macros with these names already exist +\xinttoolsname will not overwrite them. The same meanings are independently +available under the names |\xintodef|, |\xintoodef|, etc... + +Apart from |\thexintexpr|, |\thexintiexpr|, ... +all other public macros from the \xintname bundle packages start with |\xint|. + +For the good functioning of the macros, standard catcodes are assumed for the +minus sign, the forward slash, the square brackets, the letter `e'. These +requirements are dropped inside an |\xintexpr|-ession: spaces are gobbled, +catcodes mostly do not matter, the |e| of scientific notation may be |E| (on +input) \dots{} + +If a character used in the |\xintexpr| syntax is made active, +this will surely cause problems; prefixing it with |\string| is one option. +There is \csbxint{exprSafeCatcodes} and \csbxint{exprRestoreCatcodes} to +temporarily turn off potentially active characters. + +\begin{framed} + For advanced \TeX\ users. At loading time of the packages the + catcode configuration may be arbitrary as long as it satisfies the following + requirements: the percent is of category code comment character, the + backslash is of category code escape character, digits have category code + other and letters have category code letter. Nothing else is assumed. +\end{framed} + +\subsection{Origins of the package} +\label{ssec:origins} + +|2013/03/28.| Package |bigintcalc| by \textsc{Heiko Oberdiek} already +provides expandable arithmetic operations on ``big integers'', +exceeding the \TeX{} limits (of $2^{31}-1$), so why another% +% +\footnote{this section was written before the \xintfracname package; the + author is not aware of another package allowing expandable + computations with arbitrarily big fractions.} +% +one? + +I got started on this in early March 2013, via a thread on the +|c.t.tex| usenet group, where \textsc{Ulrich D\,i\,e\,z} used the +previously cited package together with a macro (|\ReverseOrder|) +which I had contributed to another thread.% +% +\footnote{the \csa{ReverseOrder} could be avoided in that circumstance, + but it does play a crucial r\^ole here.} +% +What I had learned in this +other thread thanks to interaction with \textsc{Ulrich D\,i\,e\,z} and +\textsc{GL} on expandable manipulations of tokens motivated me to +try my hands at addition and multiplication. + +I wrote macros \csa{bigMul} and \csa{bigAdd} which I posted to the +newsgroup; they appeared to work comparatively fast. These first +versions did not use the \eTeX{} \csa{numexpr} primitive, they worked +one digit at a time, having previously stored carry-arithmetic in +1200 macros. + +I noticed that the |bigintcalc| package used \csa{numexpr} +if available, but (as far as I could tell) not +to do computations many digits at a time. Using \csa{numexpr} for +one digit at a time for \csa{bigAdd} and \csa{bigMul} slowed them +a tiny bit but avoided cluttering \TeX{} memory with the 1200 +macros storing pre-computed digit arithmetic. I wondered if some speed +could be gained by using \csa{numexpr} to do four digits at a time +for elementary multiplications (as the maximal admissible number +for \csa{numexpr} has ten digits). + +|2013/04/14|. This initial \xintname was followed by \xintfracname which +handled exactly fractions and decimal numbers. + +|2013/05/25|. Later came \xintexprname and at the same time \xintfracname got +extended to handle floating point numbers. + +|2013/11/22|. Later, \xinttoolsname was detached. + +|2014/10/28|. Release |1.1| significantly extended the \xintexprname parsers. + +|2015/10/10|. Release |1.2| rewrote the core integer routines which had +remained essentially unmodified, apart from a slight improvement of division +early 2014. + +This |1.2| release also got its impulse from a fast +``reversing'' macro, which I wrote after my interest got awakened again as a +result of correspondance with Bruno \textsc{Le Floch} during September 2015: +this new reverse uses a \TeX nique which \emph{requires} the tokens to be +digits. I wrote a routine which works (expandably) in quasi-linear time, but a +less fancy |O(N^2)| variant which I developed concurrently proved to be faster +all the way up to perhaps $7000$ digits, thus I dropped the quasi-linear one. +The less fancy variant has the advantage that \xintname can handle numbers +with more than $19900$ digits (but not much more than $19950$). This is with +the current common values of the input save stack and maximal expansion depth: +$5000$ and $10000$ respectively. + +\clearpage +\expandafter\let\csname xint bundlenameUp\endcsname\undefined +\csname xintkernelnameUp\endcsname +\section{Macros of the \xintkernelname package} +\RaisedLabel{sec:kernel} + +The \xintkernelname package contains mainly the common code base for handling +the load-order of the bundle packages, the management of catcodes at loading +time, definition of common constants and macro utilities which are used +throughout the code etc ... it is automatically loaded by all packages of the +bundle. + +It provides a few macros possibly useful in other contexts. + +\localtableofcontents + +\subsection{\csh{odef}, \csh{oodef}, \csh{fdef}} +\label{odef} +\label{oodef} +\label{fdef} + +\csa{oodef}|\controlsequence {}| does +\everb|@ + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter\controlsequence + \expandafter\expandafter\expandafter{} +| + +This works only for a single +|\controlsequence|, with no parameter text, even without parameters. An +alternative would be: +\everb|@ +\def\oodef #1#{\def\oodefparametertext{#1}% + \expandafter\expandafter\expandafter\expandafter + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter\oodefparametertext + \expandafter\expandafter\expandafter } +| + +\noindent +but it does not allow |\global| as prefix, and, besides, would have anyhow its +use (almost) limited to parameter texts without macro parameter tokens +(except if the expanded thing does not see them, or is designed to deal with +them). + +There is a similar macro |\odef| with only one expansion of the replacement text +||, and |\fdef| which expands fully || using |\romannumeral-`0|. + +They can be prefixed with |\global|. It appears than |\fdef| is generally a bit +faster than |\edef| when expanding macros from the \xintname bundle, when the +result has a few dozens of digits. |\oodef| needs thousands of digits it seems +to become competitive. + + +\subsection{\csh{xintReverseOrder}}\label{xintReverseOrder} + +\csa{xintReverseOrder}\marg{list}\etype{n} does not do any expansion of its +argument and just reverses the order of the tokens in the \meta{list}. Braces +are removed once and the enclosed material, now unbraced, does not get +reversed. Unprotected spaces (of any character code) are gobbled. +% +\leftedline{|\xintReverseOrder{\xintDigitsOf\xintiiPow {2}{100}\to\Stuff}|} +% +\leftedline{gives: + \ttfamily{\string\Stuff\string\to1002\string\xintiiPow\string\xintDigitsOf}} + +\xinttoolsname provides a variant \csbxint{RevWithBraces} which keeps brace +pairs in the output, and \fexpan ds its input first. + +For inputs consisting only digit tokens, see \csbxint{ReverseDigits} from +\xintname. + +\subsection{\csh{xintLength}} +\label{xintLength} + +\csa{xintLength}\marg{list}\etype{n} counts how many tokens (or braced items) +there are (possibly none). It does no expansion of its argument, so to use it +to count things in the replacement text of a macro |\x| one should do +|\expandafter\xintLength\expandafter{\x}|. Blanks between items are not +counted. See also \csbxint{NthElt}|{0}| (from \xinttoolsname) +which first \fexpan ds its argument and then applies the same code. +% +\leftedline{|\xintLength {\xintiiPow {2}{100}}|\dtt{=\xintLength + {\xintiiPow{2}{100}}}} +% +\leftedline{${}\neq{}$|\xintLen {\xintiiPow {2}{100}}|\dtt{=\xintLen + {\xintiiPow{2}{100}}}} + +\subsection{\csh{xintFirstItem}} +\label{xintFirstItem} + +\csa{xintFirstItem}\marg{list}\etype{n} returns the first item of its +argument, one pair of braces removed. If the list has no items the output is +empty.\NewWith{1.4} + +It does no expansion. For this and the next similar ones, see +|sourcexint.pdf| for comments on limitations. + +\subsection{\csh{xintLastItem}} +\label{xintLastItem} + +Added at |1.2i|. + +\csa{xintLastItem}\marg{list}\etype{n} returns the last item +of its argument, one pair of braces removed. If the list has no items the +output is empty. + +It does no expansion, which should be obtained via suitable |\expandafter|'s. +See also \csbxint{NthElt}|{-1}| from \xinttoolsname which obtains the same +result (but with another code) after having however \fexpan ded its +argument first. + +\subsection{\csh{xintFirstOne}} +\label{xintFirstOne} + +\csa{xintFirstOne}\marg{list}\etype{n} returns the first item as a braced +item. I.e. if it was braced the braces are kept, else the braces are added. +It looks like using \csbxint{FirstItem} within braces, but the difference is +when the input was empty. Then the output is empty.\NewWith{1.4} + +It does no expansion, which should be obtained via suitable |\expandafter|'s. + +\subsection{\csh{xintLastOne}} +\label{xintLastOne} + +\csa{xintLastOne}\marg{list}\etype{n} returns the last item as a braced +item. I.e. if it was braced the braces are kept, else the braces are added. +It looks like using \csbxint{LastItem} within braces, but the +difference is when the input was empty. Then the output is empty.\NewWith{1.4} + +It does no expansion, which should be obtained via suitable |\expandafter|'s. -The macro |\Fibonacci| produces not one specific value |F(N)| but a pair of -successive values |{F(N)}{F(N+1)}| which can then serve as starting point of -another routine devoted to compute a whole sequence |F(N), F(N+1), -F(N+2),....|. Each of |F(N)| and |F(N+1)| is kept in the encapsulated internal -\xintexprname format. +\subsection{\csh{xintReplicate}, \csh{xintreplicate}} +\label{xintreplicate} +\label{xintReplicate} -|\FibonacciN| produces the single |F(N)|. It also keeps it in the private -format; thus printing it will need the |\xintthe| prefix. +\csa{romannumeral}\csa{xintreplicate}|{x}|\marg{stuff}\etype{\numx n} is simply +copied over from \LaTeX3's |\prg_replicate:nn| with some minor changes.% +% +\footnote{I started with the code from Joseph \textsc{Wright} +available on an online site.} -\begingroup\footnotesize\sffamily\baselineskip 10pt -Here a code snippet which -checks the routine via a \string\message\ of the first $51$ Fibonacci -numbers (this is not an efficient way to generate a sequence of such -numbers, it is only for validating \csa{FibonacciN}). +And \csa{xintReplicate}|{x}| integrates the +\csa{romannumeeral} prefix.\NewWith{1.4} + +It +does not do any expansion of its second argument but inserts it in the upcoming +token stream precisely |x| times. Using it with a negative |x| raises no error +and does nothing.% % -\begin{everbatim} -\def\Fibo #1.{\xintthe\FibonacciN {#1}}% -\message{\xintiloop [0+1] \expandafter\Fibo\xintiloopindex., - \ifnum\xintiloopindex<49 \repeat \xintthe\FibonacciN{50}.} -\end{everbatim} -\endgroup +\footnote{This behaviour may change in future.} -The way we use |\expandafter|'s to chain successive |\xintiiexpro| evaluations -is exactly analogous to what is possible with |\numexpr|. The various -|\romannumeral0\xintiiexpro| could very well all have been |\xintiiexpr|'s but -then we would have needed |\expandafter\expandafter\expandafter| each -time. -\begin{framed} - There is a difference though: |\numexpr| does \emph{NOT} expand inside an - |\edef|, and to force its expansion we must prefix it with |\the| or - |\number| or |\romannumeral| or another |\numexpr| which is itself prefixed, - etc\dots. + +\subsection{\csh{xintGobble}, \csh{xintgobble}} +\label{xintgobble} +\label{xintGobble} - But |\xintexpr|, |\xintiexpr|, ..., expand fully in an |\edef|, with the - completely expanded - result encapsulated in a private format. +\csa{romannumeral}\csa{xintgobble}|{x}|\etype{\numx} is a Gobbling macro +written in the spirit of \LaTeX3's |\prg_replicate:nn| (which I cloned as +\csbxint{replicate}.) It gobbles |x| tokens upstream, with |x| allowed to be +as large as \dtt{531440}. Don't use it with |x<0|. - Using |\xintthe| as prefix is necessary to print the result (like |\the| or - |\number| in the case of |\numexpr|), but it is not necessary to get the - computation done (contrarily to the situation with |\numexpr|). -\end{framed} +And \csa{xintGobble}|{x}| integrates the \csa{romannumeral}.\NewWith{1.4} -Our |\Fibonacci| expands completely under \fexpan sion, so we can use -\hyperref[fdef]{\ttfamily\char92fdef} rather than |\edef| in a situation such -as +\csbxint{gobble} looks as if it must be related to \csbxint{Trim} from +\xinttoolsname, but the latter uses different code (using directly +\csbxint{gobble} is not possible because one must make sure not to gobble more +than the number of available items; and counting available items first is an +overhead which \csbxint{Trim} avoids.) It is rather\csbxint{Keep} with a +negative first argument which hands over to \csbxint{gobble} (because in that +case it is needed to count anyhow beforehand the number of items, hence +\csbxint{gobble} can then be used safely.) + +I wrote an \csa{xintcount} in the same spirit as \csa{xintreplicate} and +\csa{xintgobble}. But it needs to be counting hundreds of tokens to be worth +its salt compared to \csbxint{Length}. + +\subsection{(WIP) \csh{xintUniformDeviate}} +\label{xintUniformDeviate} + +\csa{xintUniformDeviate}|{x}|\etype{\numx} is a wrapper of engine +|\pdfuniformdeviate| (or |\uniformdeviate|).% % -\leftedline {|\fdef \X {\FibonacciN {100}}|} +\footnote{The |\uniformdeviate| primitive has been added to Xe\TeX\ + and will be available with \TeX Live 2019 release.} +The implementation is to be +considered experimental for the time being.% + +The argument is expanded in |\numexpr| and the macro itself needs two +expansion steps. It produces like the engine primitive an integer (digit +tokens) with minimal value \dtt{0} and maximal one \dtt{x-1} if |x| is +positive, or minimal value \dtt{x+1} and maximal value \dtt{0} if |x| is +negative. For the discussion next, |x| is supposed positive as this +avoids having to insert absolute values in formulas. + +The underlying engine Random Number Generator works with an array of 55 28bits +integers. To produce a « uniform » random integer in a given range +\dtt{0..x-1} it produces next pseudo-random |y| (supposedly uniformly +distributed, i.e. non-uniformity can be neglected) such that \dtt{$0\leq y < + 2^{28}$} and the output is the rounding of \dtt{$x*(y/2^{28})$}, with upper +bound |x| remapped to |0|. This has following corollaries: +\begin{enumerate} +\item with |x=2^{29}| or |x=2^{30}| the engine primitive produces only even + numbers, +\item with |x=3*2^{26}| the integers produced by the RNG when taken modulo + three obey the proportion |1:1:2|, not |1:1:1|, +\item with |x=3*2^{14}| there is analogous although weaker non-uniformity of + the random integers when taken modulo 3, +\item generally speaking pure powers of two should generate uniform random + integers, but when the range is divisible by large powers of + two, the non-uniformity may be amplified in surprising ways by modulo + operations. +\end{enumerate} +These observations are not to be construed as criticism of the engine +primitive itself, which comes from MetaPost, as the code comments and more +generally the whole of \emph{The Art of Computer Programming, Vol. 2} stresses +that it should rather be seen as producing random fractions (the unit fraction +being $2^{28}$). Using it as a generator for \emph{integers} is a bit of an +abuse. + +The first goal of \csa{xintUniformDeviate} is to guarantee a better uniformity +for the distribution of random integers in any given range |x|. + +\emph{If the probability to obtain a given |y| in |0..x-1| is + \verb$(1+e(y))/x$, the ``{relative non-uniformity}'' for that value |y| is + \verb$|e(y)|$.} + +The engine primitive guarantees only \dtt{$x/2^{28}$} relative non-uniformity, and +\csa{xintUniformDeviate} (in its current implementation) improves this by +a factor \dtt{|2^{28}=|\number"10000000}: the non-uniformity is guaranteed to +be bounded by \dtt{$x/2^{56}$}.% % -but it is usually about as efficient to employ |\edef|. And if we want +\expandafter\footnote\expandafter{\ifnum\value{footnote}=55 This «56» is proof + of existence of devil, no? \fi These estimates assume that the engine RNG underlying stream of + 28-bits integers can be considered uniform; it is known that the + parity bits of these 28-bits integers have a period of |55(2^{55}-1)| and + that after that many draws the count of 1s has only an excess of 55 compared + to the count of 0s, so the scale seems to be an intrinsic non-uniformity of + |2^{-55}| but it is not obvious if it applies to much shorter ranges. At any + rate we assumed that the non-uniformity for |x| a power of two less than + |2^{28}| is negligible in comparison to |2^{-28}|. Bigger powers of 2 + produce only even integers because the output is rescaled by + factor |x/2^{28}|!} % -\leftedline{|\edef \Y {(\FibonacciN{100},\FibonacciN{200})}|,} +With such a small non-uniformity, modulo phenomena as mentioned earlier are +not observable in reasonable computing time.% % -then |\edef| is necessary. +\begin{everbatim*} +%\xintdefiifunc mod3(x):= x 'mod' 3; +\xintNewIIExpr\ModThree[1]{#1 'mod' 3} -Allright, so let's now give the code to generate |{F(N)}{F(N+1)}{F(N+2)}...|, -using |\Fibonacci| for the first two and then using the standard recursion -|F(N+2)=F(N+1)+F(N)|: +\pdfsetrandomseed 87654321 +\xintdefiivar BadDigits:=qraw(% + \romannumeral\xintreplicate{504}{{\ModThree{\pdfuniformdeviate "C000000}}}% +);% -\catcode`_ 11 -\def\FibonacciSeq #1#2{%#1=starting index, #2>#1=ending index - \expandafter\Fibonacci_Seq\expandafter - {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2-1}% -}% -\def\Fibonacci_Seq #1#2{% - \expandafter\Fibonacci_Seq_loop\expandafter - {\the\numexpr #1\expandafter}\romannumeral0\Fibonacci {#1}{#2}% -}% -\def\Fibonacci_Seq_loop #1#2#3#4{% standard Fibonacci recursion - {#3}\unless\ifnum #1<#4 \Fibonacci_Seq_end\fi - \expandafter\Fibonacci_Seq_loop\expandafter - {\the\numexpr #1+1\expandafter}\expandafter - {\romannumeral0\xintiiexpro #2+#3\relax}{#2}{#4}% -}% -\def\Fibonacci_Seq_end\fi\expandafter\Fibonacci_Seq_loop\expandafter - #1\expandafter #2#3#4{\fi {#3}}% -\catcode`_ 8 +\pdfsetrandomseed 87654321 +\xintdefiivar GoodDigits:=qraw(% + \romannumeral\xintreplicate{504}{{\ModThree{\xintUniformDeviate{"C000000}}}}% +);% -\begingroup\footnotesize\baselineskip10pt -\everb|@ -\catcode`_ 11 -\def\FibonacciSeq #1#2{%#1=starting index, #2>#1=ending index - \expandafter\Fibonacci_Seq\expandafter - {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2-1}% -}% -\def\Fibonacci_Seq #1#2{% - \expandafter\Fibonacci_Seq_loop\expandafter - {\the\numexpr #1\expandafter}\romannumeral0\Fibonacci {#1}{#2}% -}% -\def\Fibonacci_Seq_loop #1#2#3#4{% standard Fibonacci recursion - {#3}\unless\ifnum #1<#4 \Fibonacci_Seq_end\fi - \expandafter\Fibonacci_Seq_loop\expandafter - {\the\numexpr #1+1\expandafter}\expandafter - {\romannumeral0\xintiiexpro #2+#3\relax}{#2}{#4}% -}% -\def\Fibonacci_Seq_end\fi\expandafter\Fibonacci_Seq_loop\expandafter - #1\expandafter #2#3#4{\fi {#3}}% -\catcode`_ 8 -| -\endgroup +These 504 digits generated from \string\pdfuniformdeviate: +\xinttheiiexpr BadDigits\relax\hfill\break +contain these respective amounts of 0, 1, and 2: +% (this is definitely not the fastest way to count, but it is fun - and expandable) +\xinttheiiexpr iter(0,0,0;(i=0)?{[@][0]+1,[@][1],[@][2]} + {(i=1)?{[@][0],[@][1]+1,[@][2]} + {[@][0],[@][1],[@][2]+1}}, + i=BadDigits)\relax\par -This |\FibonacciSeq| macro is -completely expandable but it is not \fexpan dable. +These 504 digits generated from \string\xintUniformDeviate: +\xinttheiiexpr GoodDigits\relax\hfill\break +contain these respective amounts of 0, 1, and 2: +\xinttheiiexpr iter(0,0,0;(i=0)?{[@][0]+1,[@][1],[@][2]} + {(i=1)?{[@][0],[@][1]+1,[@][2]} + {[@][0],[@][1],[@][2]+1}}, + i=GoodDigits)\relax\par +% % output to data file for double-check with python +% \newwrite\out +% \immediate\openout\out=\jobname.data +% \immediate\write\out{Lbad=[\xinttheiiexpr BadDigits\relax]} +% \immediate\write\out{Lgood=[\xinttheiiexpr GoodDigits\relax]} +% \immediate\closeout\out +\end{everbatim*} -This is not a problem in the next example which uses \csbxint{For*} as the -latter applies repeatedly full expansion to what comes next each time it -fetches an item from its list argument. Thus \csbxint{For*} still manages to -generate the list via iterated full expansion. +There is a second peculiarity of the engine RNG: two seeds sharing the same +low |k| bits generate sequences of 28-bits integers which are identical modulo +|2^k|! In particular after setting the seed, there are only 2 distinct +sequences of parity bits for the integers generated by |\pdfuniformdeviate (2 +to the power 28)|... +In order to mitigate, \csa{xintUniformDeviate} currently only uses the +seven high bits from the underlying random stream, using multiple calls to +|\pdfuniformdeviate 128|. From the Birthday Effect, after about |2^{11}| seeds +one will likely pick a new one sharing its 22 low bits with an earlier one. -\begin{figure*}[ht!] - \phantomsection\label{fibonacci} - \newcounter{myindex} - \fdef\Fibxxx{\FibonacciN {30}}% - \setcounter{myindex}{30}% -\centeredline{\tabskip 1ex -\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr - \xintFor* #1 in {\FibonacciSeq {30}{59}}\do - {\themyindex &\xintthe#1 & - \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% -}\vrule -\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr - \xintFor* #1 in {\FibonacciSeq {60}{89}}\do - {\themyindex &\xintthe#1 & - \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% -}\vrule -\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr - \xintFor* #1 in {\FibonacciSeq {90}{119}}\do - {\themyindex &\xintthe#1 & - \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% -}}% -% -\centeredline{Some Fibonacci numbers together with their residues modulo - |F(30)|\dtt{=\xintthe\Fibxxx}} -\end{figure*} +\begin{enumerate} +\item but as the final random integer is obtained by additional operations + involving the range |x| (currently a modulo operation), for odd ranges it is + more difficult for bit correlations to be seen, +\item anyway as they are only +|2^{28}| seeds in total, after only |2^{14}| seeds it is likely to encounter +one already explored, and then random integers are identical, however +complicated the RNG's raw output is malaxed, and whatever the target range +|x|. And |2^{14}| is only eight times as large as |2^{11}|. +\end{enumerate} -\begingroup\footnotesize\baselineskip10pt -\everb|@ -\newcounter{myindex}% not "index", which would overwrite theindex environment! -% (many have probably been bitten by this trap) -\tabskip 1ex - \fdef\Fibxxx{\FibonacciN {30}}% - \setcounter{myindex}{30}% -\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr - \xintFor* #1 in {\FibonacciSeq {30}{59}}\do - {\themyindex &\xintthe#1 & - \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% -}\vrule -\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr - \xintFor* #1 in {\FibonacciSeq {60}{89}}\do - {\themyindex &\xintthe#1 & - \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% -}\vrule -\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr - \xintFor* #1 in {\FibonacciSeq {90}{119}}\do - {\themyindex &\xintthe#1 & - \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% -}% -| -\endgroup +It would be nice if the engine provided some user interface for + letting its RNG execute a given number of iterations without the overhead + of replicated executions of |\pdfuniformdeviate|. This could help gain + entropy and would reduce correlations across series from distinct seeds. -This produces the Fibonacci numbers from |F(30)| to |F(119)|, and -computes also all the -congruence classes modulo |F(30)|. The output has -been put in a \hyperref[fibonacci]{float}, which appears -\vpageref[above]{fibonacci}. I leave to the mathematically inclined -readers the task to explain the visible patterns\dots |;-)|. +\smallskip +\emph{The description above summarizes parts of discussions held with Bruno Le + Floch in May 2018 on occasion of his LaTeX3 contributions related to this.} +\par +\smallskip -\subsection{Acknowledgements (2013/05/25)} +\TeXnote +currently the implementation of \csbxint{UniformDeviate} consumes exactly 5 +calls to the engine primitive at each execution; the improved |x/2^{56}| +non-uniformity could be obtained with only 2 calls, but paranoïa about the +phenonemon of seeds with common bits has led me to accept the overhead of +using the 7 high bits of 4 random 28bits integers, rather than one single +28bits integer, or two, or three. -I was greatly helped in my preparatory thinking, prior to producing such an -expandable parser, by the commented source of the -\href{https://ctan.org/pkg/l3kernel}{l3fp} package, specifically the -|l3fp-parse.dtx| file (in the version of April-May 2013; I think there was in -particular a text called ``roadmap'' which was helpful). Also the source of the -|calc| package was instructive, despite the fact that here for |\xintexpr| the -principles are necessarily different due to the aim of achieving expandability. +Timings indicate that one \csbxint{UniformDeviate} has a time cost about 13 +times the one for one call to the engine primitive (and not only 5, as the +extra arithmetic expressions add overhead which is more costly than the +primitive itself). Except if the code using the pseudo-random number is very +short, this time penalty will prove in practice much less severe (and this is +one important reason why we opted for obtaining 28bits via the 7 high bits of +4 successive pseudo random numbers from the engine primitive). For example +let's raise 100 times a random integer to the tenth power: +% +\footnote{This is done on a |2.4GHz| processor. Hmm... or on a |2.8GHz| one, + I should add some automatic recognition to the build process...} +% +\begin{everbatim*} +\pdfsetrandomseed 12345678 +\pdfresettimer\romannumeral\xintreplicate + {100}{\fdef\foo{\xintiiPow{\xintUniformDeviate{100000000}}{10}}}% +\the\dimexpr\pdfelapsedtime sp\relax\space (with \string\xintUniformDeviate)\newline +(last result: \foo)\newline +\pdfsetrandomseed 12345678 +\pdfresettimer\romannumeral\xintreplicate + {100}{\fdef\foo{\xintiiPow{\pdfuniformdeviate 100000000}{10}}}% +\the\dimexpr\pdfelapsedtime sp\relax\space (with \string\pdfuniformdeviate)\newline +(last result: \foo)\par +\end{everbatim*} -\clearpage -\expandafter\let\csname Older macros and docnameUp\endcsname\undefined -\csname xinttrignameUp\endcsname +\TeXnote +the macros \csbxint{RandomDigits} or \csbxint{iiRandRange}, and their +variants, as well as the supporting macros for \func{random} generate random +decimal digits eight by eight as if using +\csa{xintUniformDeviate}|{100000000}|, but via a direct optimized call made +possibly by the range being a power of 10. +\clearpage +\let\xintkernelnameUp\undefined +\csname xintcorenameUp\endcsname \def\n{|{N}|} \def\m{|{M}|} \def\x{|{x}|} -\section{Macros of the \xinttrigname package} -\RaisedLabel{sec:trig} +\section{Macros of the \xintcorename package} +\RaisedLabel{sec:core} -\localtableofcontents +Package \xintcorename is automatically loaded by \xintname. -This package provides trigonometric functions for use with \xintexprname. -The sole macro is \csbxint{reloadxinttrig}. +\xintcorename provides for big integers the four basic arithmetic operations +(addition, subtraction, multiplication, division), as well as powers and +factorials. -This package was first included in release |1.3e| (|2019/04/05|) of -\xintexprname. It is automatically loaded by \xintexprname. +In the descriptions of the macros \texttt{\n} and \texttt{\m} stand +for (big) integers or macros \hyperref[ssec:expansions]{\fexpan ding} to +such big integers in strict format as described in \autoref{ssec:inputs}. -\textbf{Acknowledgements:} I finally decided to release some such functions -under friendly pressure of Jürgen \textsc{Gilg} and Thomas \textsc{Söll}, let -them both be thanked here. +All macros require strict integer format on input and produce +strict integer format on output, except:\IMPORTANT +\begin{itemize}[nosep] +\item \csbxint{iNum} which converts to strict integer format an input in + \emph{extended} integer format, i.e. admitting multiple leading plus or + minus signs, then possibly leading zeroes, then digits, +\item and \csbxint{Num} which is an alias for the former, which gets redefined by + \xintfracname to accept more generally also decimal numbers or fractions as + input and which truncates them to integers. +\end{itemize} -\subsection{\csh{xintreloadxinttrig}}\label{xintreloadxinttrig} +% Most removed macros listed in \autoref{ssec:coredeprecated} were by design +% applying \csbxint{Num} to their inputs. Typically these macros had a single +% |i| in their names, for example \csa{xintiAdd} was such a companion to +% \csa{xintiiAdd}. \xintfracname redefined \csbxint{Num} to be the macro +% accepting general fractional input and truncating it to an integer. Hence a +% macro such as \csa{xintiAdd} was compatible with the output format of +% \xintfracname macros, contrarily to \csbxint{iiAdd} which handles only strict +% integer format for its inputs. Of course, \xintfracname defined also its own +% \csbxint{Add} which did the addition of its arguments without truncating them +% to integers... but whose output format is the |A/B[N]| format explained in +% \autoref{ssec:outputs}, hence even if representing a small integer it can not +% be used directly in a \TeX\ context such as |\ifnum|, contrarily to +% \csa{xintiAdd} or to \csbxint{iiAdd}. -The library is loaded automatically by \xintexprname, thus with the default -value of \csbxint{theDigits} which is \dtt{16}. But it can handle a precision -of up to about \fbox{\dtt{60}} digits (make this \dtt{59} at most for the -inverse functions). For this, execute for example \csbxint{SetDigits*}|{48}|. +% \begin{framed} +% This situation was the result of some early-on design +% decisions which now appear misguided and impede further development. Hence, +% at |1.2o| it has been decided to deprecate \emph{all} such |i|-macros. And +% they got removed from the package at |1.3|. +% \end{framed} -\begin{framed} - Since |1.3f|, the starred variants \csbxint{Digits*}|:=P;| and - \csbxint{SetDigits*}\marg{num. expression} execute \csbxint{reloadxinttrig} - to let the package re-configure itself. +The |ii| in the names of the macros such as \csbxint{iiAdd} serves to stress +that they accept only strict integers as input (this is signaled by the margin +annotation \textcolor[named]{PineGreen}{\emph{f}}), or macros \fexpan ding to +such strict format (big) integers and that they produce strict integers as +output. - The non-starred variants do not execute \csbxint{reloadxinttrig} (to avoid - adding artificial overhead to existing documents).\IMPORTANTf{} -\end{framed} +Other macros, such as \csbxint{Double}, lack the |ii|, but this is only a +legacy of the history of the package and they have the same requirements for +input and format of output as the |ii|-macros. -Absence of guard digits (whether in the used hard-coded constants or in -passing over values from one auxiliary function to the next) due to high level -(user) interface used for the programming means that the produced values are -definitely expected to be wrong in the last digit or last two digits. I should -actually give some estimate of the actual maximal error in |ulps| unit, but I -have not done the complete analysis for lack of time. +% +% % +% \footnote{Regarding \csbxint{FDg} and \csbxint{LDg}, this is a breaking change +% because formerly they used \csbxint{Num}.} -Final computation results should thus probably be printed via -\csbxint{floateval}|{[-2]....}| in order to strip off (with rounding) the last -two digits, if one does not like seeing those non-meaningful figures in the -last one or two positions (I don't say those last two figures are -\emph{systematically} off). For example, to achieve \dtt{16} digits of -precision one should work with a precision of 18 digits (being careful to have -issued \csbxint{reloadxinttrig}) and round results using -\csbxint{floateval}|{[-2]....}|. +The letter \texttt{x} (with margin annotation +\smash{\textcolor[named]{PineGreen}{\numx}}) stands for an argument which will +be handled embedded in |\numexpr..\relax|. It will thus be completely expanded +and must give an integer obeying the \TeX{} bounds. See also +\autoref{sec:useofcount}. This is the case for the argument of \csbxint{iiFac} +or the exponent argument of \csbxint{iiPow}. -Another approach is to use \csbxint{ieval}|{[D]...}| for conversion to -a fixed point format. +The {\color[named]{PineGreen}$\star$}'s in the margin are there to remind of +the complete expandability, even \fexpan dability of the macros, as discussed +in \autoref{ssec:expansions}. -In future, lower level coding will probably replace the high-level interface, -or at least the macros produced by the high-level interface will be hacked -into to tell the float macros to work at a somewhat elevated precision. +\localtableofcontents -\subsection{Constants} +\subsection{\csh{xintiNum}}\label{xintiNum} -They are the correct rounding to \csbxint{theDigits} precision of the -mathematically exact ones. Their values get incorporated into the -trigonometrical functions at the time of their definitions during loading or -reloading of the package. They are left free to use, or modified, or -\csbxint{unassignvar}'d, as this will have no impact whatsoever on the -functions. +|\xintiNum|\n\etype{f} removes chains of plus or minus signs, followed by +zeroes. +\begin{everbatim*} +\xintiNum{+---++----+--000000000367941789479} +\end{everbatim*} -\begin{description} -\vardesc{twoPi} what could that be? -\vardesc{threePiover2} -\vardesc{Pi} -\vardesc{Piover2} -\vardesc{oneRadian} this is one radian in degrees: $180/\pi$ -\vardesc{oneDegree} this is one degree in radian: $\pi/180$ -\vardesc{invfact2} this is $1/2!$ -\vardesc{invfact3} this is $1/3!$ -\item[\dots] -\vardesc{invfact44} this is $1/44!$ -\end{description} +\subsection{\csh{xintDouble}}\label{xintDouble} + +|\xintDouble|\n\etype{f} computes |2N|. + +\subsection{\csh{xintHalf}}\label{xintHalf} + +|\xintHalf|\n\etype{f} computes |N/2| +truncated towards zero. + +\subsection{\csh{xintInc}}\label{xintInc} + +|\xintInc|\n\etype{f} evaluates |N+1|. + +\subsection{\csh{xintDec}}\label{xintDec} + +|\xintDec|\n\etype{f} evaluates |N-1|. + +\subsection{\csh{xintDSL}}\label{xintDSL} + +|\xintDSL|\n\etype{f} is decimal shift left, \emph{i.e.} multiplication by +ten. -For a (very) slight optimization of usage, it is recommended to convert them -to macro form, for example: -\begin{everbatim*} -\edef\oneDegree{\xintfloatexpr oneDegree\relax} -\xintfloateval{sin(37\oneDegree)}\newline -\xintfloateval{sind(37)}\newline -\end{everbatim*} -By the way, the above value differs by |1ulp| from correct rounding of exact -one (which looks \dtt{...520482}79917...), see \autoref{ssec:trignotes}. +\subsection{\csh{xintDSR}}\label{xintDSR} -\subsection{Functions} +|\xintDSR|\n\etype{f} is truncated decimal shift right, \emph{i.e.} it is the +truncation of |N/10| towards zero. -\subsubsection{Direct trigonometry} +\subsection{\csh{xintDSRr}}\label{xintDSRr} -With the variable in radians: +|\xintDSRr|\n\etype{f} is rounded decimal shift right, \emph{i.e.} it is the +rounding of |N/10| away from zero. It is needed in \xintcorename for use by +\csbxint{iiDivRound}. -\begin{description} -\funcdesc{sin} sine -\funcdesc{cos} cosine -\funcdesc{tan} tangent -\funcdesc{cot} cotangent -\funcdesc{sec} secant -\funcdesc{csc} cosecant -\end{description} +\subsection{\csh{xintFDg}}\label{xintFDg} -With the variable in degrees: +|\xintFDg|\n\etype{f} outputs the first digit (most significant) of the +number. -\begin{description} -\funcdesc{sind} sine -\funcdesc{cosd} cosine -\funcdesc{tand} tangent -\funcdesc{cotd} cotangent -\funcdesc{secd} secant -\funcdesc{cscd} cosecant -\end{description} +\subsection{\csh{xintLDg}}\label{xintLDg} -Only available with the variable in radians: -\begin{description} -\funcdesc{tg} tangent -\funcdesc{cotg} cotangent -\funcdesc{sinc} cardinal sine $\sinc(x) = \sin(x)/x$ -\end{description} +|\xintLDg|\n\etype{f} outputs the least significant digit. When the number +is positive, this is the same as the remainder in the Euclidean division by +ten. -\subsubsection{Inverse trigonometry} +\subsection{\csh{xintiiSgn}}\label{xintiiSgn} -With the value in radians: +|\xintiiSgn|\n\etype{f} returns 1 if the number is positive, 0 if it is zero +and -1 if it is negative. -\begin{description} -\funcdesc{asin} arcsine -\funcdesc{acos} arccosine -\funcdesc{atan} arctangent -\funcdesc[x, y]{Arg} the main branch of the argument of the complex number -|x+iy|, from $-\pi$ (excluded) to $\pi$ (included). As the output is rounded --\var{Pi} is a possible return value. -\funcdesc[x, y]{pArg} the branch of the argument of the complex number -|x+iy| with values going from $0$ (included) to $2\pi$ (excluded). Inherent -rounding makes \var{twoPi} a possible return value. -\funcdesc[y, x]{atan2} it is |Arg(x, y)|. Note the reversal of the arguments, -this seems to be the most frequently encountered convention across languages. -\end{description} +\subsection{\csh{xintiiOpp}}\label{xintiiOpp} -With the value in degrees: +|\xintiiOpp|\n\etype{f} outputs the opposite |-N| of the number |N|. -\begin{description} -\funcdesc{asind} arcsine -\funcdesc{acosd} arccosine -\funcdesc{atand} arctangent -\funcdesc[x, y]{Argd} the main branch of the argument of the complex number -|x+iy|, from $-180$ (excluded) to $180$ (included). Inherent rounding of -output can cause |-180| -to be returned. -\funcdesc[x, y]{pArgd} the branch of the argument of the complex number -|x+iy| with values going from $0$ (included) to $360$ (excluded). Inherent rounding of -output can cause |360| to be returned. -\funcdesc[y, x]{atan2d} it is |Argd(x, y)|. Note the reversal of the arguments, -this seems to be the most frequently encountered convention across languages. -\end{description} +Important note: an input such as |-\foo| is not legal, generally speaking, as +argument to the macros of the \xintname bundle (except, naturally in +\csbxint{expr}-essions). The reason is that the minus sign stops the \fexpan +sion done during parsing of the inputs. One must use the syntax +|\xintiiOpp{\foo}| if one wants to pass |-\foo| as +argument to other macros. -\subsubsection{Conversion functions (optional definitions left to user - decision)} +\subsection{\csh{xintiiAbs}}\label{xintiiAbs} -Python provides functions |degrees()| and |radians()|. But as most of the -\xinttrigname functions are already defined for the two units, I felt this was -not really needed. It is a oneliner to add them: -\begin{everbatim} -\xintdeffloatefunc radians(x) := x * oneDegree; -\xintdeffloatefunc degrees(x) := x * oneRadian; -\xintdefefunc radians(x) := x * oneDegree; -\xintdefefunc degrees(x) := x * oneRadian; -\end{everbatim} +|\xintiiAbs|\n\etype{f} outputs the absolute value of the number. -The variants for \csbxint{expr} above do an exact multiplication, I did not -add a \func{float} wrapper to force rounding as anyhow the trigonometrical -functions will do this initial rounding of their arguments. But if you define -a variable for multiple later use using such a |degrees()| function, it would -be better to add a \func{float} wrapper in the variable definition so the -rounding is already done: rounding an already rounded value is unavoidable -overhead but proceeds faster as it is quicly realized the input actually needs -no rounding. - -Notice however that the conversion factors above are without guard digits. One -can do this: -\begin{everbatim} -\xintdeffloatefunc radians(x) := float(\xintexpr x * oneDegreewithmoredigits\relax); -\xintdeffloatefunc degrees(x) := float(\xintexpr x * oneRadianwithmoredigits\relax); -\end{everbatim} -But recall that |x| will normally already be a rounded value, so this is -perhaps a bit complex for not much ado. Probably better to work overall with -an elevated precision and print final results at a lower precision. +\subsection{\csh{xintiiAdd}}\label{xintiiAdd} -\subsection{Important implementation notes} -\label{ssec:trignotes} +|\xintiiAdd|\n\m\etype{ff} computes the sum of the two (big) integers. -\begin{itemize} -\item The package is almost entirely implemented using the high level user - interface of \xintexprname, see \autoref{sec:xintexprsyntax} for - \csbxint{deffloatefunc} and \csbxint{deffloatvar}, the main two exceptions - were: - \begin{enumerate}[nolistsep] - \item the range reduction for the |sind()| and |cosd()| functions which - required for optimized efficiency the coding at some more core level. - \item some changes at core level - facilitate the transfer of the defined functions from the float parser to - the exact parser. - \end{enumerate} - To avoid problems if the package is reloaded at a time the user has - used some letter variables as assigned variables, I added - \csbxint{ensuredummy} and \csbxint{restorevariable}. -\item It is not possible from this interface to (easily) let the computation - proceed with a temporarily elevated precision (``guard digits''). Expect - thus some errors in the last places; basically one should use the optional - rounding argument of either \csbxint{floateval} or \csbxint{ieval} to reduce - the number of digits of printed values by about two digits, if one - hopes to get correct rounding (most of the time). -\item Currently, \xintname is lacking some dedicated internal representation - of floats which means that most operations re-parse the digit tokens of their - arguments to count them\dots\ this does not contribute to efficiency (you - can load the module under |\xintverbosetrue| regime and see how the nested - macros look like and get an idea of how many times some rather silly - re-counting of mantissa lengths will get done!) -\item One should not overwrite some function names which are employed as - auxiliaries: |sin_aux|, |cos_aux|, |sin_|, |cos_|, |sind_|, |cosd_|, - |asin_l|\dots others\dots |asin_a|, |asind_a|, |atan_a|, |atand_a|, - |atan_b|, |atand_b|. If you redefine any one of them, you break the - whole thing. -\item Floats with large exponents are integers and are multiple of \dtt{1000}; - hence modulo \dtt{360} all such ``angles'' are multiple of \dtt{40} degrees. - Needless to say that considering usage of the |sind()| and |cosd()| functions - with such large float numbers is meaningless. -\item Regarding |sin()| and |cos()|, \xinttrigname converts their argument to - degrees by multiplication by (pre-rounded) $180/\pi$, then does range - reduction modulo $360$ and finally goes back to radians in the appropriate - octants to use usual Taylor series (roughly said). For large floats, the - output value will thus be one of |sind(40n)|, |cosd(40n)|, |n=0..8|. If the - unit in the last place of original variable was for example \dtt{1e9} the - final result means nothing at all: the unit in the last place interval - extends above possibly astronomical numbers of intervals of length $2\pi$. +\subsection{\csh{xintiiCmp}}\label{xintiiCmp} - This intrinsic problem is not a by-product of conversion problems to and - from degrees, it is an in-built inadequacy of the concept of floating point - numbers to provide meaning to evaluating trigonometrical functions. The - argument should be treated as a uniformly distributed random variable modulo - $2\pi$, and the sine and cosine values should be random variables realizing - the value distribution of these mathematical functions. Clearly this adds - some (rather severe) implementation complications such as deciding how to - make the transition to randomness. Too lazy for that. +|\xintiiCmp|\n\m\etype{ff} produces \dtt{1} if |N>M|, \dtt{0} if |N=M|, +and \dtt{-1} if |N1+ and |x<0|, an error is raised. There will also +be an error if |x| exceeds the maximal \eTeX{} number \dtt{\number"7FFFFFFF}, +but the real limit for exponents comes from either the computation time or the +settings of some \TeX\ memory parameters. -Although the precision is thus limited to about \dtt{8} or \dtt{9} digits this -is amply enough for plots. +\begin{framed} + Indeed, the maximal power of $2$ which \xintname is able to compute + explicitely is |2^(2^17)=2^131072| which has \dtt{39457} digits. This + exceeds the maximal size on input for the \xintcorename multiplication, hence + any |2^N| with a higher |N| will fail. On the other hand |2^(2^16)| has + \dtt{19729} digits, thus it can be squared once to obtain |2^(2^17)| or + multiplied by anything smaller, thus all exponents up to and including |2^17| + are allowed (because the power operation works by squaring things and making + products). +\end{framed} -\subsection{\csh{poormanloghack}} -\label{ssec:poormanloghack} +% Side remark: after all it does pay to think! I almost melted my CPU trying by +% dichotomy to pin-point the exact maximal allowable |N| for |\xintiiPow 2{N}| +% before finally making the reasoning above. Indeed, each such computation with +% |N>130000| activates the fan of my laptop and results in so warm a keyboard +% that I can hardly go on working on it! And it takes about 12 minutes for each +% |\xintiiPow2{N}| with such |N|'s of the order of $130000$ (a.t.t.o.w.). -\begin{description} -\item[\string\poormanloghack\string{**\string}] use it to let the |**| operator be remapped to the - \func{pow} function. -\item[\string\poormanloghack\string{\string^\string}] use it to let the |^| operator be remapped to the - \func{pow} function. -\end{description} -If used, they obey \TeX\ scoping as usual. -\begin{everbatim*} -\begingroup -\poormanloghack{**}\xintfloateval{[8]1.234**5.678}\newline -\poormanloghack{^}\xintfloateval{[8]1.234^5.678}\par -\endgroup -\end{everbatim*} +\subsection{\csh{xintiiFac}}\label{xintiiFac} -Notice that in \csbxint{floateval} those (equivalent) operators already -natively handle half-integer exponents. Once remapped to the \func{pow} -function they will become less precise than the original ones for half-integer -and integer exponents. +|\xintiiFac|\x\etype{\numx} computes the factorial. -\subsection{Functions} +\begin{framed} + The (theoretically) allowable range is $0\leqslant x\leqslant10000$. + + However the maximal possible computation depends on the values of some memory + parameters of the |tex| executable: with the current default settings of + TeXLive 2015, the maximal computable factorial (a.t.t.o.w. 2015/10/06) turns + out to be $5971!$ which has $19956$ digits.%\footnotemark +\end{framed} -All those functions achieve only about \dtt{8} or \dtt{9} digits of precision. -Notice in particular that the digits beyond the ninth printed by \func{log} -have no significance (here we suppose |1x)?{1}{0}}{-1},m=2n+1)) - ??{break(0)}{omit}{break(1)},n=1++))?{x}{omit}, - x=10001..[2]..10200)\relax +\xintiiDivRound {100}{3}, \xintiiDivRound {101}{3} \end{everbatim*} -The syntax in this last example may look a bit involved (... and it is so I -admit). First |x/:m| computes |x modulo m| (this is the modulo with respect to -floored division). The |(x)?{yes}{no}| construct checks if |x| (which -\emph{must} be within parentheses) is true or false, i.e. non zero or zero. It -then executes either the |yes| or the |no| branch, the non chosen branch is -\emph{not} evaluated. Thus if |m| divides |x| we are in the second (``false'') -branch. This gives a |-1|. This |-1| is the argument to a |??| branch which is -of the type |(y)??{y<0}{y=0}{y>0}|, thus here the |y<0|, i.e., |break(0)| is -chosen. This |0| is thus given to another |?| which consequently chooses -|omit|, hence the number is not kept in the list. The numbers which survive -are the prime numbers. +\subsection{\csh{xintiiDivTrunc}}\label{xintiiDivTrunc} +|\xintiiDivTrunc|\m\n\etype{ff} computes $trunc(M/N)$. For positive arguments +$M,N>0$ it is the same as the Euclidean quotient \csbxint{iiQuo}. \begin{everbatim*} -The first Fibonacci number beyond |2^64| bound is -\xinttheiiexpr subs(iterr(0,1;(@1>N)?{break(i)}{@1+@2},i=1++),N=2^64)\relax{} -and the previous number was its index. +\xintiiQuo{1000}{57} (Euclidean), \xintiiDivTrunc{1000}{57} (truncated), +\xintiiDivRound{1000}{57} (rounded)\newline +\xintiiQuo{-1000}{57}, \xintiiDivTrunc{-1000}{57} (t), \xintiiDivRound{-1000}{57} (r)\newline +\xintiiQuo{1000}{-57}, \xintiiDivTrunc{1000}{-57} (t), \xintiiDivRound{1000}{-57} (r)\newline +\xintiiQuo{-1000}{-57}, \xintiiDivTrunc{-1000}{-57} (t), \xintiiDivRound{-1000}{-57} (r)\par \end{everbatim*} -% A006877 In the `3x+1' problem, these values for the starting value set new -% records for number of steps to reach 1. (Formerly M0748) 14 1, 2, 3, 6, 7, -% 9, 18, 25, 27, 54, 73, 97, 129, 171, 231, 313, 327, 649, 703, 871, 1161, -% 2223, 2463, 2919, 3711, 6171, 10971, 13255, 17647, 23529, 26623, 34239, -% 35655, 52527, 77031, 106239, 142587, 156159, 216367, 230631, 410011, 511935, -% 626331, 837799 +\subsection{\csh{xintiiDivFloor}}\label{xintiiDivFloor} -One more recursion: +|\xintiiDivFloor|\m\n\etype{ff} computes $floor(M/N)$. For positive divisor +$N>0$ and arbitrary dividend $M$ it is the same as the Euclidean quotient +\csbxint{iiQuo}. \begin{everbatim*} -\def\syr #1{\xinttheiiexpr rseq(#1; (@<=1)?{break(i)}{odd(@)?{3@+1}{@//2}},i=0++)\relax} -The 3x+1 problem: \syr{231}\par +\xintiiQuo{1000}{57} (Euclidean), \xintiiDivFloor{1000}{57} (floored)\newline +\xintiiQuo{-1000}{57}, \xintiiDivFloor{-1000}{57}\newline +\xintiiQuo{1000}{-57}, \xintiiDivFloor{1000}{-57}\newline +\xintiiQuo{-1000}{-57}, \xintiiDivFloor{-1000}{-57}\par \end{everbatim*} -OK, a final one: +\subsection{\csh{xintiiMod}}\label{xintiiMod} + +|\xintiiMod|\m\n\etype{ff} computes $M - N*floor(M/N)$. For positive divisor +$N>0$ and arbitrary dividend $M$ it is the same as the Euclidean remainder +\csbxint{iiRem}. + +Formerly, this macro computed $M - N*trunc(M/N)$. The former meaning is +retained as \csa{xintiiModTrunc}. \begin{everbatim*} -\def\syrMax #1{\xinttheiiexpr iterr(#1,#1;even(i)? - {(@2<=1)?{break(i/2)}{odd(@2)?{3@2+1}{@2//2}}} - {(@1>@2)?{@1}{@2}},i=0++)\relax } -With initial value 1161, the maximal number attained is \syrMax{1161} and that latter -number is the number of steps which was needed to reach 1.\par +\xintiiRem {1000}{57} (Euclidean), \xintiiMod {1000}{57} (floored), +\xintiiModTrunc {1000}{57} (truncated)\newline +\xintiiRem {-1000}{57}, \xintiiMod {-1000}{57}, \xintiiModTrunc {-1000}{57}\newline +\xintiiRem {1000}{-57}, \xintiiMod {1000}{-57}, \xintiiModTrunc {1000}{-57}\newline +\xintiiRem {-1000}{-57}, \xintiiMod {-1000}{-57}, \xintiiModTrunc {-1000}{-57}\par \end{everbatim*} -Look at the - \hyperlink{BrentSalamin}{Brent-Salamin algorithm implementation} for a more - interesting recursion. +\subsection{\csh{xintNum}}\label{xintNum} -% \begin{everbatim*} -% \newcommand\Factors [1]{\xinttheiiexpr -% subs(seq((i/:3=1)?{omit}{[L][i]},i=0..len(L)-1), -% L=rseq(#1;(p^2>[@][0])?{([@][0]>1)?{break(1,[@][0],1)}{abort}} -% {(([@][0])/:p)?{omit} -% {iter(([@][0])//p; (@/:p)?{break(@,p,e)}{@//p},e=1++)}},p=2++))\relax } -% \Factors {41^4*59^2*29^3*13^5*17^8*29^2*59^4*37^6} -% \end{everbatim*} +|\xintNum|\etype{f} is originally an alias for \csbxint{iNum}. But with +\xintfracname loaded its meaning is \hyperref[xintNumFrac]{modified} to accept +more general inputs. It then becomes an alias to \csbxint{TTrunc} which +truncates the general input to an integer in strict format. -% This might look a bit scary, I admit.% -% % -% \footnote{Look at the -% \hyperlink{BrentSalamin}{Brent-Salamin algorithm implementation} for a much -% saner example.} -% % +% \subsection{Removed macros}\label{ssec:coredeprecated} -% \xintexprname has minimal tools and -% is obstinate about doing everything expandably! We are hampered by absence of a -% notion of ``nuple''. The algorithm divides |N| by |2| until no more possible, -% then by |3|, then by |4| (which is silly), then by |5|, then by |6| (silly -% again), \dots. +% These macros were deprecated at |1.2o| and removed at |1.3|. +% |\xintiiFDg| (renamed to \csbxint{FDg}), +% |\xintiiLDg| (renamed to \csbxint{LDg}), +% |\xintiOpp|, +% |\xintiAbs|, +% |\xintiAdd|, +% |\xintCmp| (it gets defined by \xintfracname, so deprecation will usually not be +% seen; the macro with this name from former \xintcorename should have been +% called |\xintiCmp| actually), +% |\xintSgn| (it also gets its proper definition from \xintfracname), +% |\xintiSub|, +% |\xintiMul|, +% |\xintiDivision|, +% |\xintiQuo|, +% |\xintiRem|, +% |\xintiDivRound|, +% |\xintiDivTrunc|, +% |\xintiMod|, +% |\xintiSqr|, +% |\xintiPow|, +% |\xintiFac|. + + +\clearpage +\let\xintcorenameUp\undefined +\csname xintnameUp\endcsname +\def\n{|{N}|} +\def\m{|{M}|} +\def\x{|{x}|} +\section{Macros of the \xintname package} +\RaisedLabel{sec:xint} + +This package loads automatically \xintcorename (and \xintkernelname) hence +all macros described in \autoref{sec:core} are still available. + +This is \texttt{\xintbndlversion} of +\texttt{\xintbndldate}. + +Version |1.0| was released |2013/03/28|. +Since |1.1 2014/10/28| the core arithmetic macros have been moved to a separate +package \xintcorename, which is automatically loaded by \xintname. +Only the \csbxint{iiSum}, \csbxint{iiPrd}, \csbxint{iiSquareRoot}, +\csbxint{iiPFactorial}, \csbxint{iiBinomial} genuinely add to the arithmetic +macros from \xintcorename. (\csbxint{iiFac} which computes factorials is +already in \xintcorename.) + +With the exception of \csbxint{Len}, of the «Boolean logic macros» (see +next paragraphs) all macros require inputs being integers in strict format, see \autoref{ssec:inputs}.% +% +\footnote{of +course for conditionals such as \csbxint{iiifCmp} this constraint applies only +to the first two arguments.} +% +The |ii| in the macro names is here as a reminder of that fact. The output is +an integer in strict format, or a pair of two braced such integers for +\csbxint{iiSquareRoot}, with the exception of \csbxint{iiE} which may produce +strings of zero's if its first argument is zero. + +Macros \csbxint{DecSplit} and \csbxint{ReverseDigits} are non-arithmetic and +have their own specific rules. + +For all macros described here for which it makes sense, package \xintfracname +defines a similar one without |ii| in its name. This will handle more general +inputs: decimal, scientific numbers, fractions. The |ii| macros provided here +by \xintname can be nested inside macros of \xintfracname but the opposite +does not apply, because the output format of the \xintfracname macros, even +for representing integers, is not understood by the |ii| macros. The «Boolean +macros» \csbxint{AND} etc... are exceptions though, they work fine if served +as inputs some \xintfracname output, despite doing only \fexpan +sion. Prior to |1.2o|, these macros did apply the \csbxint{Num} +or the more general \xintfracname general parsing, but this overhead was +deemed superfluous as it serves only to handle hand-written input and is not +needed if the input is obtained as a nested chain of \xintfracname macros for +example. + +Prior to release |1.2o|, \xintname defined additional macros which applied +\csbxint{Num} to their input arguments. All these macros were deprecated at +|1.2o| and have been removed at |1.3|. + +At |1.3d| macros \csbxint{iiGCD} and \csbxint{iiLCM} from package \xintgcdname +are also available from loading \xintname only. They are support macros for +the (multi-arguments) functions \func{gcd} and \func{lcm} in \csbxint{iiexpr}. + +See \autoref{ssec:expansions} for the significance of the +\textcolor[named]{PineGreen}{\Numf}, \textcolor[named]{PineGreen}{\emph{f}}, +\textcolor[named]{PineGreen}{\numx} and \textcolor[named]{PineGreen}{$\star$} +margin annotations. -% The variable |L=rseq(#1;...)| expands, if one follows the steps, to a comma -% separated list starting with the initial (evaluated) |N=#1| and then -% pseudo-triplets where the first item is |N| trimmed of small primes, the -% second item is the last prime divisor found, and the third item is its -% exponent in original |N|. -% The algorithm needs to keep handy the last computed quotient by prime powers, -% hence all of them, but at the very end it will be cleaner to get rid of them -% (this corresponds to the first line in the code above). This is achieved in a -% cumbersome inefficient way; indeed each item extraction |[L][i]| is costly: it -% is not like accessing an array stored in memory, due to expandability, nothing -% can be stored in memory! Nevertheless, this step could be done here in a far -% less inefficient manner if there was a variant of |seq| which, in the spirit -% of \csbxint{iloopindex}, would know how many steps it had been through so far. -% This is a feature to be added to |\xintexpr|! (as well as a |++| construct -% allowing a non unit step). -% Notice that in |iter(([@][0])//p;| the |@| refers to the previous triplet (or -% in the first step to |N|), but the latter |@| showing up in |(@/:p)?| refers -% to the previous value computed by |iter|. -% \begin{snugframed} -% Parentheses are essential in |..([y][0])| else the parser will see |..[| and -% end up in ultimate confusion, and also in |([@][0])/:p| else the parser will -% see the itemwise operator |]/| on lists and again be very confused (I could -% implement a |]/:| on lists, but in this situation this would also be very -% confusing to the parser.) -% \end{snugframed} -% See \autoref{ssec:factorize} for a routine |\Factorize| written directly with -% \xintname macros. Last time I checked |\Factors| was about seven times slower -% than |\Factorize| in test cases such as -% |16246355912554185673266068721806243461403654781833| and others. Among the -% various things explaining the speed difference, there is fact that the -% |\Factorize| algorithm step by increments of two, not one, and also it divides -% only once, obtaining quotient and remainder in one go. These two things -% already make for a speed-up factor of about four. Thus, |\Factors| is not -% completely inefficient in comparison, and was quite easier to come up with -% than |\Factorize|. +\etocsetnexttocdepth{subsubsection} +\localtableofcontents -\subsection{Completely expandable prime test} -\label{ssec:primesI} +\subsection{\csh{xintiLen}}\label{xintiLen} -Let us now construct a completely expandable macro which returns $1$ if its -given input is prime and $0$ if not: -\everb|@ -\def\remainder #1#2{\the\numexpr #1-(#1/#2)*#2\relax } -\def\IsPrime #1% - {\xintANDof {\xintApply {\remainder {#1}}{\xintSeq {2}{\xintiiSqrt{#1}}}}} -| +|\xintiLen|\n\etype{\Numf} returns the length of the number, after its parsing +via \csbxint{iNum}. The count does not include the sign. +\begin{everbatim*} +\xintiLen{-12345678901234567890123456789} +\end{everbatim*} -This uses \csbxint{iiSqrt} and assumes its input is at least $5$. Rather than -\xintname's own \csbxint{iiRem} we used a quicker |\numexpr| expression as we -are dealing with short integers. Also we used \csbxint{ANDof} which will -return $1$ only if all the items are non-zero. The macro is a bit -silly with an even input, ok, let's enhance it to detect an even input: -\everb|@ -\def\IsPrime #1% - {\xintiiifOdd {#1} - {\xintANDof % odd case - {\xintApply {\remainder {#1}} - {\xintSeq [2]{3}{\xintiiSqrt{#1}}}% - }% - } - {\xintifEq {#1}{2}{1}{0}}% - } -| +Prior to |1.2o|, the package defined only \csbxint{Len}, which is extended by +\xintfracname to fractions or decimal numbers, hence acquires a bit more +overhead then. -We used the \xintname expandable tests (on big integers or fractions) -in order for |\IsPrime| to be \fexpan dable. +\subsection{\csh{xintReverseDigits}} \label{xintReverseDigits} -Our integers are short, but without |\expandafter|'s with -|\@firstoftwo|, % @ n'est plus actif dans le dtx 1.1 ! -or some other related techniques, -direct use of |\ifnum..\fi| tests is dangerous. So to make the macro more -efficient we are going to use the expandable tests provided by the package -\href{http://ctan.org/pkg/etoolbox}{etoolbox}% -% -\footnote{\url{http://ctan.org/pkg/etoolbox}}. -% -The macro becomes: -% -\everb|@ -\def\IsPrime #1% - {\ifnumodd {#1} - {\xintANDof % odd case - {\xintApply {\remainder {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}} - {\ifnumequal {#1}{2}{1}{0}}} -| +\the\dp\strutbox, \the\ht\strutbox, \the\baselineskip -In the odd case however we have to assume the integer is at least $7$, as -|\xintSeq| generates an empty list if |#1=3| or |5|, and |\xintANDof| returns -$1$ when supplied an empty list. Let us ease up a bit |\xintANDof|'s work by -letting it work on only $0$'s and $1$'s. We could use: -% -\everb|@ -\def\IsNotDivisibleBy #1#2% - {\ifnum\numexpr #1-(#1/#2)*#2=0 \expandafter 0\else \expandafter1\fi} -| -\noindent -where the |\expandafter|'s are crucial for this macro to be \fexpan dable and -hence work within the applied \csbxint{ANDof}. Anyhow, now that we have loaded -\href{http://ctan.org/pkg/etoolbox}{etoolbox}, we might as well use: -% -\everb|@ -\newcommand{\IsNotDivisibleBy}[2]{\ifnumequal{#1-(#1/#2)*#2}{0}{0}{1}} -| -\noindent -Let us enhance our prime macro to work also on the small primes: -\everb|@ -\newcommand{\IsPrime}[1] % returns 1 if #1 is prime, and 0 if not - {\ifnumodd {#1} - {\ifnumless {#1}{8} - {\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes - {\xintANDof - {\xintApply - { \IsNotDivisibleBy {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}% - }}% END OF THE ODD BRANCH - {\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH -} -| +|\xintReverseDigits|\n\etype{f} will reverse the order of the digits of the +number. \csa{xintRev} is the former denomination and is kept as an alias. +Leading zeroes resulting from the operation are not removed. Contrarily to +\csbxint{ReverseOrder} this macro \fexpan ds its argument; it is only usable +with digit tokens. It does \emph{not} apply \csbxint{Num} to its argument (so +this must be done explicitely if the argument is an integer produced from some +\xintfracname macros). It does accept a leading minus sign which will be left +upfront in the output. -The input is still assumed positive. There is a deliberate blank before -\csa{IsNotDivisibleBy} to use this feature of \csbxint{Apply}: a space stops the -expansion of the applied macro (and disappears). This expansion will be done by -\csbxint{ANDof}, which has been designed to skip everything as soon as it finds -a false (i.e. zero) input. This way, the efficiency is considerably improved. +\begingroup +\begin{everbatim*} +\oodef\x{\xintReverseDigits + {98765432109876543210987654321098765432109876543210}}\meaning\x\par +\noindent\oodef\x{\xintReverseDigits {\xintReverseDigits + {98765432109876543210987654321098765432109876543210}}}\meaning\x\par +\end{everbatim*} +\endgroup -We did generate via the \csbxint{Seq} too many potential divisors though. Later -sections give two variants: one with \csbxint{iloop} (\autoref{ssec:primesII}) -which is still expandable and another one (\autoref{ssec:primesIII}) which is a -close variant of the |\IsPrime| code above but with the \csbxint{For} loop, thus -breaking expandability. The \hyperref[ssec:primesII]{xintiloop variant} does not -first evaluate the integer square root, the \hyperref[ssec:primesIII]{xintFor - variant} still does. I did not compare their efficiencies. +\subsection{\csh{xintDecSplit}} +\label{xintDecSplit} +|\xintDecSplit|\x\n\etype{\numx f} cuts the |N| (a list of digits) into two +pieces |L| and |R|: it outputs |{L}{R}| where the original |N| +is the concatenation |LR|. These two pieces are decided according to |x|: +\begin{itemize}[nosep] +\item for |x>0|, |R| coincides with the |x| least significant digits. If |x| + equals or exceeds the length of |N| the first piece |L| will thus be + \emph{empty}, +\item for |x=0|, |R| is empty, and |L| is all of |N|, +\item for |x<0|, the first piece |L| consists of the \verb+|x|+ most + significant digits and the second piece |R| gets the remaining ones. If |x| + equals or exceeds the length of |N| the second piece |R| will thus be + \emph{empty}. +\end{itemize} -Let us construct with this expandable primality test a table of the prime -numbers up to $1000$. We need to count how many we have in order to know how -many tab stops one shoud add in the last row.% -% -\footnote{although a tabular row may have less tabs than in the - preamble, there is a problem with the \char`\|\space\space vertical - rule, if one does that.} -% -There is some subtlety for this -last row. Turns out to be better to insert a |\\| only when we know for sure we -are starting a new row; this is how we have designed the |\OneCell| macro. And -for the last row, there are many ways, we use again |\xintApplyUnbraced| but -with a macro which gobbles its argument and replaces it with a tabulation -character. The \csbxint{For*} macro would be more elegant here. -% -\everb?@ -\newcounter{primecount} -\newcounter{cellcount} -\newcommand{\NbOfColumns}{13} -\newcommand{\OneCell}[1]{% - \ifnumequal{\IsPrime{#1}}{1} - {\stepcounter{primecount} - \ifnumequal{\value{cellcount}}{\NbOfColumns} - {\\\setcounter{cellcount}{1}#1} - {&\stepcounter{cellcount}#1}% - } % was prime - {}% not a prime, nothing to do -} -\newcommand{\OneTab}[1]{&} -\begin{tabular}{|*{\NbOfColumns}{r}|} -\hline -2 \setcounter{cellcount}{1}\setcounter{primecount}{1}% - \xintApplyUnbraced \OneCell {\xintSeq [2]{3}{999}}% - \xintApplyUnbraced \OneTab - {\xintSeq [1]{1}{\the\numexpr\NbOfColumns-\value{cellcount}\relax}}% - \\ -\hline -\end{tabular} -There are \arabic{primecount} prime numbers up to 1000. -? +This macro provides public interface to some functionality which is primarily +of internal interest. It operates only (after \fexpan sion) on ``strings'' of +digits tokens: leading zeroes are allowed but a leading sign (even a minus +sign) will provoke an error. -The table has been put in \hyperref[primesupto1000]{float} which appears -\vpageref{primesupto1000}. -We had to be careful to use in the last row \csbxint{Seq} with its optional -argument |[1]| so as to not generate a decreasing sequence from |1| to |0|, but -really an empty sequence in case the row turns out to already have all its -cells (which doesn't happen here but would with a number of columns dividing -$168$). -% -\newcommand{\IsNotDivisibleBy}[2]{\ifnumequal{#1-(#1/#2)*#2}{0}{0}{1}} +Breaking change with |1.2i|: formerly |N<0| was replaced by its + absolute value. Now, a sign (positive or negative) will create an error. -\newcommand{\IsPrime}[1] - {\ifnumodd {#1} - {\ifnumless {#1}{8} - {\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes - {\xintANDof - {\xintApply - { \IsNotDivisibleBy {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}% - }}% END OF THE ODD BRANCH - {\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH -} -\newcounter{primecount} -\newcounter{cellcount} -\newcommand{\NbOfColumns}{13} -\newcommand{\OneCell}[1] - {\ifnumequal{\IsPrime{#1}}{1} - {\stepcounter{primecount} - \ifnumequal{\value{cellcount}}{\NbOfColumns} - {\\\setcounter{cellcount}{1}#1} - {&\stepcounter{cellcount}#1}% - } % was prime - {}% not a prime nothing to do -} -\newcommand{\OneTab}[1]{&} -\begin{figure*}[ht!] - \centering - \phantomsection\label{primesupto1000} - \begin{tabular}{|*{\NbOfColumns}{r}|} - \hline - 2\setcounter{cellcount}{1}\setcounter{primecount}{1}% - \xintApplyUnbraced \OneCell {\xintSeq [2]{3}{999}}% - \xintApplyUnbraced \OneTab - {\xintSeq [1]{1}{\the\numexpr\NbOfColumns-\value{cellcount}\relax}}% - \\ - \hline - \end{tabular} -\smallskip -\centeredline{There are \arabic{primecount} prime numbers up to 1000.} -\end{figure*} +\subsection{\csh{xintDecSplitL}, \csh{xintDecSplitR}} +\label{xintDecSplitL} +\label{xintDecSplitR} -\subsection{Another completely expandable prime test} -\label{ssec:primesII} +|\xintDecSplitL|\x\n\etype{\numx f} returns the first piece (unbraced) from +the \csa{xintDecSplit} output. -The |\IsPrime| macro from \autoref{ssec:primesI} checked expandably if a (short) -integer was prime, here is a partial rewrite using \csbxint{iloop}. We use the -|etoolbox| expandable conditionals for convenience, but not everywhere as -|\xintiloopindex| can not be evaluated while being braced. This is also the -reason why |\xintbreakiloopanddo| is delimited, and the next macro -|\SmallestFactor| which returns the smallest prime factor examplifies that. One -could write more efficient completely expandable routines, the aim here was only -to illustrate use of the general purpose \csbxint{iloop}. A little table giving -the first values of |\SmallestFactor| follows, its coding uses \csbxint{For}, -which is described later; none of this uses count registers. -% +\noindent|\xintDecSplitR|\x\n\etype{\numx f} returns the second piece +(unbraced) from the \csa{xintDecSplit} output. +\subsection{\csh{xintiiE}}\label{xintiiE} +|\xintiiE|\n\x\etype{f\numx } serves to extend |N| with |x| zeroes. The +parameter |x| must be non-negative. The same output would be obtained via +\csbxint{DSH}|{-x}{N}|, except for |N=0|, as |\xintDSH{-x}{N}| multiplies |N| +by |10^x| hence produces |0| if |N=0| whereas +|\xintiiE{0}{x}| produces |x+1| zeros. \begin{everbatim*} -\let\IsPrime\undefined \let\SmallestFactor\undefined % clean up possible previous mess -\newcommand{\IsPrime}[1] % returns 1 if #1 is prime, and 0 if not - {\ifnumodd {#1} - {\ifnumless {#1}{8} - {\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes - {\if - \xintiloop [3+2] - \ifnum#1<\numexpr\xintiloopindex*\xintiloopindex\relax - \expandafter\xintbreakiloopanddo\expandafter1\expandafter.% - \fi - \ifnum#1=\numexpr (#1/\xintiloopindex)*\xintiloopindex\relax - \else - \repeat 00\expandafter0\else\expandafter1\fi - }% - }% END OF THE ODD BRANCH - {\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH -}% -\catcode`_ 11 -\newcommand{\SmallestFactor}[1] % returns the smallest prime factor of #1>1 - {\ifnumodd {#1} - {\ifnumless {#1}{8} - {#1}% 3,5,7 are primes - {\xintiloop [3+2] - \ifnum#1<\numexpr\xintiloopindex*\xintiloopindex\relax - \xint_afterfi{\xintbreakiloopanddo#1.}% - \fi - \ifnum#1=\numexpr (#1/\xintiloopindex)*\xintiloopindex\relax - \xint_afterfi{\expandafter\xintbreakiloopanddo\xintiloopindex.}% - \fi - \iftrue\repeat - }% - }% END OF THE ODD BRANCH - {2}% EVEN BRANCH -}% -\catcode`_ 8 -{\centering - \begin{tabular}{|c|*{10}c|} - \hline - \xintFor #1 in {0,1,2,3,4,5,6,7,8,9}\do {&\bfseries #1}\\ - \hline - \bfseries 0&--&--&2&3&2&5&2&7&2&3\\ - \xintFor #1 in {1,2,3,4,5,6,7,8,9}\do - {\bfseries #1% - \xintFor #2 in {0,1,2,3,4,5,6,7,8,9}\do - {&\SmallestFactor{#1#2}}\\}% - \hline - \end{tabular}\par -} +\xintiiE {0}{91}\par \end{everbatim*} -\subsection{Miller-Rabin Pseudo-Primality expandably} -\label{ssec:PrimesIV} +\subsection{\csh{xintDSH}}\label{xintDSH} +|\xintDSH|\x\n\etype{\numx f} is parametrized decimal shift. When |x| is +negative, it is like iterating \csbxint{DSL} \verb+|x|+ times (\emph{i.e.} +multiplication by $10^{-x}$). When |x| positive, it is like iterating +\csbxint{DSR} |x| times (and is more efficient), and for a non-negative |N| +this is thus the same as the quotient from the Euclidean division by |10^x|. -At the time of writing, the code at the link above is still the version from -April 2016 and it needed some hacks to get recursive (pseudo)-functions -defined. Since |1.2h| of |2016/11/20| there is \csbxint{NewFunction} which -allows us here to avoid such internal hacking. +\subsection{\csh{xintDSHr}, \csh{xintDSx}}\label{xintDSHr}\label{xintDSx} -And since |1.3| of |2018/03/01|, it is possible to use \csbxint{defiifunc} -also for recursive definitions, so we use it here, but we can benefit from it -only for modular exponentiation as the rest of the code uses |iter| or |break| -statements which are not yet compatible with \csbxint{defiifunc}. +|\xintDSHr|\x\n\etype{\numx f} expects |x| to be zero or positive and it +returns then a value |R| which is correlated to the value |Q| returned by +\csbxint{DSH}\x\n{} in the following manner: +\begin{itemize} +\item if |N| is + positive or zero, |Q| and |R| are the quotient and remainder in + the Euclidean division by |10^x| (obtained in a more efficient + manner than using \csa{xintiiDivision}), +\item if |N| is negative let + |Q1| and |R1| be the quotient and remainder in the Euclidean + division by |10^x| of the absolute value of |N|. If |Q1| + does not vanish, then |Q=-Q1| and |R=R1|. If |Q1| vanishes, then + |Q=0| and |R=-R1|. +\item for |x=0|, |Q=N| and |R=0|. +\end{itemize} +So one has |N = 10^x Q + R| if |Q| turns out to be zero or +positive, and |N = 10^x Q - R| if |Q| turns out to be negative, +which is exactly the case when |N| is at most |-10^x|. -The |isPseudoPrime(n)| is usable in \csbxint{iiexpr}-essions and establishes -if its (positive) argument is a Miller-Rabin PseudoPrime to the bases $2, 3, -5, 7, 11, 13, 17$. If this is true and $n<341550071728321$ (which has 15 -digits) then $n$ really is a prime number. +|\xintDSx|\x\n\etype{\numx f} for |x| negative is exactly as +|\xintDSH|\x\n, \emph{i.e.} multiplication by $10^{-|x|}$. For |x| zero or +positive it returns the two numbers |{Q}{R}| described above, each one within +braces. So |Q| is |\xintDSH|\x\n, and |R| is |\xintDSHr|\x\n, but computed +simultaneously. -Similarly $n=3825123056546413051$ (19 digits) is the smallest composite number -which is a strong pseudo prime for bases $2, 3, 5, 7, 11, 13, 17, 19$ and -$23$. It is easy to extend the code below to include these additional tests -(we could make the list of tested bases an argument too, now that I think -about it.) +\subsection{\csh{xintiiEq}}\label{xintiiEq} -For more information see - \centeredline{\url{https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test#Deterministic_variants_of_the_test}} - and -\centeredline{\url{http://primes.utm.edu/prove/prove2_3.html}} +|\xintiiEq|\n\m\etype{ff} returns 1 if |N=M|, 0 otherwise. -In particular, according to \textsc{Jaeschke} \emph{On strong pseudoprimes to - several bases,} Math. Comp., 61 (1993) 915-926, if $n < 4,759,123,141$ it is -enough to establish Rabin-Miller pseudo-primality to bases $a = 2, 7, 61$ to -prove that $n$ is prime. This range is enough for \TeX\ numbers and we could -then write a very fast expandable primality test for such numbers using only -|\numexpr|. Left as an exercise\dots +\subsection{\csh{xintiiNotEq}}\label{xintiiNotEq} -\begin{everbatim*} -% I -------------------------------- Modular Exponentiation -% Computes x^m modulo n (with m non negative). -% We will always use it with 1 < x < n +|\xintiiNotEq|\n\m\etype{ff} returns 0 if |N=M|, 1 otherwise. -\xintdefiifunc powmod_a(x, m, n) := - ifone(m, - % m=1, return x modulo n - x /: n, - % m > 1 test if odd or even and do recursive call - if(odd(m), (x*sqr(powmod_a(x, m//2, n))) /: n, - sqr(powmod_a(x, m//2, n)) /: n - ) - ); -\xintdefiifunc powmod(x, m, n) := if(m, powmod_a(x, m, n), 1); +\subsection{\csh{xintiiGeq}}\label{xintiiGeq} -% For comparison here are the underlying support macros defined by -% \xintdefiifunc from the code above (since 1.3a): (with linebreaks added by -% TeX when writing to the log) +|\xintiiGeq|\n\m\etype{ff} returns 1 if the \emph{absolute value} +of the first number is at least equal to the absolute value of the second +number. If \verb+|N|<|M|+ it returns 0. -% Function powmod_a for \xintiiexpr parser associated to \XINT_iiexpr_userfun -% c_powmod_a with meaning macro:#1#2#3->\xintiiifOne {#2}{\xintiiMod {#1}{#3}}{\x -% intiiifNotZero {\xintiiOdd {#2}}{\xintiiMod {\xintiiMul {#1}{\xintiiSqr {\xintE -% xpandArgs {XINT_iiexpr_userfunc_powmod_a}{{#1}{\xintiiDivFloor {#2}{2}}{#3}}}}} -% {#3}}{\xintiiMod {\xintiiSqr {\xintExpandArgs {XINT_iiexpr_userfunc_powmod_a}{{ -% #1}{\xintiiDivFloor {#2}{2}}{#3}}}}{#3}}} +Important: the macro compares \emph{absolute values}. -% Function powmod for \xintiiexpr parser associated to \XINT_iiexpr_userfunc_ -% powmod with meaning macro:#1#2#3->\xintiiifNotZero {#2}{\xintExpandArgs {XINT_i -% iexpr_userfunc_powmod_a}{{#1}{#2}{#3}}}{1} +\subsection{\csh{xintiiGt}}\label{xintiiGt} -% II ------------------------------ Miller-Rabin compositeness witness +|\xintiiGt|\n\m\etype{ff} returns 1 if |N|$>$|M|, 0 otherwise. -% n=2^k m + 1 with m odd and k at least 1 +\subsection{\csh{xintiiLt}}\label{xintiiLt} -% Choose 1 if at some point n-1 mod n found, we can't say anything and break out -% -> if however we never find n-1 mod n before reaching -% z=y^{2^{k-1}} with j=k -% we then have z^2=x^{n-1}. - % Suppose z is not -1 mod n. If z^2 is 1 mod n, then n can be prime only if - % z is 1 mod n, and we can go back up, until initial y, and we have already - % excluded y=1. Thus if z is not -1 mod n and z^2 is 1 then n is not prime. - % But if z^2 is not 1, then n is not prime by Fermat. Hence (z not -1 mod n) - % implies (n is composite). (Miller test) +|\xintiiLt|\n\m\etype{ff} returns 1 if |N|$<$|M|, 0 otherwise. -% let's use again xintexpr indecipherable (except to author) syntax. Of course -% doing it with macros only would be faster. +\subsection{\csh{xintiiGtorEq}}\label{xintiiGxstorEq} -% Here \xintdefiifunc is not usable because not compatible with iter, break, ... -% but \xintNewFunction comes to the rescue. +|\xintiiGtorEq|\n\m\etype{ff} returns 1 if |N|$\geqslant$|M|, 0 otherwise. +Extended by \xintfracname to fractions. -\xintNewFunction{isCompositeWitness}[4]{% x=#1, n=#2, m=#3, k=#4 - subs((y==1)?{0} - {iter(y;(j=#4)?{break(!(@==#2-1))} - {(@==#2-1)?{break(0)}{sqr(@)/:#2}},j=1++)} - ,y=powmod(#1,#3,#2))} +\subsection{\csh{xintiiLtorEq}}\label{xintiiLtorEq} -% added note (2018/03/07) it is possible in the above that m=#3 is never -% zero, so we should rather call powmod_a for a small gain, but I don't -% have time to re-read the code comments and settle this. - -% III ------------------------------------- Strong Pseudo Primes +|\xintiiLtorEq|\n\m\etype{ff} returns 1 if |N|$\leqslant$|M|, 0 otherwise. -% cf -% http://oeis.org/A014233 -% -% +\subsection{\csh{xintiiIsZero}}\label{xintiiIsZero} -% check if positive integer <49 si a prime. -% 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47 -\def\IsVerySmallPrime #1% - {\ifnum#1=1 \xintdothis0\fi - \ifnum#1=2 \xintdothis1\fi - \ifnum#1=3 \xintdothis1\fi - \ifnum#1=5 \xintdothis1\fi - \ifnum#1=\numexpr (#1/2)*2\relax\xintdothis0\fi - \ifnum#1=\numexpr (#1/3)*3\relax\xintdothis0\fi - \ifnum#1=\numexpr (#1/5)*5\relax\xintdothis0\fi - \xintorthat 1} +|\xintiiIsZero|\n\etype{f} returns 1 if |N=0|, 0 otherwise. -\xintNewFunction{isPseudoPrime}[1]{% n = #1 - (#1<49)?% use ? syntax to evaluate only what is needed - {\IsVerySmallPrime{\xintthe#1}}% macro needs to be fed with #1 unlocked. - {(even(#1))? - {0} - {subs(% - % L expands to two values m, k hence isCompositeWitness does get - % its four variables x, n, m, k - isCompositeWitness(2, #1, L)? - {0}% - {isCompositeWitness(3, #1, L)? - {0}% - {isCompositeWitness(5, #1, L)? - {0}% - {isCompositeWitness(7, #1, L)? - {0}% -% above enough for N<3215031751 hence all TeX numbers - {isCompositeWitness(11, #1, L)? - {0}% -% above enough for N<2152302898747, hence all 12-digits numbers - {isCompositeWitness(13, #1, L)? - {0}% -% above enough for N<3474749660383 - {isCompositeWitness(17, #1, L)? - {0}% -% above enough for N<341550071728321 - {1}% - }% not needed to comment-out end of lines spaces inside - }% \xintexpr but this is too much of a habit for me with TeX! - }% I left some after the ? characters. - }% - }% - }% this computes (m, k) such that n = 2^k m + 1, m odd, k>=1 - , L=iter(#1//2;(even(@))?{@//2}{break(@,k)},k=1++))% - }% - }% -} +\subsection{\csh{xintiiIsNotZero}}\label{xintiiIsNotZero} + +|\xintiiIsNotZero|\n\etype{f} returns 1 if |N!=0|, 0 otherwise. + +\subsection{\csh{xintiiIsOne}}\label{xintiiIsOne} + +|\xintiiIsOne|\n\etype{f} returns 1 if |N=1|, 0 otherwise. + +\subsection{\csh{xintiiOdd}}\label{xintiiOdd} + +|\xintiiOdd|\n\etype{f} is 1 if the number is odd and 0 otherwise. + +\subsection{\csh{xintiiEven}}\label{xintiiEven} + +|\xintiiEven|\n\etype{f} is 1 if the number is even and 0 otherwise. -% if needed: -%\def\IsPseudoPrime #1{\xinttheiiexpr isPseudoPrime(#1)\relax} +\subsection{\csh{xintiiMON}}\label{xintiiMON} -\noindent The smallest prime number at least equal to 3141592653589 is -\xinttheiiexpr - seq(isPseudoPrime(3141592653589+n)? - {break(3141592653589+n)}{omit}, n=0++)\relax. -% we could not use 3141592653589++ syntax because it works only with TeX numbers -\par +|\xintiiMON|\n\etype{f} computes |(-1)^N|. +\begin{everbatim*} +\xintiiMON {-280914019374101929} \end{everbatim*} +\subsection{\csh{xintiiMMON}}\label{xintiiMMON} +|\xintiiMMON|\n\etype{f} computes |(-1)^{N-1}|. +\begin{everbatim*} +\xintiiMMON {280914019374101929} +\end{everbatim*} +\subsection{\csh{xintiiifSgn}}\label{xintiiifSgn} +\csh{xintiiifSgn}\marg{N}\marg{A}\marg{B}\marg{C}\etype{fnnn} executes either +the \meta{A}, \meta{B} or \meta{C} code, depending on its first argument being +respectively negative, zero, or positive. -\subsection{A table of factorizations} -\label{ssec:factorizationtable} +\subsection{\csh{xintiiifZero}}\label{xintiiifZero} -As one more example with \csbxint{iloop} let us use an alignment to display the -factorization of some numbers. The loop will actually only play a minor r\^ole -here, just handling the row index, the row contents being almost entirely -produced via a macro |\factorize|. The factorizing macro does not use -|\xintiloop| as it didn't appear to be the convenient tool. As |\factorize| will -have to be used on |\xintiloopindex|, it has been defined as a delimited macro. +\csa{xintiiifZero}\marg{N}\marg{IsZero}\marg{IsNotZero}\etype{fnn} expandably +checks if the first mandatory argument |N| (a number, possibly a fraction if +\xintfracname is loaded, or a macro expanding to one such) is zero or not. It +then either executes the first or the second branch. -To spare some fractions of a second in the compilation time of this document -(which has many many other things to do), \number"7FFFFFED{} and -\number"7FFFFFFF, which turn out to be prime numbers, are not given to -|factorize| but just typeset directly; this illustrates use of -\csbxint{iloopskiptonext}. +Beware that both branches must be present. -The code next generates a \hyperref[floatfactorize]{table} which has -been made into a float appearing \vpageref{floatfactorize}. Here is now -the code for factorization; the conditionals use the package provided -|\xint_firstoftwo| and |\xint_secondoftwo|, one could have employed -rather \LaTeX{}'s own |\@firstoftwo| and |\@secondoftwo|, or, simpler -still in \LaTeX{} context, the |\ifnumequal|, |\ifnumless| \dots, -utilities from the package |etoolbox| which do exactly that under the -hood. Only \TeX{} acceptable numbers are treated here, but it would be -easy to make a translation and use the \xintname macros, thus extending -the scope to big numbers; naturally up to a cost in speed. +\subsection{\csh{xintiiifNotZero}}\label{xintiiifNotZero} -The reason for some strange looking expressions is to avoid arithmetic overflow. +\csa{xintiiifNotZero}\marg{N}\marg{IsNotZero}\marg{IsZero}\etype{fnn} +expandably checks if the first mandatory argument |N| is not +zero or is zero. It then either executes the first or the second branch. -\begin{everbatim*} -\catcode`_ 11 -\def\abortfactorize #1\xint_secondoftwo\fi #2#3{\fi} +Beware that both branches must be present. -\def\factorize #1.{\ifnum#1=1 \abortfactorize\fi - \ifnum\numexpr #1-2=\numexpr ((#1/2)-1)*2\relax - \expandafter\xint_firstoftwo - \else\expandafter\xint_secondoftwo - \fi - {2&\expandafter\factorize\the\numexpr#1/2.}% - {\factorize_b #1.3.}}% +\subsection{\csh{xintiiifOne}}\label{xintiiifOne} -\def\factorize_b #1.#2.{\ifnum#1=1 \abortfactorize\fi - \ifnum\numexpr #1-(#2-1)*#2<#2 - #1\abortfactorize - \fi - \ifnum \numexpr #1-#2=\numexpr ((#1/#2)-1)*#2\relax - \expandafter\xint_firstoftwo - \else\expandafter\xint_secondoftwo - \fi - {#2&\expandafter\factorize_b\the\numexpr#1/#2.#2.}% - {\expandafter\factorize_b\the\numexpr #1\expandafter.% - \the\numexpr #2+2.}}% -\catcode`_ 8 -\begin{figure*}[ht!] -\centering\phantomsection\label{floatfactorize}\normalcolor -\tabskip1ex -\centeredline{\vbox{\halign {\hfil\strut#\hfil&&\hfil#\hfil\cr\noalign{\hrule} - \xintiloop ["7FFFFFE0+1] - \expandafter\bfseries\xintiloopindex & - \ifnum\xintiloopindex="7FFFFFED - \number"7FFFFFED\cr\noalign{\hrule} - \expandafter\xintiloopskiptonext - \fi - \expandafter\factorize\xintiloopindex.\cr\noalign{\hrule} - \ifnum\xintiloopindex<"7FFFFFFE - \repeat - \bfseries \number"7FFFFFFF&\number "7FFFFFFF\cr\noalign{\hrule} -}}} -\centeredline{A table of factorizations} -\end{figure*} -\end{everbatim*} +\csa{xintiiifOne}\marg{N}\marg{IsOne}\marg{IsNotOne}\etype{fnn} expandably +checks if the first mandatory argument |N| is one or not one. It +then either executes the first or the second branch. Beware that both branches +must be present. -\subsection{Another table of primes} -\label{ssec:primesIII} +\subsection{\csh{xintiiifCmp}}\label{xintiiifCmp} -As a further example, let us dynamically generate a tabular with the first $50$ -prime numbers after $12345$. First we need a macro to test if a (short) number -is prime. Such a completely expandable macro was given in \autoref{ssec:primesI}, -here we consider a variant which will be slightly more efficient. This new -|\IsPrime| has two parameters. The first one is a macro which it redefines to -expand to the result of the primality test applied to the second argument. For -convenience we use the \href{http://ctan.org/pkg/etoolbox}{etoolbox} wrappers to -various |\ifnum| tests, although here there isn't anymore the constraint of -complete expandability (but using explicit |\if..\fi| in tabulars has its -quirks); equivalent tests are provided by \xintname, but they have some overhead -as they are able to deal with arbitrarily big integers. +\csa{xintiiifCmp}\marg{A}\marg{B}\marg{AB}\etype{ffnnn} +compares its first two arguments and chooses accordingly the correct branch. -\def\IsPrime #1#2% -{\edef\TheNumber {\the\numexpr #2}% positive integer - \ifnumodd {\TheNumber} - {\ifnumgreater {\TheNumber}{1} - {\edef\ItsSquareRoot{\xintiiSqrt \TheNumber}% - \xintFor ##1 in {\xintintegers [3+2]}\do - {\ifnumgreater {##1}{\ItsSquareRoot} - {\def#1{1}\xintBreakFor} - {}% - \ifnumequal {\TheNumber}{(\TheNumber/##1)*##1} - {\def#1{0}\xintBreakFor } - {}% - }} - {\def#1{0}}}% 1 is not prime - {\ifnumequal {\TheNumber}{2}{\def#1{1}}{\def#1{0}}}% -}% +\subsection{\csh{xintiiifEq}}\label{xintiiifEq} -\everb|@ -\def\IsPrime #1#2% """color[named]{PineGreen}#1=\Result, #2=tested number (assumed >0).;! -{\edef\TheNumber {\the\numexpr #2}%"""color[named]{PineGreen} hence #2 may be a count or \numexpr.;! - \ifnumodd {\TheNumber} - {\ifnumgreater {\TheNumber}{1} - {\edef\ItsSquareRoot{\xintiiSqrt \TheNumber}% - \xintFor """color{red}##1;! in {"""color{red}\xintintegers;! [3+2]}\do - {\ifnumgreater {"""color{red}##1;!}{\ItsSquareRoot} """color[named]{PineGreen}% "textcolor{red}{##1} is a \numexpr.;! - {\def#1{1}\xintBreakFor} - {}% - \ifnumequal {\TheNumber}{(\TheNumber/##1)*##1} - {\def#1{0}\xintBreakFor } - {}% - }} - {\def#1{0}}}% 1 is not prime - {\ifnumequal {\TheNumber}{2}{\def#1{1}}{\def#1{0}}}% -} -| +\csa{xintiiifEq}\marg{A}\marg{B}\marg{A=B}\marg{not(A=B)}\etype{ffnn} checks +equality of its two first arguments and executes the corresponding branch. -As we used \csbxint{For} inside a macro we had to double the |#| in its |#1| -parameter. Here is now the code which creates the prime table (the table has -been put in a \hyperref[primes]{float}, which should be found on page -\pageref{primes}): +\subsection{\csh{xintiiifGt}}\label{xintiiifGt} -\everb?@ -\newcounter{primecount} -\newcounter{cellcount} -\begin{figure*}[ht!] - \centering - \begin{tabular}{|*{7}c|} - \hline - \setcounter{primecount}{0}\setcounter{cellcount}{0}% - \xintFor """color{red}#1;! in {"""color{red}\xintintegers;! [12345+2]} \do -"""color[named]{PineGreen}% "textcolor{red}{#1} is a \numexpr.;! - {\IsPrime\Result{#1}% - \ifnumgreater{\Result}{0} - {\stepcounter{primecount}% - \stepcounter{cellcount}% - \ifnumequal {\value{cellcount}}{7} - {"""color{red}\the#1;! \\\setcounter{cellcount}{0}} - {"""color{red}\the#1;! &}} - {}% - \ifnumequal {\value{primecount}}{50} - {\xintBreakForAndDo - {\multicolumn {6}{l|}{These are the first 50 primes after 12345.}\\}} - {}% - }\hline -\end{tabular} -\end{figure*} -? +\csa{xintiiifGt}\marg{A}\marg{B}\marg{A>B}\marg{not(A>B)}\etype{ffnn} +checks if $A>B$ and executes the corresponding branch. -\begin{figure*}[ht!] - \centering\phantomsection\label{primes} - \begin{tabular}{|*{7}c|} - \hline - \setcounter{primecount}{0}\setcounter{cellcount}{0}% - \xintFor #1 in {\xintintegers [12345+2]} \do - {\IsPrime\Result{#1}% - \ifnumgreater{\Result}{0} - {\stepcounter{primecount}% - \stepcounter{cellcount}% - \ifnumequal {\value{cellcount}}{7} - {\the#1 \\\setcounter{cellcount}{0}} - {\the#1 &}} - {}% - \ifnumequal {\value{primecount}}{50} - {\xintBreakForAndDo - {\multicolumn {6}{l|}{These are the first 50 primes after 12345.}\\}} - {}% - }\hline -\end{tabular} -\end{figure*} +\subsection{\csh{xintiiifLt}}\label{xintiiifLt} -\subsection{Factorizing again} -\label{ssec:factorize} +\csa{xintiiifLt}\marg{A}\marg{B}\marg{A0| and |M^2-d=N| with +|M| the smallest (hence if |N=k^2| is a perfect square then |M=k+1|, |d=2k+1|). - This |code 6| could be extended to handle more general numbers, as - acceptable by \xintfracname. I have also written a non expandable version, - which is even faster, but this matters really only when handling hundreds or - rather thousands of values.} -% +\begin{everbatim*} +\xintAssign\xintiiSquareRoot {17000000000000000000000000}\to\A\B +\xintiiSub{\xintiiSqr\A}\B=\A\string^2-\B +\end{everbatim*} -The |\QSx| macro expands its list argument, which may thus be a macro; its -comma separated items must expand to integers or decimal numbers or fractions -or scientific notation as acceptable to \xintfracname, but if an item is -itself some (expandable) macro, this macro will be expanded each time the item -is considered in a comparison test! This is actually good if the macro expands -in one step to the digits, and there are many many digits, but bad if the macro -needs to do many computations. Thus |\QSx| should be used with either explicit -numbers or with items being macros expanding in one step to the numbers -(particularly if these numbers are very big). +A rational approximation to $\sqrt{|N|}$ is $|M|-\frac{|d|}{|2M|}$ which is a +majorant and the error is at most |1/2M| (if |N| is a perfect square |k^2| +this gives |k+1/(2k+2)|, not |k|.) -If the interest is only in \TeX{} integers, then one should replace the -|\xintifCmp| macro with a suitable conditional, possibly helped by tools such as -|\ifnumgreater|, |\ifnumequal| and |\ifnumless| from -\href{http://ctan.org/pkg/etoolbox}{etoolbox} (\LaTeX{} only; I didn't see a -direct equivalent to |\xintifCmp|.) Or, if we are dealing with decimal numbers -with at most four+four digits, then one should use suitable |\ifdim| tests. -Naturally this will boost consequently the speed, from having skipped all the -overhead in parsing fractions and scientific numbers as are acceptable by -\xintfracname macros, and subsequent treatment. +Package \xintfracname has \csbxint{FloatSqrt} for square roots of floating +point numbers. +\subsection{\csh{xintiiSqrt}, \csh{xintiiSqrtR}} +\label{xintiiSqrt}\label{xintiiSqrtR} + +\noindent|\xintiiSqrt|\n\ computes the largest integer whose square +is at most equal to |N|.\etype{f} |\xintiiSqrtR| +produces the rounded, not truncated, square root.\etype{f} \begin{everbatim*} -% THE QUICK SORT ALGORITHM EXPANDABLY -% \usepackage{xintfrac} in the preamble (latex) -\makeatletter -% use extra safe delimiters -\catcode`! 3 \catcode`? 3 -\def\QSx {\romannumeral0\qsx }% -% first we check if empty list (else \qsx@finish will not find a comma) -\def\qsx #1{\expandafter\qsx@a\romannumeral-`0#1,!,?}% -\def\qsx@a #1{\ifx,#1\expandafter\qsx@abort\else - \expandafter\qsx@start\fi #1}% -\def\qsx@abort #1?{ }% -\def\qsx@start {\expandafter\qsx@finish\romannumeral0\qsx@b,}% -\def\qsx@finish ,#1{ #1}% -% -% we check if empty of single and if not pick up the first as Pivot: -\def\qsx@b ,#1#2,#3{\ifx?#3\xintdothis\qsx@empty\fi - \ifx!#3\xintdothis\qsx@single\fi - \xintorthat\qsx@separate {#1#2}{}{}{#1#2}#3}% -\def\qsx@empty #1#2#3#4#5{ }% -\def\qsx@single #1#2#3#4#5?{, #4}% -\def\qsx@separate #1#2#3#4#5#6,% -{% - \ifx!#5\expandafter\qsx@separate@done\fi - \xintifCmp {#5#6}{#4}% - \qsx@separate@appendtosmaller - \qsx@separate@appendtoequal - \qsx@separate@appendtogreater {#5#6}{#1}{#2}{#3}{#4}% -}% -% -\def\qsx@separate@appendtoequal #1#2{\qsx@separate {#2,#1}}% -\def\qsx@separate@appendtogreater #1#2#3{\qsx@separate {#2}{#3,#1}}% -\def\qsx@separate@appendtosmaller #1#2#3#4{\qsx@separate {#2}{#3}{#4,#1}}% -% -\def\qsx@separate@done\xintifCmp #1% - \qsx@separate@appendtosmaller - \qsx@separate@appendtoequal - \qsx@separate@appendtogreater #2#3#4#5#6#7?% -{% - \expandafter\qsx@f\expandafter {\romannumeral0\qsx@b #4,!,?}{\qsx@b #5,!,?}{#3}% -}% -% -\def\qsx@f #1#2#3{#2, #3#1}% -% -\catcode`! 12 \catcode`? 12 -\makeatother +\begin{itemize}[nosep] +\item \xintiiSqrt {3000000000000000000000000000000000000} +\item \xintiiSqrtR {3000000000000000000000000000000000000} +\item \xintiiSqrt {\xintiiE {3}{100}} +\end{itemize} +\end{everbatim*} -% EXAMPLE -\begingroup -\edef\z {\QSx {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, - 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9}} -\meaning\z +\subsection{\csh{xintiiBinomial}}\label{xintiiBinomial} -\def\a {3.123456789123456789}\def\b {3.123456789123456788} -\def\c {3.123456789123456790}\def\d {3.123456789123456787} -\oodef\z {\QSx { \a, \b, \c, \d}}% -% The space before \a to let it not be expanded during the conversion from CSV -% values to List. The \oodef expands exactly twice (via a bunch of \expandafter's) -\meaning\z -\endgroup -\end{everbatim*} (the spaces after \string\d, etc... come from the use of the -|\meaning| primitive.) +|\xintiiBinomial{x}{y}|\etype{\numx\numx} computes binomial coefficients. -The choice of pivot as first element is bad if the list is already almost -sorted. Let's add a variant which will pick up the pivot index randomly. The -previous routine worked also internally with comma separated lists, but for a -change this one will use internally lists of braced items (the initial -conversion via \csbxint{CSVtoList} handles all potential spurious space -problems). +If |x<0| an out-of-range error is raised. Else, if |y<0| or if |x Requires availability of \pdfuniformdeviate <==== -% \usepackage{xintfrac, xinttools} in preamble -\makeatletter -\def\QSx {\romannumeral0\qsx }% This is a f-expandable macro. -% This converts from comma separated values on input and back on output. -% **** NOTE: these steps (and the other ones too, actually) are costly if input -% has thousands of items. -\def\qsx #1{\xintlistwithsep{, }% - {\expandafter\qsx@sort@a\expandafter{\romannumeral0\xintcsvtolist{#1}}}}% -% -% we check if empty or single or double and if not pick up the first as Pivot: -\def\qsx@sort@a #1% - {\expandafter\qsx@sort@b\expandafter{\romannumeral0\xintlength{#1}}{#1}}% -\def\qsx@sort@b #1{\ifcase #1 - \expandafter\qsx@sort@empty - \or\expandafter\qsx@sort@single - \or\expandafter\qsx@sort@double - \else\expandafter\qsx@sort@c\fi {#1}}% -\def\qsx@sort@empty #1#2{ }% -\def\qsx@sort@single #1#2{#2}% -\catcode`_ 11 -\def\qsx@sort@double #1#2{\xintifGt #2{\xint_exchangetwo_keepbraces}{}#2}% -\catcode`_ 8 -\def\qsx@sort@c #1#2{% - \expandafter\qsx@sort@sep@a\expandafter - {\romannumeral0\xintnthelt{\pdfuniformdeviate #1+\@ne}{#2}}#2?}% -\def\qsx@sort@sep@a #1{\qsx@sort@sep@loop {}{}{}{#1}}% -\def\qsx@sort@sep@loop #1#2#3#4#5% -{% - \ifx?#5\expandafter\qsx@sort@sep@done\fi - \xintifCmp {#5}{#4}% - \qsx@sort@sep@appendtosmaller - \qsx@sort@sep@appendtoequal - \qsx@sort@sep@appendtogreater {#5}{#1}{#2}{#3}{#4}% -}% -% -\def\qsx@sort@sep@appendtoequal #1#2{\qsx@sort@sep@loop {#2{#1}}}% -\def\qsx@sort@sep@appendtogreater #1#2#3{\qsx@sort@sep@loop {#2}{#3{#1}}}% -\def\qsx@sort@sep@appendtosmaller #1#2#3#4{\qsx@sort@sep@loop {#2}{#3}{#4{#1}}}% -% -\def\qsx@sort@sep@done\xintifCmp #1% - \qsx@sort@sep@appendtosmaller - \qsx@sort@sep@appendtoequal - \qsx@sort@sep@appendtogreater #2#3#4#5#6% -{% - \expandafter\qsx@sort@recurse\expandafter - {\romannumeral0\qsx@sort@a {#4}}{\qsx@sort@a {#5}}{#3}% -}% % -\def\qsx@sort@recurse #1#2#3{#2#3#1}% +It turns out that ${65000 \choose 32500}$ has \dtt{19565} digits and +${64000 \choose 32000}$ has \dtt{19264} digits. The latter can be evaluated +(this takes a long long time) but presumably not the former (I didn't try). +Reasonable feasible evaluations are with binomial coefficients not exceeding +about one thousand digits. + + % -\makeatother +The |binomial| function is available in the \xintexprname parsers. +\begin{everbatim*} +\xinttheiiexpr seq(binomial(100,i), i=47..53)\relax +\end{everbatim*} -% EXAMPLES -\begingroup -\edef\z {\QSx {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, - 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9}} -\meaning\z +See \csbxint{FloatBinomial} from package \xintfracname for the float variant, +used in \csbxint{floatexpr}. -\def\a {3.123456789123456789}\def\b {3.123456789123456788} -\def\c {3.123456789123456790}\def\d {3.123456789123456787} -\oodef\z {\QSx { \a, \b, \c, \d}}% -% The space before \a to let it not be expanded during the conversion from CSV -% values to List. The \oodef expands exactly twice (via a bunch of \expandafter's) -\meaning\z -\def\somenumbers{% -3997.6421, 8809.9358, 1805.4976, 5673.6478, 3179.1328, 1425.4503, 4417.7691, -2166.9040, 9279.7159, 3797.6992, 8057.1926, 2971.9166, 9372.2699, 9128.4052, -1228.0931, 3859.5459, 8561.7670, 2949.6929, 3512.1873, 1698.3952, 5282.9359, -1055.2154, 8760.8428, 7543.6015, 4934.4302, 7526.2729, 6246.0052, 9512.4667, -7423.1124, 5601.8436, 4433.5361, 9970.4849, 1519.3302, 7944.4953, 4910.7662, -3679.1515, 8167.6824, 2644.4325, 8239.4799, 4595.1908, 1560.2458, 6098.9677, -3116.3850, 9130.5298, 3236.2895, 3177.6830, 5373.1193, 5118.4922, 2743.8513, -8008.5975, 4189.2614, 1883.2764, 9090.9641, 2625.5400, 2899.3257, 9157.1094, -8048.4216, 3875.6233, 5684.3375, 8399.4277, 4528.5308, 6926.7729, 6941.6278, -9745.4137, 1875.1205, 2755.0443, 9161.1524, 9491.1593, 8857.3519, 4290.0451, -2382.4218, 3678.2963, 5647.0379, 1528.7301, 2627.8957, 9007.9860, 1988.5417, -2405.1911, 5065.8063, 5856.2141, 8989.8105, 9349.7840, 9970.3013, 8105.4062, -3041.7779, 5058.0480, 8165.0721, 9637.7196, 1795.0894, 7275.3838, 5997.0429, -7562.6481, 8084.0163, 3481.6319, 8078.8512, 2983.7624, 3925.4026, 4931.5812, -1323.1517, 6253.0945}% +In order to +evaluate binomial coefficients ${x \choose y}$ with $x>99999999$, or even +$x\geqslant 2^{31}$, but $y$ is not too large, one may use an ad hoc function +definition such as: +\begin{everbatim*} +\xintdeffunc mybigbinomial(x,y):=`*`(x-y+1..[1]..x)//y!;% +% without [1], x would have been limited to < 2^31 +\printnumber{\xinttheexpr mybigbinomial(98765432109876543210,10)\relax} +\end{everbatim*} -\oodef\z {\QSx \somenumbers}% produced as a comma+space separated list -% black magic as workaround to the shrinkability of spaces in last line... -\hsize 87\fontcharwd\font`0 -\lccode`~=32 -\lowercase{\def~}{\discretionary{}{}{\kern\fontcharwd\font`0}}\catcode32 13 -\noindent\phantom{000}\scantokens\expandafter{\meaning\z}\par -\endgroup + +To get this functionality in macro form, one can do: +\begin{everbatim*} +\xintNewIIExpr\MyBigBinomial [2]{`*`(#1-#2+1..[1]..#1)//#2!} +\printnumber{\MyBigBinomial {98765432109876543210}{10}} \end{everbatim*} -\fi % fin de si pas xetex +As we used \csa{xintNewIIExpr}, this macro will only accept strict integers. +Had we used \csa{xintNewExpr} the |\MyBigBinomial| would have accepted general +fractions or decimal numbers, and computed the product at the numerator +without truncating them to integers; but the factorial at the denominator +would truncate its argument. -All the previous examples were with numbers which could have been handled via -|\ifdim| tests rather than the \csbxint{ifCmp} macro from \xintfracname; using -|\ifdim| tests would naturally be faster. Even faster routine is |code 6| at -(link removed) which uses |\pdfescapestring| and a -Merge Sort algorithm. +\subsection{\csh{xintiiPFactorial}}\label{xintiiPFactorial} -We then turn to a graphical illustration of the algorithm.% -% -\footnote{I have rewritten (2015/11/21) the routine to do only once (and not thrice) the - needed calls to \csa{xintifCmp}, up to the price of one additional |\edef|, - although due to the context execution time on our side is not an issue and - moreover is anyhow overwhelmed by the TikZ's activities. Simultaneously I - have updated the code. - The - variant with the choice of pivot on the right has more overhead: the reason - is simply that we do not convert the data into an array, but maintain a list - of tokens with self-reorganizing delimiters.} -% -For simplicity the pivot is always chosen as the first list item. Then we also -give a variant which picks up the last item as pivot. -\begin{everbatim*} -% in LaTeX preamble: -% \usepackage{xintfrac, xinttools} -% \usepackage{color} -% or, when using Plain TeX: -% \input xintfrac.sty \input xinttools.sty -% \input color.tex -% -% Color definitions -\definecolor{LEFT}{RGB}{216,195,88} -\definecolor{RIGHT}{RGB}{208,231,153} -\definecolor{INERT}{RGB}{199,200,194} -\definecolor{INERTpiv}{RGB}{237,237,237} -\definecolor{PIVOT}{RGB}{109,8,57} -% Start of macro defintions -\makeatletter -% \catcode`? 3 % a bit too paranoid. Normal ? will do. -% -% argument will never be empty -\def\QS@cmp@a #1{\QS@cmp@b #1??}% -\def\QS@cmp@b #1{\noexpand\QS@sep@A\@ne{#1}\QS@cmp@d {#1}}% -\def\QS@cmp@d #1#2{\ifx ?#2\expandafter\QS@cmp@done\fi - \xintifCmp {#1}{#2}\tw@\@ne\z@{#2}\QS@cmp@d {#1}}% -\def\QS@cmp@done #1?{?}% -% -\def\QS@sep@A #1?{\QSLr\QS@sep@L #1\thr@@?#1\thr@@?#1\thr@@?}% -\def\QS@sep@L #1#2{\ifcase #1{#2}\or\or\else\expandafter\QS@sep@I@start\fi \QS@sep@L}% -\def\QS@sep@I@start\QS@sep@L {\noexpand\empty?\QSIr\QS@sep@I}% -\def\QS@sep@I #1#2{\ifcase#1\or{#2}\or\else\expandafter\QS@sep@R@start\fi\QS@sep@I}% -\def\QS@sep@R@start\QS@sep@I {\noexpand\empty?\QSRr\QS@sep@R}% -\def\QS@sep@R #1#2{\ifcase#1\or\or{#2}\else\expandafter\QS@sep@done\fi\QS@sep@R}% -\def\QS@sep@done\QS@sep@R {\noexpand\empty?}% -% -\def\QS@loop {% - \xintloop - % pivot phase - \def\QS@pivotcount{0}% - \let\QSLr\DecoLEFTwithPivot \let\QSIr \DecoINERT - \let\QSRr\DecoRIGHTwithPivot \let\QSIrr\DecoINERT - \centerline{\QS@list}% - % sorting phase - \ifnum\QS@pivotcount>\z@ - \def\QSLr {\QS@cmp@a}\def\QSRr {\QS@cmp@a}% - \def\QSIr {\QSIrr}\let\QSIrr\relax - \edef\QS@list{\QS@list}% compare - \let\QSLr\relax\let\QSRr\relax\let\QSIr\relax - \edef\QS@list{\QS@list}% separate - \def\QSLr ##1##2?{\ifx\empty##1\else\noexpand \QSLr {{##1}##2}\fi}% - \def\QSIr ##1##2?{\ifx\empty##1\else\noexpand \QSIr {{##1}##2}\fi}% - \def\QSRr ##1##2?{\ifx\empty##1\else\noexpand \QSRr {{##1}##2}\fi}% - \edef\QS@list{\QS@list}% gather - \let\QSLr\DecoLEFT \let\QSRr\DecoRIGHT - \let\QSIr\DecoINERTwithPivot \let\QSIrr\DecoINERT - \centerline{\QS@list}% - \repeat }% -% -% \xintFor* loops handle gracefully empty lists. -\def\DecoLEFT #1{\xintFor* ##1 in {#1} \do {\colorbox{LEFT}{##1}}}% -\def\DecoINERT #1{\xintFor* ##1 in {#1} \do {\colorbox{INERT}{##1}}}% -\def\DecoRIGHT #1{\xintFor* ##1 in {#1} \do {\colorbox{RIGHT}{##1}}}% -\def\DecoPivot #1{\begingroup\color{PIVOT}\advance\fboxsep-\fboxrule\fbox{#1}\endgroup}% -% -\def\DecoLEFTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do - {\xintifForFirst {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}}% -\def\DecoINERTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do - {\xintifForFirst {\colorbox{INERTpiv}{##1}}{\colorbox{INERT}{##1}}}}% -\def\DecoRIGHTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do - {\xintifForFirst {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}}% +|\xintiiPFactorial{a}{b}|\etype{\numx\numx} computes the partial factorial +|(a+1)(a+2)...b|. For |a=b| the product is considered empty hence returns |1|. + +%\begin{framed} + The allowed range % -\def\QuickSort #1{% warning: not compatible with empty #1. - % initialize, doing conversion from comma separated values to a list of braced items - \edef\QS@list{\noexpand\QSRr{\xintCSVtoList{#1}}}% many \edef's are to follow anyhow -% earlier I did a first drawing of the list, here with the color of RIGHT elements, -% but the color should have been for example white, anyway I drop this first line - %\let\QSRr\DecoRIGHT - %\par\centerline{\QS@list}% % - % loop as many times as needed - \QS@loop }% % -% \catcode`? 12 % in case we had used a funny ? as delimiter. -\makeatother -%% End of macro definitions. -%% Start of Example -\begingroup\offinterlineskip -\small -% \QuickSort {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, -% 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9} -% \medskip -% with repeated values -\QuickSort {1.0, 0.5, 0.3, 0.8, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, - 1.3, 1.1, 0.7, 0.3, 1.6, 0.6, 0.3, 0.8, 0.2, 0.8, 0.7, 1.2} -\endgroup + is $-100000000\leqslant a, b\leqslant99999999$. + The + rule is to interpret the formula as the product of the + $j$'s such that $ab$ or negative arguments, the definitive rules have not yet + been fixed. + +\begin{everbatim*} +\xintiiPFactorial {100}{130} \end{everbatim*} +%\end{framed} -Here is the variant which always picks the pivot as the rightmost element. +This theoretical range allows computations whose result values would have more +than the roughly 19950 digits that the arithmetics of \xintname can handle. In +such cases, the computation will end up in a low-level \TeX{} error after a +long time. +The |pfactorial| function is available in the \xintexprname parsers. \begin{everbatim*} -\makeatletter -% -\def\QS@cmp@a #1{\noexpand\QS@sep@A\expandafter\QS@cmp@d\expandafter - {\romannumeral0\xintnthelt{-1}{#1}}#1??}% -% -\def\DecoLEFTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do - {\xintifForLast {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}} -\def\DecoINERTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do - {\xintifForLast {\colorbox{INERTpiv}{##1}}{\colorbox{INERT}{##1}}}} -\def\DecoRIGHTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do - {\xintifForLast {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}} -\def\QuickSort #1{% - % initialize, doing conversion from comma separated values to a list of braced items - \edef\QS@list{\noexpand\QSLr {\xintCSVtoList{#1}}}% many \edef's are to follow anyhow - % - % loop as many times as needed - \QS@loop }% -\makeatother -\begingroup\offinterlineskip -\small -% \QuickSort {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, -% 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9} -% \medskip -% with repeated values -\QuickSort {1.0, 0.5, 0.3, 0.8, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, - 1.3, 1.1, 0.7, 0.3, 1.6, 0.6, 0.3, 0.8, 0.2, 0.8, 0.7, 1.2} -\endgroup +\xinttheiiexpr pfactorial(100,130)\relax \end{everbatim*} -The choice of the first or last item as pivot is not a good one as nearly -ordered lists will take quadratic time. But for explaining the algorithm via a -graphical interpretation, it is not that bad. If one wanted to pick up the -pivot randomly, the routine would have to be substantially rewritten: in -particular the |\Deco..withPivot| macros need to know where the pivot is, and -currently this is implemented by using either |\xintifForFirst| or -|\xintifForLast|. +See \csbxint{FloatPFactorial} from package \xintfracname for the float +variant, used in \csbxint{floatexpr}. -\etocdepthtag.toc {macros} -\addtocontents{toc}{\gdef\string\sectioncouleur{{joli}}} -\addtocontents{toc}{\gdef\string\SKIPSECTIONINTERSPACE{\kern\smallskipamount}} -\renewcommand{\etocaftertochook}{\addvspace{\bigskipamount}} -\clearpage +In case values are needed with $b>99999999$, or even $b\geqslant 2^{31}$, but +$b-a$ is not too large, one may use an ad hoc function definition such as: +\begin{everbatim*} +\xintdeffunc mybigpfac(a,b):=`*`(a+1..[1]..b);% +% without [1], b would have been limited to < 2^31 +\printnumber{\xinttheexpr mybigpfac(98765432100,98765432120)\relax} +\end{everbatim*} -\expandafter\let\csname Old examplesnameUp\endcsname\undefined -\csname xintbundlenameUp\endcsname +\subsection{\csh{xintiiMax}}\label{xintiiMax} -\def\xintRunningHeader{{\inheadertrue\catcode`,12\relax - \DOCxintfrontpage, - \xintbundlename, - \xintkernelname, - \xintcorename, - \xintname, - \xintfracname, - \xintbinhexname, - \xintgcdname, - \xintseriesname, - \xintcfracname, - \xinttoolsname}} -\markboth{\makebox[0pt]{\xintRunningHeader}}{\makebox[0pt]{\xintRunningHeader}} +|\xintiiMax|\n\m\etype{ff} returns the largest of the two in the sense +of the order structure on the relative integers (\emph{i.e.} the right-most +number if they are put on a line with positive numbers on the right): +|\xintiiMax {-5}{-6}|\dtt{=\xintiiMax{-5}{-6}}. -\part{The macro layer for expandable computations: \xintcorename, \xintname, - \xintfracname,...} -\RaisedLabel[15]{sec:bundle} +\subsection{\csh{xintiiMin}}\label{xintiiMin} +|\xintiiMin|\n\m\etype{ff} returns the smallest of the two in the sense of the +order structure on the relative integers (\emph{i.e.} the left-most number if +they are put on a line with positive numbers on the right): |\xintiiMin +{-5}{-6}|\dtt{=\xintiiMin{-5}{-6}}. -\begin{framed} - WARNING ! +\subsection{\csh{xintiiMaxof}}\label{xintiiMaxof} - The documentation is old, although we try to keep updated the list of macros - defined by all the packages. -\end{framed} +\csa{xintiiMaxof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns the +maximum. The list argument may be a macro, it is \fexpan ded first. -\etocsetnexttocdepth{section} -\localtableofcontents +\subsection{\csh{xintiiMinof}}\label{xintiiMinof} -\section{The \xintname bundle} +\csa{xintiiMinof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns the +minimum. The list argument may be a macro, it is \fexpan ded first. -\localtableofcontents +\subsection{\csh{xintifTrueAelseB}} +\label{xintifTrueAelseB} -\subsection{Characteristics} +\csa{xintifTrueAelseB}\marg{f}\marg{true branch}\marg{false branch}\etype{fnn} +is a synonym for \csbxint{iiifNotZero}. -\begin{framed} - The main characteristics are: - \begin{enumerate} - \item exact algebra on ``big numbers'', integers as well as - fractions, - \item floating point variants with user-chosen precision, - \item the computational macros are compatible with expansion-only context, - \item the bundle comes with parsers (integer-only, or handling fractions, or - doing floating point computations) of infix operations implementing - beyond infix operations extra features such as dummy variables. - \end{enumerate} +{\small + \noindent |\xintiiifnotzero| is lowercase companion macro.\par } +Note 1: as it does only \fexpan sion on its argument it fails with inputs such +as |--0|. But with \xintfracname loaded, it does work fine if nested with +other \xintfracname macros, because the output format of such macros is fine +as input to \csbxint{iiifNotZero}. This remark applies to all other «Boolean +logic» macros next. - Since |1.2| ``big numbers'' must have less than about \dtt{19950} digits: - the maximal number of digits for addition is at \dtt{19968} digits, and it - is \dtt{19959} for multiplication. The reasonable range of use of the - package is with numbers of up to a few hundred digits.\footnotemark +Note 2: prior to |1.2o| this macro was using \csbxint{ifNotZero} which applies +\csbxint{Num} to its argument (or gets redefined by \xintfracname to handle +general decimal numbers or fractions). Hence it would have +worked with input such as |--0|. But it was decided at |1.2o| that the +overhead was not worth it. The same remark applies to the other «Boolean +logic» type macros next. - \TeX\ does not know off-hand how to print on the page such very long - numbers, see \autoref{ssec:printnumber}. -\end{framed} -\footnotetext{For example multiplication of integers having from \dtt{50} to - \dtt{100} digits takes roughly of the order of the millisecond on a 2012 - desktop computer. I compared this to using Python3: using timeit module on a - wrapper defined as |return w*z| with random integers of \dtt{100} digits, I - observe on the same computer a computation time of roughly $4.10^{-7}$s per - call. And with |return str(w*z)| then this becomes more like $16.10^{-7}$s - per call. And with |return str(int(W)*int(Z))| where |W| and |Z| are - strings, this becomes about $26.10^{-7}$s (I am deliberately ignoring - Python's Decimal module here...) Anyway, my sentence from earlier version of - this documentation: \emph{this is, I guess, at least about 1000 times slower - than what can be expected with any reasonable programming language,} is - about right. I then added: \emph{nevertheless as compilation of a typical - \LaTeX\ document already takes of the order of seconds and even dozens of - seconds for long ones, this leaves room for reasonably many computations - via \xintexprname or via direct use of the macros of - \xintname/\xintfracname.}} +\subsection{\csh{xintifFalseAelseB}} +\label{xintifFalseAelseB} -Integers with only $10$ digits and starting with a $3$ already exceed the -\TeX{} bound; and \TeX{} does not have a native processing of floating point -numbers (multiplication by a decimal number of a dimension register is allowed ---- this is used for example by the -\href{http://mirrors.ctan.org/graphics/pgf/base}{pgf} basic math engine.) +\csa{xintifFalseAelseB}\marg{f}\marg{false branch}\marg{true + branch}\etype{fnn} is a synonym for \csbxint{iiifZero}. -\TeX{} elementary operations on numbers are done via the non-expandable -\emph{\char92advance, \char92multiply, \emph{and} \char92divide} assignments. -This was changed with \eTeX{}'s |\numexpr| which does expandable computations -using standard infix notations with \TeX{} integers. But \eTeX{} did not -modify the \TeX{} bound on acceptable integers, and did not add floating point -support. +{\small + \noindent |\xintiiifzero| is lowercase companion macro.\par } -The \href{https://ctan.org/pkg/bigintcalc}{bigintcalc} package by -\textsc{Heiko Oberdiek} provided expandable macros (using some of |\numexpr| -possibilities, when available) on arbitrarily big integers, beyond the \TeX{} -bound. It does not provide an expression parser.% -% -\footnote{One can currently use package - \href{http://ctan.org/pkg/bnumexpr}{bnumexpr} to associate the |bigintcalc| - macros with an expression parser. This may be unavailable in future if - |bnumexpr| becomes more tightly associated with future evolutions or - variants of \xintcorename.} -% -\xintname did it again using more of |\numexpr| for higher speed, and in a -later evolution added handling of exact fractions, of scientific numbers, and -an expression parser. Arbitrary precision floating points operations were -added as a derivative, and not part of the initial design goal. +\subsection{\csh{xintNOT}}\label{xintNOT} -The concept of signed infinities, signed zeroes, |NaN|'s, error -traps\dots,\footnote{The latter exist as work-in-progress for some time in the - source code.} have not been implemented, only the notion of `scientific -notation with a given number of significant figures'.% -% -\footnote{multiplication of two floats with |P=\xinttheDigits| digits is - first done exactly then rounded to |P| digits, rather than using a - specially tailored multiplication for floating point numbers which - would be more efficient (it is a waste to evaluate fully the - multiplication result with |2P| or |2P-1| digits.)} +\csa{xintNOT}\etype{f} is a synonym for \csa{xintiiIsZero}. -The \LaTeX3 project has implemented expandably floating-point computations with -\dtt{16} significant figures -(\href{https://ctan.org/pkg/l3kernel}{l3fp}), including -functions such as exp, log, sine and cosine.\footnote{at the time of writing (2014/10/28) the - \href{https://ctan.org/pkg/l3kernel}{l3fp} (exactly represented) floating - point numbers have their exponents limited to $\pm$\dtt{9999}.} -% +{\small |\xintiiiszero| serves as lowercase companion macro.\par} -More directly related to the \xintname bundle there is the \liiibigint{} -package, also devoted to big integers and in development a.t.t.o.w (2015/10/09, -no division yet). It is part of the experimental trunk of the -\href{http://latex-project.org}{\LaTeX3 Project} and provides an expression -parser for expandable arithmetic with big integers. Its author Bruno -\textsc{Le Floch} succeeded brilliantly into implementing expandably the -Karatsuba multiplication algorithm and he achieves \emph{sub-quadratic growth - for the computation time}. This shows up very clearly with numbers having -thousands of digits, up to the maximum which a.t.t.o.w is at $8192$ digits. +\subsection{\csh{xintAND}}\label{xintAND} -The \liiibigint{} multiplication from late |2015| is observed to be roughly -|3x--4x| faster than the one from \csbxint{iiexpr} in the range of \dtt{4000} -to \dtt{5000} digits integers, and isn't far from being |9x| faster at -\dtt{8000} digits. On the other hand \csbxint{iiexpr}'s multiplication is -found to be on average roughly |2.5x| faster than \liiibigint's for numbers up -to \dtt{100} digits and the two packages achieve about the same speed at -\dtt{900} digits: but each such multiplication of numbers of \dtt{900} digits -costs about one or two tenths of a second on a 2012 desktop computer, whereas -the order of magnitude is rather the |ms| for numbers with \dtt{50--100} -digits.\footnote{I have tested this again on |2016/12/19|, but the macros have - not changed on the \liiibigint{} side and barely on the \xintcorename side, - hence I got again the same results\dots} +|\xintAND{f}{g}|\etype{ff} returns \dtt{1} if |f!=0| and |g!=0| and \dtt{0} +otherwise. -Even with the superior \liiibigint{} Karatsuba multiplication it takes about -|3.5s| on this 2012 desktop computer for a single multiplication of two -\dtt{5000}-digits numbers. Hence it is not possible to do routinely such -computations in a document. I have long been thinking that without the -expandability constraint much higher speeds could be achieved, but perhaps I -have not given enough thought to sustain that optimistic stance.\footnote{The - \href{https://ctan.org/pkg/apnum}{apnum} package implements - (non-expandably) arbitrary precision fixed point algebra and (v1.6) - functions exp, log, sqrt, the trigonometrical direct and inverse functions.} +\subsection{\csh{xintOR}}\label{xintOR} -I remain of the opinion that if one really wants to do computations with -\emph{thousands} of digits, one should drop the expandability requirement. -Indeed, as clearly demonstrated long ago by the -\href{https://ctan.org/pkg/pi}{pi computing file} by \textsc{D. Roegel} one -can program \TeX{} to compute with many digits at a much higher speed than -what \xintname achieves: but, direct access to memory storage in one form or -another seems a necessity for this kind of speed and one has to renounce at -the complete expandability.% -% -\footnote{The Lua\TeX{} project possibly makes endeavours such as \xintname - appear even more insane that they are, in truth: \xintname is able to handle - fast enough computations involving numbers with less than one hundred digits - and brings this to all engines.} +|\xintOR{f}{g}|\etype{ff} returns \dtt{1} if |f!=0| or |g!=0| and \dtt{0} +otherwise. -\subsection{Floating point evaluations} -\label{ssec:floatingpoint} +\subsection{\csh{xintXOR}}\label{xintXOR} -Floating point macros are provided by package \xintfracname to work with a -given arbitrary precision |P|. The default value is $P=16$ meaning that the -significands of the produced (non-zero) numbers have \dtt{16} decimal digits. -The syntax to set the precision to |P| is +|\xintXOR{f}{g}|\etype{ff} returns \dtt{1} if exactly one of |f| or |g| +is true (i.e. non-zero), else \dtt{0}. + +\subsection{\csh{xintANDof}}\label{xintANDof} + +\csa{xintANDof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns \dtt{1} if +all are true (i.e. non zero) and \dtt{0} otherwise. The list argument may be a +macro, it (or rather its first token) is \fexpan ded first to deliver its +items. + +\subsection{\csh{xintORof}}\label{xintORof} + +\csa{xintORof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns \dtt{1} if at +least one is true (i.e. does not vanish), else it produces \dtt{0}. The list +argument may be a macro, it is \fexpan ded first. + +\subsection{\csh{xintXORof}}\label{xintXORof} + +\csa{xintXORof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns \dtt{1} if an +odd number of them are true (i.e. do not vanish), else it produces \dtt{0}. +The list argument may be a macro, it is \fexpan ded first. + +\subsection{\csh{xintiiGCD}} +\label{xintiiGCD} + +|\xintiiGCD|\n\m\etype{ff} computes the greatest common divisor. It is +positive, except when both |N| and |M| vanish, in which case the macro returns +zero. % -\centeredline{|\xintDigits:=P\relax|} +\leftedline{\csa{xintiiGCD}|{10000}{1113}|\dtt{=\xintiiGCD{10000}{1113}}} % -The value is local to the group or environment (if using \LaTeX). To query the -current value use \csbxint{theDigits}. +\leftedline{|\xintiiGCD{123456789012345}{9876543210321}=|\dtt + {\xintiiGCD{123456789012345}{9876543210321}}} -Most floating point macros accept an optional first argument |[P]| which then -sets the target precision and replaces the |\xintDigits| assigned value (the -|[P]| must be repeated if the arguments are themselves \xintfracname macros -with arguments of their own.) In this section |P| refers to the prevailing -|\xinttheDigits| float precision or to the target precision set in this way as -an optional argument. +At |1.3d|, this macro (which is used by the \func{gcd} function in +\csbxint{iiexpr}) was copied over to \xintname, thus removing a partial +dependency of \xintexprname on \xintgcdname. -\csbxint{floatexpr}|[Q]...\relax| also admits an optional argument |[Q]| but -it has an altogether different meaning: the computations are always done with -the prevailing |\xinttheDigits| precision and the optional argument |Q| is -used for the final rounding. This makes sense only if |Q<\xinttheDigits| and -is intended to clean up the result from dubious last digits. +At |1.4| \xintgcdname requires \xintname and the latter is thus the one +providing the macro. +\subsection{\csh{xintiiLCM}} +\label{xintiiLCM} - +|\xintiiLCM|\n\m\etype{ff} computes the least common multiple. It is positive, +except if one of |N| or |M| vanish, in which case the macro returns zero. +% +\leftedline{\csa{xintiiLCM}|{10000}{1113}|\dtt{=\xintiiLCM{10000}{1113}}} +% +\leftedline{|\xintiiLCM{123456789012345}{9876543210321}=|\dtt + {\xintiiLCM{123456789012345}{9876543210321}}} +At |1.3d|, this macro (which is used by the \func{lcm} function in +\csbxint{iiexpr}) was copied over to \xintname, thus removing a partial +dependency of \xintexprname on \xintgcdname. +At |1.4| \xintgcdname requires \xintname and the latter is thus the one +providing the macro. +\subsection{\csh{xintiiGCDof}}\label{xintiiGCDof} -\begin{framed} - The |IEEE 754|\footnotemark\ requirement of \emph{correct rounding} for - addition, subtraction, multiplication, division and square root is achieved - (in arbitrary precision) by the macros of \xintfracname hence also by the - infix operators |+|, |-|, |*|, |/|. +\csa{xintiiGCDof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast f}} computes the +greatest common divisor of the integers |a|, |b|, \dots{}. It is a support +macro for the |gcd()| function of the \csbxint{iiexpr} parser. - This means that for operands given with at most |P| significant digits - (and arbitrary exponents) the output coincides exactly with the rounding - of the exact theoretical result (barring overflow or underflow). +It replaces the \csbxint{GCDof} which was formerly provided by \xintgcdname +and is now available via \xintfracname in a version handling also +fractions. -{\footnotesize Due to a typographical oversight, this documentation - (up to |1.2j|) adjoined |^| and |**| to the above list of - infix operators. But as - is explained in \autoref{xintFloatPower}, what is guaranteed regarding - integer powers is an error of at most |0.52ulp|, not the correct rounding. - Half-integer powers are computed as square roots of integer powers.\par }% +\subsection{\csh{xintiiLCMof}}\label{xintiiLCMof} - The rounding mode is ``round to nearest, ties away from zero''. - It is not customizable. +\csa{xintiiLCMof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast f}} computes the +least common multiple of the integers |a|, |b|, \dots{}. It is a support +macro for the |lcm()| function of the \csbxint{iiexpr} parser. - Currently \xintfracname has no notion of |NaN|s or signed infinities or signed - zeroes, but this is intended for the future. -\end{framed} -% -\footnotetext{The |IEEE 754-1985| standard was for hardware implementations of - binary floating-point arithmetic with a specific value for the precision - ($24$ bits for single precision, $53$ bits for double precision). The newer - {\texttt{IEEE 754-2008}} - (\url{https://en.wikipedia.org/wiki/IEEE_floating_point}) normalizes five - basic formats, three binaries and two decimals ($16$ and $34$ decimal - digits) and discusses extended formats with higher precision. These - standards are only indirectly relevant to libraries like \xintname dealing - with arbitrary precision.% -} +It replaces the \csbxint{LCMof} which was formerly provided by \xintgcdname +and is now available via \xintfracname in a version handling also +fractions. +\subsection{\csh{xintLen}}\label{xintLen} -Since release -|1.2f|, square root extraction achieves correct rounding in arbitrary -precision. +|\xintLen|\etype{\Numf} is originally an alias for \csbxint{iLen}. But with +\xintfracname loaded its meaning is \hyperref[xintLenFrac]{modified} to accept +more general inputs. -The power -function in the expression parsers accepts integer exponents and also -half-integer exponents for float expressions.\footnote{Half-integer exponents - work inside expressions, but not via the \csbxint{FloatPower} macro.} -A preliminary implementation of fractional powers is available see -\xintlogname. Trigonometrical functions are available (\xinttrigname). +% \subsection{Removed macros (they require \xintfracname)}\label{ssec:xintdeprecated} +% These macros now require \xintfracname. They have been removed from \xintname +% at |1.3|. +% |\xintEq|, +% |\xintNeq|, +% |\xintGeq|, +% |\xintGt|, +% |\xintLt|, +% |\xintGtorEq|, +% |\xintLtorEq|, +% |\xintIsZero|, +% |\xintIsNotZero|, +% |\xintIsOne|, +% |\xintOdd|, +% |\xintEven|, +% |\xintifSgn|, +% |\xintifCmp|, +% |\xintifEq|, +% |\xintifGt|, +% |\xintifLt|, +% |\xintifZero|, +% |\xintifNotZero|, +% |\xintifOne|, +% |\xintifOdd|. -The maximal floating point decimal exponent is currently -\dtt{\number"7FFFFFFF} which is the maximal number handled by \TeX. The -minimal exponent is its opposite. But this means that overflow or underflow -are detected only via low-level |\numexpr| arithmetic overflows which are -basically un-recoverable. Besides there are some border effects as the -routines need to add or subtract lengths of numbers from exponents, possibly -triggering the low-level overflows. In the future not only the Precision but -also the maximal and minimal exponents |Emin| and |Emax| will be specifiable -by the user. +% With the exception of |\xintNeq| which was renamed to |\xintNotEq|, the above +% listed macros all belong to \xintfracname. -Since |1.2f|, the float macros round their inputs to the target precision |P| -before further processing. Formerly, the initial rounding was done to |P+2| -digits (and at least |P+3| for the power operation.) +% At |1.4|, these macros formerly available via \xintgcdname have been moved to +% \xintfracname as well. +% |\xintGCD|, +% |\xintLCM|, +% |\xintGCDof|, +% |\xintLCMof|. -The more ambitious model would be for the computing macros to obey the -intrinsic precision of their inputs, i.e. to compute the correct rounding to -|P| digits of the exact mathematical result corresponding to inputs allowed to -have their own higher precision.% -% -\footnote{The |MPFR| library - \url{http://www.mpfr.org/} implements this but it does not know fractions!} -% -This would be feasible by \xintfracname which after all knows how to compute -exactly, but I have for the time being decided that for reasons of efficiency, -the chosen model is the one of rounding inputs to the target precision first. +% \subsection{Removed macros (they used \csh{xintNum})}\label{ssec:xintdeprecatedNum} -The float macros of \xintfracname have to handle inputs which -not only may have much more digits than the target float precision, but may -even be fractions: in a way this means infinite precision. +% These macros filtered their arguments via \csbxint{Num}. They got deprecated +% at |1.2o| and removed at |1.3|: +% |\xintMON|, +% |\xintMMON|, +% |\xintiMax|, +% |\xintiMin|, +% |\xintiMaxof|, +% |\xintiMinof|, +% |\xintiSquareRoot|, +% |\xintiSqrt|, +% |\xintiSqrtR|, +% |\xintiBinomial|, +% |\xintiPFactorial|. -From releases |1.08a| to |1.2j| a fraction input $AeM/BeN$ had its numerator -and denominator $A$ and $B$ truncated to |Q+2| digits of precision, then the -substituted fraction was correctly rounded to |Q| digits of precision (usually -with |Q| set to |P+2|) and then the operation was implemented on such rounded -inputs. But this meant that two fractions representing the same rational -number could end up being rounded differently (with a difference of one unit -in the last place), if it had numerators and denominators with at least |Q+3| -digits. +\subsection{(WIP) \csh{xintRandomDigits}}\label{xintRandomDigits} -Starting with release |1.2k| a fractional input $AeM/BeN$ is handled -intrinsically: the fraction, independently of its representation $AeM/BeN$, is -\emph{correctly rounded} to |P| digits during the input parsing. Hence the -output depends only on its arguments as mathematical fractions and not on -their representatives as quotients. +\begin{framed} + All randomness related macros are Work-In-Progress: implementation and user + interface may change. They work only if the \TeX\ engine provides the + \csa{uniformdeviate} or \csa{pdfuniformdeviate} primitive. See + \csbxint{UniformDeviate} for additional information. +\end{framed} -Notice that in float expressions, the |/| is treated as operator, and is -applied to arguments which are generally already |P|-floats, hence the above -discussion becomes relevant in this context only for the special input form -|qfloat(A/B)| or when using a sub-expression |\xintexpr A/B\relax| embedded in -the float expression with |A| or |B| having more digits than the prevailing -float precision |P|. +|\xintRandomDigits{N}|\etype{\numx} expands in two steps to |N| random decimal +digits. The argument must be non-negative and is limited by \TeX\ memory +parameters. +On \TeX Live 2018 with input save stack size at \dtt{5000} the +maximal allowed |N| is at most \dtt{19984} (tested within a |\write| to an +auxiliary file, the macro context may cause a reduced maximum). +\begin{everbatim*} +\pdfsetrandomseed 271828182 +\xintRandomDigits{92} +\end{everbatim*} +\TeXnote the digits are produced eight by eight by the same method which would +result from \csbxint{UniformDeviate}|{100000000}| but with less overhead. +% \subsection{\csh{\xintOneRandomDigit}}\label{xintOneRandomDigit} +\subsection{(WIP) \csh{xintXRandomDigits}}\label{xintXRandomDigits} +|\xintXRandomDigits{N}|\retype{\numx} expands under exhaustive expansion +(|\edef|, |\write|, |\csname| ...) to |N| random decimal +digits. The argument must be non-negative. +For example: +\begin{everbatim} +\newwrite\out +\immediate\openout\out=\jobname-out.txt +\immediate\write\out{\xintXRandomDigits{4500000}} +\immediate\closeout\out +\end{everbatim} +creates a \dtt{4500001} bytes file (it ends with a line feed character). +Trying with \dtt{5000000} raises this error: +\begin{everbatim} +Runaway text? +588875947168511582764514135070217555354479805240439407753451354223283\ETC. +! TeX capacity exceeded, sorry [main memory size=5000000]. + 666515098 + +l.15 ...ate\write\out{\xintXRandomDigits{5000000}} + +No pages of output. +Transcript written on temp.log. +\end{everbatim} +This can be lifted by increasing the \TeX\ memory settings (installation +dependent). +\TeXnote the digits are produced eight by eight by the same method which would +result from \csbxint{UniformDeviate}|{100000000}| but with less overhead. -\subsection{Expansion matters} +\subsection{(WIP) \csh{xintiiRandRange}}\label{xintiiRandRange} -\subsubsection{Full expansion of the first token} -\label{ssec:expansions} +|\xintiiRandRange{A}|\etype{f} expands to a random (big) integer |N| +such that |0<=N8|, if we proceed +immediately after having set the seed. If we add some entropy in any way, then +it is slightly more credible; but I think that for each seed the period is +something like |2^{27}(2^{55}-1)55|,% % -An expandable macro can not execute a |\def| or an |\edef|. But the macro must -expand its arguments to find the digits it is supposed to manipulate. \TeX{} -provides a tool to do the job of (expandable !) repeated expansion of the -first token found until hitting something non expandable, such as a digit, a -|\def| token, a brace, a |\count| token, etc... is found. A space token also -will stop the expansion (and be swallowed, contrarily to the non-expandable -tokens). +\footnote{Compare the result of exercise 3.2.2-30 in TAOCP, vol II.} +% +so we expect at most about |2^{110}55| +``points in time'', and this is already small compared to the |10^40| +from example above. Thus already we are very far from being intrinsically +able to generate all numbers with fourty digits as random numbers, and this +makes the previous section about usage of \csbxint{XRandomDigits} to generate +millions of digits a bit comical... -By convention in this manual \fexpan sion (``full expansion'' or ``full first -expansion'') will be this \TeX{} process of expanding repeatedly the first -token seen. For those familiar with \LaTeX3 (which is not used by \xintname) -this is what is called in its documentation full expansion (whereas expansion -inside |\edef| would be described I think as ``exhaustive'' expansion). +\TeXnote the digits are produced eight by eight by the same method which would +result from \csbxint{UniformDeviate}|{100000000}| but with less overhead. -Most of the package macros, and all those dealing with computations% -% -\footnote{except \csbxint{XTrunc}.}, -% -are expandable in the strong sense that they expand to their final result via -this \fexpan sion. This will be signaled in their descriptions via a -\etype{}star in the margin. +\subsection{(WIP) \csh{xintiiRandRangeAtoB}}\label{xintiiRandRangeAtoB} -These macros not only have this property of \fexpan dability, they all begin -by first applying \fexpan sion to their arguments. Again from \LaTeX3's -conventions this will be signaled by a% -% -\ntype{{\setbox0 \hbox{\Ff}\hbox to \wd0 {\hss f\hss}}} -% -margin annotation next to the description of the arguments. +|\xintiiRandRangeAtoB{A}{B}|\etype{ff} expands to a random (big) integer |N| +such that |A<=N2 143\else 33\fi - 0^2\relax|$\to$\dtt{\xinttheiexpr \ifnum3>2 143\else 33\fi 0^2\relax - =1430\char`\^2}} -% - \endgroup +\xintfracname loads automatically \xintcorename and \xintname and inherits +their macro definitions. Only these two are redefined: +\hyperref[xintNumFrac]{\string\xintNum} and +\hyperref[xintLenFrac]{\string\xintLen}. As explained in \autoref{ssec:inputs} +and \autoref{ssec:outputs} the interchange format for the \xintfracname +macros, i.e. |A/B[N]|, is not understood by the |ii|-named macros of +\xintcorename/\xintname which expect the so-called strict integer format. +Hence, to use such an |ii|-macro with an output from an \xintfracname macro, +an extra \csbxint{Num} wrapper is required. But macros already defined by +\xintfracname cover most use cases hence this should be a rarely needed. -\item after the definition |\def\x {12}|, one can not use - {\color{blue}|-\x|} as input to one of the package macros: the \fexpan sion - will act only on the minus sign, hence do nothing. The only way is to use the - \csbxint{Opp} macro (or \csbxint{iiOpp} which is integer only) - which obtains the opposite of a given number. +In the macro descriptions, the variable |f|\ntype{\Ff} and the margin +indicator stand for the \xintfracname input format for integers, scientific +numbers, and fractions as described in \autoref{ssec:inputs}. - \begingroup\slshape - Again, this is otherwise inside an \csbxint{theexpr}-ession or - \csbxint{thefloatexpr}-ession. There, the - minus sign may prefix macros which will expand to numbers (or parentheses - etc...) - \endgroup +As in the \hyperref[sec:xint]{xint.sty} documentation, |x|\ntype{\numx} stands +for something which internally will be handled in a \csa{numexpr}. It may thus +be an expression as understood by \csa{numexpr} but its evaluation and +intermediate steps must obey the \TeX\ bound. -\def\x {12}% -\def\AplusBC #1#2#3{\xintAdd {#1}{\xintMul {#2}{#3}}}% +The output format for most macros is the |A/B[N]| format but naturally the +float macros use the scientific notation on output. And some macros are +special, for example \csbxint{Trunc} produces decimal numbers, \csbxint{Irr} +produces an |A/B| with no |[N]|, \csbxint{iTrunc} and \csbxint{iRound} produce +integers without trailing |[N]| either, etc\dots -\item \label{item:xpxp} With the definition -% -\leftedline{|\def\AplusBC #1#2#3{\xintAdd {#1}{\xintMul {#2}{#3}}}|} -% -one obtains an - expandable macro producing the expected result, not in two, but rather in - three steps: a first expansion is consumed by the macro expanding to its - definition. As the package macros expand their arguments until no more is - possible (regarding what comes first), this |\AplusBC| may be used inside - them: {|\xintAdd {\AplusBC {1}{2}{3}}{4}|} does work and returns - \dtt{\xintAdd {\AplusBC {1}{2}{3}}{4}}. +|1.3a| belatedly adds documentation for some macros such as +\csbxint{DivFloor} which had been defined long ago, but did not make it to the +user manual for various reasons, one being that it is thought few users will +use directly the \xintfracname macros, the \csbxint{expr} interface being more +convenient. For complete documentation refer to |sourcexint.pdf|. - If, for some reason, it is important to create a macro expanding in two steps - to its final value, one may either do: -% -\smallskip -% -\leftedline {|\def\AplusBC #1#2#3{\romannumeral-`0\xintAdd {#1}{\xintMul - {#2}{#3}}}|} -% -or use the \emph{lowercase} form of \csa{xintAdd}: -% -\smallskip -% -\leftedline {|\def\AplusBC #1#2#3{\romannumeral0\xintadd {#1}{\xintMul - {#2}{#3}}}|} +\localtableofcontents - and then \csa{AplusBC} will share the same properties as do the - other \xintname `primitive' macros. +\subsection{\csh{xintNum}}\label{xintNumFrac} -\item -The |\romannumeral0| and |\romannumeral-`0| things above look like an invitation -to hacker's territory; if it is not important that the macro expands in two -steps only, there is no reason to follow these guidelines. Just chain -arbitrarily the package macros, and the new ones will be completely expandable -and usable one within the other. +The original \csbxint{Num} \etype{\Ff} from \xintname is made a synonym to +\csbxint{TTrunc} (whose description is to be found farther in this section). -Since release |1.07| the \csbxint{NewExpr} macro automatizes the creation of -such expandable macros: -% -\leftedline{|\xintNewExpr\AplusBC[3]{#1+#2*#3}|} -% -creates the |\AplusBC| macro doing the above and expanding in two expansion -steps. +Attention that for example |\xintNum{1e100000}| expands to the needed +\dtt{100001} digits... -\item In the expression parsers of \xintexprname such as - \csbxint{expr}|..\relax|, \csbxint{floatexpr}|..\relax| the contents are - expanded completely from left to right until the ending |\relax| is found - and swallowed, and spaces and even (to some extent) catcodes do not matter. +The original \hyperref[xintiNum]{\string\xintNum} from \xintcorename which +does not understand the fraction slash or the scientific notation is still +available under the name \csbxint{iNum}. -\item For all variants, prefixing with \csbxint{the} allows to print the - result or use it in other contexts. Shortcuts \csbxint{theexpr}, - \csbxint{thefloatexpr}, \csbxint{theiiexpr}, \dots\ are available. +\subsection{\csh{xintRaw}}\label{xintRaw} -\end{enumerate} +This macro `prints' the\etype{\Ff} +fraction |f| as it is received by the package after its parsing and +expansion, in a form |A/B[N]| equivalent to the internal +representation: the denominator |B| is always strictly positive and is +printed even if it has value |1|. +\begin{everbatim*} +\xintRaw{\the\numexpr 571*987\relax.123e-10/\the\numexpr-201+59\relax e-7} +\end{everbatim*} -\subsection {Input formats for macros}\label{ssec:inputs} +No simplification is done, not even of common zeroes between numerator and +denominator: +\begin{everbatim*} +\xintRaw {178000/25600000} +\end{everbatim*} -Macros can have different types of arguments (we do not consider here the -\csbxint{expr}-parsers but only the macros of -\xintcorename/\xintname/\xintfracname). In a macro description, a -margin annotation signals what is the argument type. -\begin{enumerate} -\item \TeX\ integers\ntype{\numx} are handled inside a |\numexpr..\relax| - hence may be count registers or variables. Beware that |-(1+1)| is not legal - and raises an error, but |0-(1+1)| is. Also |2\cnta| with |\cnta| a |\count| - isn't legal. Integers must be kept less than \dtt{\number "7FFFFFFF} in - absolute value, although the \emph{scaling} operation |(a*b)/c| computes the - intermediate product with twice as many bits. +\subsection{\csh{xintNumerator}}\label{xintNumerator} - The slash |/| does a \fbox{rounded} division which is a fact of life of - |\numexpr| which I have found very annoying in at least nine cases out of - ten, not to say ninety-nine cases out of one hundred. Besides, it is at odds - with \TeX's |\divide| which does a truncated division (non-expandably). +The input data\etype{\Ff} is parsed as if by \csbxint{Raw} into |A/B[N]| +format and +the macro outputs |A| if |N<=0|, or |A| extended by |N| zeroes if |N>0|. +\begin{everbatim*} +\xintNumerator {178000/25600000[17]}\newline +\xintNumerator {312.289001/20198.27}\newline +\xintNumerator {178000e-3/256e5}\newline +\xintNumerator {178.000/25600000} +\end{everbatim*} - But to follow-suit |/| also does rounded integer division in - \csbxint{iiexpr}|..\relax|, and the operator |//| does there the truncated - division. +\subsection{\csh{xintDenominator}}\label{xintDenominator} -\item the strict format\ntype{f} applies to macros handling big integers but - only \fexpan ding their arguments. After this \fexpan sion the input should - be a string of digits, optionally preceded by a unique minus sign. The first - digit can be zero only if it is the only digit. A plus sign is not accepted. - |-0| is not legal in the strict format. Macros of \xintname with a double - |ii| require this `strict' format for the inputs. +The input data\etype{\Ff} is parsed as if by \csbxint{Raw} into |A/B[N]| +format and +the macro outputs |B| if |N>0|, or |B| extended by \verb+|N|+ zeroes if |N<=0|. +\begin{everbatim*} +\xintDenominator {178000/25600000[17]}\newline +\xintDenominator {312.289001/20198.27}\newline +\xintDenominator {178000e-3/256e5}\newline +\xintDenominator {178.000/25600000} +\end{everbatim*} -\item the extended integer format\ntype{\Numf} applies when the macro parses - its arguments via \csbxint{Num}. The input may then have arbitrarily many - leading minus and plus signs, followed by leading zeroes, and further - digits. With \xintfracname loaded, \csbxint{Num} is extended to - accept fractions and its action is to truncate them to integers. +\subsection{\csh{xintRawWithZeros}}\label{xintRawWithZeros} + +This macro parses the input\etype{\Ff} and outputs |A/B|, with |A| +as would be returned by \csa{xintNumerator}|{f}| and |B| as would be returned by +\csa{xintDenominator}|{f}|. +\begin{everbatim*} +\xintRawWithZeros{178000/25600000[17]}\newline +\xintRawWithZeros{312.289001/20198.27}\newline +\xintRawWithZeros{178000e-3/256e5}\newline +\xintRawWithZeros{178.000/25600000}\newline +\xintRawWithZeros{\the\numexpr 571*987\relax.123e-10/\the\numexpr-201+59\relax e-7} +\end{everbatim*} - At |1.2o| many macros from \xintcorename/\xintname which - used. All these macros have now been removed at |1.3|. +\subsection{\csh{xintREZ}}\label{xintREZ} -\item the fraction input format\ntype{\Ff} applies to the arguments of - \xintfracname macros handling genuine fractions. It allows two types - of inputs: general and restricted. The restricted type is parsed faster, - but... is restricted. - \begin{description} - \item[general:] inputs of the shape |A.BeC/D.EeF|. Example: +The input\etype{\Ff} is first parsed into |A/B[N]| as by \csbxint{Raw}, then +trailing zeroes of |A| and |B| are suppressed and |N| is accordingly adjusted. \begin{everbatim*} -\noindent\xintRaw{+--0367.8920280e17/-++278.289287e-15}\newline -\xintRaw{+--+1253.2782e++--3/---0087.123e---5}\par +\xintREZ {178000/25600000[17]} \end{everbatim*} - The input parser does not reduce fractions to smallest terms. - Here are the rules of this general fraction format: - \begin{itemize} - \item everything is optional, absent numbers are treated as zero, here are - some extreme cases: + +This macro is used internally by various other constructs; its implementation +was redone entirely at |1.3a|, and it got faster on long inputs. + +\subsection{\csh{xintIrr}}\label{xintIrr} + +This puts the fraction\etype{\Ff} into its unique irreducible form: \begin{everbatim*} -\xintRaw{}, \xintRaw{.}, \xintRaw{./1.e}, \xintRaw{-.e}, \xintRaw{e/-1} +\xintIrr {178.256/256.1780}, \xintIrr {178000/25600000[17]} \end{everbatim*} - \item |AB| and |DE| may start with pluses and minuses, then leading - zeroes, then digits. - \item |C| and |F| will be given to |\numexpr| and can be anything - recognized as such and not provoking arithmetic overflow (the lengths of - |B| and |E| will also intervene to build the final exponent naturally - which must obey the \TeX{} bound). - \item the |/|, |.| (numerator and/or denominator) and |e| - (numerator and/or denominator) are all optional components. - \item each of |A|, |B|, |C|, |D|, |E| and |F| may arise from \fexpan sion - of a macro. - \item the whole thing may arise from \fexpan sion, however the |/|, |.|, - and |e| should all come from this initial expansion. The |e| of - scientific notation is mandatorily lowercased. - \end{itemize} - \item[restricted:] inputs either of the shape |A[N]| or |A/B[N]|, which - represents the fraction |A/B| times |10^N|. The whole thing or - each of |A|, |B|, |N| (but then not |/| or |[|) may arise from \fexpan - sion, |A| (after expansion) \emph{must} have a unique optional minus sign - and no leading zeroes, |B| (after expansion) if present \emph{must} be a - positive integer with no signs and no leading zeroes, |[N]| if present - will be given to |\numexpr|. Any deviation from the rules above will - result in errors. - \end{description} - Notice that |*|, |+| and |-| contrarily to the |/| (which is treated simply - as a kind of delimiter) are not acceptable within arguments of this - type\ntype{\Ff} (see \autoref{sec:useofcount} - for some exceptions to this.) -\end{enumerate} - -Generally speaking, there should be no spaces among the digits in the inputs -(in arguments to the package macros). Although most would be harmless in most -macros, there are some cases where spaces could break havoc.% -\footnote{The \csbxint{Num} macro does not remove spaces between digits beyond - the first non zero ones; however this should not really alter the subsequent - functioning of the arithmetic macros, and besides, since \xintcorename 1.2 - there is an initial parsing of the entire number, during which spaces will - be gobbled. However I have not done a complete review of the legacy code to - be certain of all possibilities after |1.2| release. One thing to be aware - of is that \csa{numexpr} stops on spaces between digits (although it - provokes an expansion to see if an infix operator follows); the exponent for - \csbxint{iiPow} or the argument of the factorial \csbxint{iiFac} are only - subjected to such a \csa{numexpr} (there are a few other macros with such - input types in \xintname). If the input is given as, say |1 2\x| where - \csa{x} is a macro, the macro \csa{x} will not be expanded by the - \csa{numexpr}, and this will surely cause problems afterwards. Perhaps a - later \xintname will force \csa{numexpr} to expand beyond spaces, but I - decided that was not really worth the effort. Another immediate cause of - problems is an input of the type |\xintiiAdd{\x}{\y}|, because the - space will stop the initial expansion; this will most certainly cause an - arithmetic overflow later when the \csa{x} will be expanded in a - \csa{numexpr}. Thus in conclusion, damages due to spaces are unlikely if - only explicit digits are involved in the inputs, or arguments are single - macros with no preceding space.} -So the best is to avoid them entirely. -This is entirely otherwise inside an |\xintexpr|-ession, where spaces are -ignored (except when they occur inside arguments to some macros, thus -escaping the |\xintexpr| parser). See the \autoref{sec:expr}. +The current implementation does not cleverly first factor powers of +2 and 5, and |\xintIrr {2/3[100]}| will execute the +Euclidean division of |2|\raisebox{.5ex}{|.|}|10^{100}| by |3|, which is a bit +stupid as it could have known that the \dtt{100} trailing zeros can not bring +any divisibility by \dtt{3}. -There are also some slighly more obscure expansion types: in particular, the -\csbxint{ApplyInline} and \csbxint{For*} macros from \xinttoolsname apply a -special iterated \fexpan sion, which gobbles spaces, to the non-braced items -(braced items are submitted to no expansion because the opening brace stops -it) coming from their list argument; this is denoted by a special -symbol\ntype{{\lowast f}} in the margin. Some other macros such as -\csbxint{Sum} from \xintfracname first do an \fexpan sion, then treat each -found (braced or not) item (skipping spaces between such items) via the -general fraction input parsing, this is signaled as -here\ntype{f{$\to$}{\lowast\Ff}} in the margin where the signification of the -\lowast{} is thus a bit different from the previous case. +Starting with release |1.08|, \csa{xintIrr} does not remove the trailing |/1| +when the output is an integer. This was deemed better for various (questionable?) +reasons, anyway the output format is since \emph{always} |A/B| with |B>0|, even +in cases where it turns out that |B=1|. +Use \csbxint{PRaw} on top of \csa{xintIrr} if it is needed to get rid of such a +trailing |/1|. -A few macros from \xinttoolsname do not expand, or expand only once their -argument\ntype{n{{\color{black}\upshape, resp.}} o}. This is also -signaled in the margin with notations \`a la \LaTeX3. +\subsection{\csh{xintPIrr}}\label{xintPIrr} +This puts the fraction\etype{\Ff} into irreducible form, +\emph{keeping as is the + decimal part} |[N]| from raw internal |A/B[N]| format. +(|P| stands here for \emph{Partial}) +\begin{everbatim*} +\xintPIrr {178.256/256.1780}, \xintPIrr {178000/25600000[17]} +\end{everbatim*} -\subsection{Output formats of macros} -\label{ssec:outputs} +Notice that the output always has the ending |[N]|, which is exactly the +opposite of \csbxint{Irr}'s behaviour. The interest of this macro is mainly in +handling fractions which somehow acquired a big |[N]| (perhaps from input in +scientific notation) and for which the reduced fraction would have a very +large number of digits. This large number of digits can considerably slow-down +computations done afterwards. -We do not consider here the \csbxint{expr}-parsers but only the macros from \xintcorename, \xintname and \xintfracname. Macros of other -components of the bundle may have their own output formats, for example for -continuous fractions with \xintcfracname. -There are mainly three types of outputs:% +For example package \href{http://ctan.org/pkg/polexpr}{polexpr} uses +\csa{xintPIrr} when differentiating a polynomial, or in setting up a Sturm +chain for localization of the real roots of a polynomial. This is relevant to +polynomials whose coefficients were input in decimal notation, as this +automatically creates internally some |[N]|. Keeping and combining those +|[N]|'s during computations significantly increases their speed. -\begin{itemize}[nosep,listparindent=\leftmarginiii] -\item arithmetic macros from \xintcorename/\xintname deliver integers - in the strict format as described in the previous section. -\item arithmetic macros from \xintfracname produce on output the strict -fraction format |A/B[N]|, which stands for |(A/B)|$\times$|10^N|, where |A| -and |B| are integers, |B| is positive, and |N| is a ``short'' integer. The -output is not reduced to smallest terms. The |A| and |B| may end with zeroes -(\emph{i.e}, |N| does not represent all powers of ten). The denominator |B| is -always strictly positive. There is no |+| sign. The |-| is always first if -present (i.e. the denominator on output is always positive.) The output will -be expressed as such a fraction even if the inputs are both integers and the -mathematical result is an integer. The |B=1| is not removed.% -% -\footnote{refer to the documentation of \csbxint{PRaw} for an alternative.} -\item macros with |Float| in their names produce on output scientific -format with |P=|\nobreak\csbxint{theDigits} digits, a lowercase |e| and an -exponent |N|. The first digit is not zero, it is preceded by an optional minus -sign and is followed by a dot and |P-1| digits. Trailing zeroes are not -trimmed. There is one exceptional case: -\begin{itemize}[nosep] -\item if the value is mathematically zero, it is output as |0.e0|, - i.e. zeros after the decimal mark are removed and the exponent is always |0|. -\end{itemize} -Future versions of the package may modify this. -\end{itemize} +\subsection{\csh{xintJrr}}\label{xintJrr} +This also puts the fraction\etype{\Ff} into its unique irreducible form: +\begin{everbatim*} +\xintJrr {178.256/256.178} +\end{everbatim*} -\subsection{Count registers and variables}\label{sec:useofcount} +This is (supposedly, not tested for ages) faster than \csa{xintIrr} for +fractions having some big common factor in the numerator and the denominator. +\begin{everbatim*} +\xintJrr {\xintiiPow{\xintiiFac {15}}{3}/% + \xintiiPrd{{\xintiiFac{10}}{\xintiiFac{30}}{\xintiiFac{5}}}} +\end{everbatim*} -Inside |\xintexpr..\relax| and its variants, a count register or count control -sequence is automatically unpacked using |\number|, with tacit multiplication: -|1.23\counta| is like |1.23*\number\counta|. There -is a subtle difference between count \emph{registers} and count -\emph{variables}. In |1.23*\counta| the unpacked |\counta| variable defines a -complete operand thus |1.23*\counta 7| is a syntax error. But |1.23*\count0| -just replaces |\count0| by |\number\count0| hence |1.23*\count0 7| is like -|1.23*57| if |\count0| contains the integer value |5|. +But to notice the difference one would need computations with much bigger +numbers than in this example. As \csbxint{Irr}, \csa{xintJrr} does not remove +the trailing |/1| from a fraction reduced to an integer. -Regarding now the package macros, there is first the case of arguments having to -be short integers: this means that they are fed to a |\numexpr...\relax|, hence -submitted to a \emph{complete expansion} which must deliver an integer, and -count registers and even algebraic expressions with them like -|\mycountA+\mycountB*17-\mycountC/12+\mycountD| are admissible arguments (the -slash stands here for the rounded integer division done by |\numexpr|). This -applies in particular to the number of digits to truncate or round with, to the -indices of a series partial sum, \dots +\subsection{\csh{xintPRaw}}\label{xintPRaw} -The macros allowing the extended format for long numbers or dealing with -fractions will \emph{to some extent} allow the direct use of count -registers and even infix algebra inside their arguments: a count -register |\mycountA| or |\count 255| is admissible as numerator or also as -denominator, with no need to be prefixed by |\the| or |\number|. It is possible -to have as argument an algebraic expression as would be acceptable by a -|\numexpr...\relax|, under this condition: \emph{each of the numerator and - denominator is expressed with at most \emph{nine} - tokens}.% -% -\footnote{The |1.2k| and earlier versions manual claimed up to 8 - tokens, but low-level TeX error arose if the |\numexpr...\relax| occupied - exactly 8 tokens \emph{and} evaluated to zero. With |1.2l| and later, up to - 9 tokens are always safe and one may even drop the ending |\relax|. But - well, all these explanations are somewhat silly because prefixing by |\the| - or |\number| is always working with arbitrarily many tokens.} -% -% -\footnote{Attention! in the \LaTeX{} context a - \csa{value}\texttt{\{countername\}} will behave ok only if it is first in - the input, if not it will not get expanded, and braces around the name will - be removed and chaos\IMPORTANT{} will ensue inside a \csa{numexpr}. One - should enclose the whole input in \csa{the}\csa{numexpr}|...|\csa{relax} in - such cases.} -% -Important: a slash for rounded division in a |\numexpr| should be written with -braces |{/}| to not be confused with the \xintfracname delimiter between -numerator and denominator (braces will be removed internally and the slash -will count for one token). Example: -|\mycountA+\mycountB{/}17/1+\mycountA*\mycountB|, or |\count 0+\count -2{/}17/1+\count 0*\count 2|. -% -\leftedline{|\cnta 10 \cntb 35 \xintRaw - {\cnta+\cntb{/}17/1+\cnta*\cntb}|\dtt{->\cnta 10 \cntb 35 \xintRaw - {\cnta+\cntb{/}17/1+\cnta*\cntb}}} -% -For longer algebraic expressions using -count registers, there are two possibilities: -\begin{enumerate}[nosep] -\item let the numerator and the denominator be presented as |\the\numexpr...\relax|, -\item or as |\numexpr {...}\relax| (the braces are removed during processing; - they are not legal for |\numexpr...\relax| syntax.) -\end{enumerate} -\everb|@ -\cnta 100 \cntb 10 \cntc 1 -\xintPRaw {\numexpr {\cnta*\cnta+\cntb*\cntb+\cntc*\cntc+ - 2*\cnta*\cntb+2*\cnta*\cntc+2*\cntb*\cntc}\relax/% - \numexpr {\cnta*\cnta+\cntb*\cntb+\cntc*\cntc}\relax } -| -\cnta 100 \cntb 10 \cntc 1 -% -\leftedline{\dtt{\xintPRaw {\numexpr - {\cnta*\cnta+\cntb*\cntb+\cntc*\cntc+ - 2*\cnta*\cntb+2*\cnta*\cntc+2*\cntb*\cntc}\relax/% - \numexpr {\cnta*\cnta+\cntb*\cntb+\cntc*\cntc}\relax }}} +|PRaw|\etype{\Ff} stands for ``pretty raw''. It does like \csbxint{Raw} apart +from removing the |[N]| part if |N=0| and removing the |B| if |B=1|. +\begin{everbatim*} +\xintPRaw {123e10/321e10}, \xintPRaw {123e9/321e10}, \xintPRaw {\xintIrr{861/123}} +\end{everbatim*} -\subsection{Dimension registers and variables} -\label{sec:Dimensions} +\subsection{\csh{xintFracToSci}, \csh{xintFracToSciE}}\label{xintFracToSci} +\label{xintFracToSciE} -\meta{dimen} variables can be converted into (short) integers suitable for the -\xintname macros by prefixing them with |\number|. This transforms a dimension -into an explicit short integer which is its value in terms of the |sp| unit -($1/65536$\,|pt|). -When |\number| is applied to a \meta{glue} variable, the stretch and shrink -components are lost. +\csa{xintFracToSci}\etype{\Ff} is not really part of public interface. It is a +macro used by \csbxint{expr} for output. -For \LaTeX{} users: a length is a \meta{glue} variable, prefixing a -length macro defined by \csa{newlength} with \csa{number} will thus discard -the |plus| and |minus| glue components and return the dimension component as -described above, and usable in the \xintname bundle macros. +\noindent\csa{xintFracToSciE}\NewWith{1.4} says what to use for the scientific +notation, its default definition is +\begin{everbatim} +\def\xintFracToSciE{e} +\end{everbatim} -This conversion is done automatically inside an -|\xintexpr|-essions, with tacit multiplication implied if prefixed by some -(integral or decimal) number. +If using directly \csa{xintFracToSci}: attention that it expects input to +already be in raw \xintfracname format, apart from denominator and |[N]| +postfix parts being optional. Its output is like \csbxint{PRaw} except for +using scientific notation in place of raw \xintfracname format. +\begin{everbatim*} +\xintFracToSci {\xintRaw{123e10/321e10}}, +\xintFracToSci {\xintRaw{123e9/321e10}}, +\xintFracToSci {\xintIrr{861/123}} +\end{everbatim*} -One may thus compute areas or volumes with no limitations, in units of |sp^2| -respectively |sp^3|, do arithmetic with them, compare them, etc..., and possibly -express some final result back in another unit, with the suitable conversion -factor and a rounding to a given number of decimal places. -A \hyperref[tableofdimensions]{table of dimensions} illustrates that the -internal values used by \TeX{} do not correspond always to the closest -rounding. For example a millimeter exact value in terms of |sp| units is -\dtt{72.27/10/2.54*65536=\xinttheexpr trunc(72.27/10/2.54*65536,3)\relax ...} -and \TeX{} uses internally \dtt{\number\dimexpr 1mm\relax}|sp| (\TeX{} -truncates to get an integral multiple of the |sp| unit; see at the end of this -section the exact rules applied internally by \TeX). +\subsection{\csh{xintDecToString}}\label{xintDecToString} -\begin{figure*}[ht!] -\phantomsection\label{tableofdimensions} -\begingroup\let\ignorespaces\empty - \let\unskip\empty - \def\T{\expandafter\TT\number\dimexpr} - \def\TT#1!{\gdef\tempT{#1}} - \def\E{\expandafter\expandafter\expandafter - \EE\xintexpr reduce(} - \def\EE#1!{\gdef\tempE{#1}} -\centeredline{\begin{tabular}{% - >{\bfseries\strut}c% - c% - >{\E}c<{)\relax!}@{}% - >{\xintthe\tempE}r@{${}={}$}% - >{\xinttheexpr trunc(\tempE,3)\relax...}l% - >{\T}c<{!}@{}% - >{\tempT}r% - >{\xinttheexpr round(100*(\tempT-\tempE)/\tempE,4)\relax\%}c} - \hline - Unit&% - definition&% - \omit &% - \multicolumn{2}{c}{Exact value in \texttt{sp} units\strut}&% - \omit &% - \omit\parbox{2cm}{\centering\strut\TeX's value in \texttt{sp} units\strut}&% - \omit\parbox{2cm}{\centering\strut Relative error\strut}\\\hline - cm&0.01 m&72.27/2.54*65536&&&1cm&&\\ - mm&0.001 m&72.27/10/2.54*65536&&&1mm&&\\ - in&2.54 cm&72.27*65536&&&1in&&\\ - pc&12 pt&12*65536&&&1pc&&\\ - pt&1/72.27 in&65536&&&1pt&&\\ - bp&1/72 in&72.27*65536/72&&&1bp&&\\ - \omit\hfil\llap{3}bp\strut\hfil&1/24 in&72.27*65536/24&&&3bp&&\\ - \omit\hfil\llap{12}bp\strut\hfil&1/6 in&72.27*65536/6&&&12bp&&\\ - \omit\hfil\llap{72}bp\strut\hfil&1 in&72.27*65536&&&72bp&&\\ - dd&1238/1157 pt&1238/1157*65536&&&1dd&&\\ - \omit\hfil\llap{11}dd\strut\hfil&11*1238/1157 pt&11*1238/1157*65536&&&11dd&&\\ - \omit\hfil\llap{12}dd\strut\hfil&12*1238/1157 pt&12*1238/1157*65536&&&12dd&&\\ - sp&1/65536 pt&1&&&1sp&&\\\hline - \multicolumn{8}{c}{\bfseries\large\TeX{} \strut dimensions}\\\hline -\end{tabular}} -\endgroup -\end{figure*} +This is\etype{\Ff} a macro tailored for printing decimal numbers. It does not +trim trailing zeros, use |\xintDecToString{\xintREZ{}}| for that. -There is something quite amusing with the Didot point. According to the \TeX -Book, $1157$\,|dd|=$1238$\,|pt|. The actual internal value of $1$\,|dd| in \TeX{} is $70124$\,|sp|. We can use \xintcfracname to display the list of -centered convergents of the fraction $70124/65536$: -% -\leftedline{|\xintListWithSep{, }{\xintFtoCCv{70124/65536}}|} -% -\xintFor* #1 in {\xintFtoCCv{70124/65536}}\do {$\printnumber{#1}$, }% -and we don't find -$1238/1157$ therein, but another approximant $1452/1357$! +\begin{everbatim*} +\xintDecToString {123456789e5}\newline +\xintDecToString {123456789e-5}\newline +\xintDecToString {12345e-10}\newline +\xintDecToString {12345e-10/123}\newline % leaves the denominator as is +\xintDecToString {1234567890000e-6}\newline % does not trim trailing zeros +\xintDecToString {\xintREZ{1234567890000e-6}}\par % does trim trailing zeros +\end{everbatim*} +Consider it an unstable macro, what it does exactly is yet to be decided. It +is a backport from \href{http://ctan.org/pkg/polexpr}{polexpr}'s +|\PolDecToString|, which has now been made an alias to it. -And indeed multiplying $70124/65536$ by $1157$, and respectively $1357$, we find -the approximations (wait for more, later): -% -\leftedline{``$1157$\,|dd|''\dtt{=\xinttheexpr trunc(1157\dimexpr - 1dd\relax/\dimexpr 1pt\relax,12)\relax}\dots|pt|} -% -\leftedline{``$1357$\,|dd|''\dtt{=\xinttheexpr trunc(1357\dimexpr - 1dd\relax/\dimexpr 1pt\relax,12)\relax}\dots|pt|} -% -and we seemingly discover that $1357$\,|dd|=$1452$\,|pt| is \emph{far more - accurate} than -the \TeX Book formula $1157$\,|dd|=$1238$\,|pt|~! -The formula to compute $N$\,|dd| was -% -\leftedline{|\xinttheexpr trunc(N\dimexpr 1dd\relax/\dimexpr - 1pt\relax,12)\relax}|} -% +\subsection{\csh{xintTrunc}}\label{xintTrunc} -What's the catch? The catch is that \TeX{} \emph{does not} compute $1157$\,|dd| -like we just did:% -% -\leftedline{$1157$\,|dd|=|\number\dimexpr 1157dd\relax/65536|% - \dtt{=\xintTrunc{12}{\number\dimexpr 1157dd\relax/65536}}\dots|pt|} -% -\leftedline{$1357$\,|dd|=|\number\dimexpr 1357dd\relax/65536|% - \dtt{=\xintTrunc{12}{\number\dimexpr 1357dd\relax/65536}}\dots|pt|} -% -We thus discover that \TeX{} (or rather here, e-\TeX{}, but one can check that -this works the same in \TeX82), uses $1238/1157$ as a conversion -factor (and necessarily intermediate computations simulate higher precision -than a priori available with integers less than $2^{31}$ or rather $2^{30}$ for -dimensions). Hence the $1452/1357$ ratio is irrelevant, an artefact -of the rounding (or rather, as we see, truncating) for one |dd| to be -expressed as an integral number of |sp|'s. +\csa{xintTrunc}|{x}{f}|\etype{\numx\Ff} returns the start of the decimal +expansion of the fraction |f|, truncated to: +\begin{itemize} +\item if |x>0|, |x| digits after the decimal mark, +\item if |x=0|, an integer, +\item if |x<0|, an integer multiple of |10^{-x}| (in scientific notation).\NewWith{1.4a} +\end{itemize} +The output is the sole digit token \dtt{0} if and only if the input was exactly +zero; else it contains always either a decimal mark (even if |x=0|) or a +scientific part and it conserves the sign of |f| (even if the truncated value +represents the zero value). -Let us now -use |\xintexpr| to compute the value of the Didot point in millimeters, if -the above rule is exactly verified: -% -\leftedline{|\xinttheexpr - trunc(1238/1157*25.4/72.27,12)\relax|% - \dtt{=\xinttheexpr trunc(1238/1157*25.4/72.27,12)\relax}|...mm|} -% -This fits very well with the possible values of the Didot point as listed in -the -\href{http://en.wikipedia.org/wiki/Point_%28typography%29#Didot}{Wikipedia Article}. -% -The value $0.376065$\,|mm| is said to be \emph{the traditional value in - European printers' offices}. So the $1157$\,|dd|=$1238$\,|pt| rule refers to -this Didot point, or more precisely to the \emph{conversion factor} to be used -between this Didot and \TeX{} points. +Truncation is done towards zero. +\begin{everbatim*} +\xintFor* #1 in {\xintSeq[-1]{7}{-14}}:{\xintTrunc{#1}{-11e12/7}\newline}% +\xintTrunc{10}{1e-11}\newline +\xintTrunc{10}{1/65536}\par +\end{everbatim*} -The actual value in millimeters of exactly one Didot point as implemented in -\TeX{} is -% -\leftedline {|\xinttheexpr trunc(\dimexpr - 1dd\relax/65536/72.27*25.4,12)\relax|} -% -\leftedline{\dtt{=\xinttheexpr trunc(\dimexpr - 1dd\relax/65536/72.27*25.4,12)\relax}|...mm|} -% -The difference of circa $5$\AA\ is arguably tiny! +\begin{framed} + \textbf{Warning:} \emph{it is not yet decided is the current behaviour is + definitive.} -% 543564351/508000000 + Currently \xintfracname has no notion of a positive zero or a negative zero. + Hence transitivity of \csbxint{Trunc} is broken for the case where the first + truncation gives on output \dtt{0.00...0} or \dtt{-0.00...0}: a second + truncation to less digits will then output \dtt{0}, whereas if it had been + applied directly to the initial input it would have produced \dtt{0.00...0} + or respectively \dtt{-0.00...0} (with less zeros after decimal mark). -By the way the \emph{European printers' offices \emph{(dixit Wikipedia)} - Didot} is thus exactly -% -\leftedline{|\xinttheexpr reduce(.376065/(25.4/72.27))\relax|% - \dtt{=\xinttheexpr reduce(.376065/(25.4/72.27))\relax}\,|pt|} -% -and the centered convergents of this fraction are \xintFor* #1 in -{\xintFtoCCv{543564351/508000000}}\do {\dtt{\printnumber{#1}}\xintifForLast{.}{, }} We do -recover the $1238/1157$ therein! + If \xintfracname distinguished zero, positive zero, and + negative zero then it would be possible to maintain transitivity. -\begin{framed} - Here is how \TeX\ converts |abc.xyz...|. First the decimal is - \emph{rounded} to the nearest integral multiple of |1/65536|, say |X/65536|. - The || is associated to a ratio |N/D|, which represents |/pt|. - For the Didot point the ratio is indeed |1238/1157|. \TeX\ \emph{truncates} - the fraction |XN/D| to an integer |M|. The dimension is represented by |M - sp|. + The problem would also be fixed, even without distinguishing a negative zero + on input, if \csbxint{Trunc} always produced \dtt{0.00...0} (with no sign) + when the mathematical result is zero, discarding the information on original + input being positive, zero, or negative. + I have multiple times hesitated about what to do and must postpone again + final decision. \end{framed} +\subsection{\csh{xintXTrunc}}\label{xintXTrunc} -\subsection{\csh{ifcase}, \csh{ifnum}, ... constructs}\label{sec:ifcase} - -When using things such as |\ifcase \xintSgn{\A}| one has to make sure to leave -a space after the closing brace for \TeX{} to -stop its scanning for a number: once \TeX{} has finished expanding -|\xintSgn{\A}| and has so far obtained either |1|, |0|, or |-1|, a -space (or something `unexpandable') must stop it looking for more -digits. Using |\ifcase\xintSgn\A| without the braces is very dangerous, -because the blanks (including the end of line) following |\A| will be -skipped and not serve to stop the number which |\ifcase| is looking for. -% -\begin{everbatim*} -\begin{enumerate}[nosep]\def\A{1} -\item \ifcase \xintSgn\A 0\or OK\else ERROR\fi -\item \ifcase \xintSgn\A\space 0\or OK\else ERROR\fi -\item \ifcase \xintSgn{\A} 0\or OK\else ERROR\fi -\end{enumerate} -\end{everbatim*} -In order to use successfully |\if...\fi| constructions either as arguments to -the \xintname bundle expandable macros, or when building up a completely -expandable macro of one's own, one needs some \TeX nical expertise (see also -\autoref{fn:expansions} on page~\pageref{fn:expansions}). +\csa{xintXTrunc}|{x}{f}|\retype{\numx\Ff} is similar to \csbxint{Trunc} with +the following important differences: +\begin{itemize}[nosep] +\item it is completely expandable but not +\fexpan dable, as is indicated by the hollow star in the margin, +\item hence it can not be used as argument to the other package macros, but as + it \fexpan ds its |{f}| argument, it accepts arguments expressed with other + \xintfracname macros, +\item it requires |x>0|, +\item contrarily to \csbxint{Trunc} the number of digits on output is not + limited to about \dtt{19950} and may go well beyond \dtt{100000} (this is + mainly useful for outputting a decimal expansion to a file), +\item when the mathematical result is zero, it always prints it as + \dtt{0.00...0} or \dtt{-0.00...0} with |x| zeros after the decimal mark. +\end{itemize} -It is thus much to be recommended to use the expandable branching macros, -provided by \xintfracname succh as \csbxint{ifSgn}, \csbxint{ifZero}, -\csbxint{ifOne}, \csbxint{ifNotZero}, \csbxint{ifTrueAelseB}, \csbxint{ifCmp}, -\csbxint{ifGt}, \csbxint{ifLt}, \csbxint{ifEq}, -\csbxint{ifInt}... See their respective documentations. All these conditionals -always have either two or three branches, and empty brace pairs |{}| for -unused branches should not be forgotten. +\textbf{Warning:} +transitivity is broken too (see discussion of \csbxint{Trunc}), due to the +sign in the last item. Hence \emph{the definitive policy is yet to be fixed.} -If these tests are to be applied to standard \TeX{} short integers, it is more -efficient to use (under \LaTeX{}) the equivalent conditional tests from the -\href{https://ctan.org/pkg/etoolbox}{etoolbox}% -% -\footnote{\url{https://ctan.org/pkg/etoolbox}} -package. +Transitivity is here in the sense of using a first |\edef| and then a second +one, because it is not possible to nest \csb{xintXTrunc} directly as argument +to itself. Besides, although the number of digits on output isn't limited, +nevertheless |x| should be less than about |19970| when the number of digits +of the input (assuming it is expressed as a decimal number) is even bigger: +|\xintXTrunc{30000}{\Z}| after |\edef\Z{\xintXTrunc{60000}{1/66049}| raises an +error in contrast with a direct |\xintXTrunc{30000}{1/66049}|. But +|\xintXTrunc{30000}{123.456789}| works, because here the number of digits +originally present is smaller than what is asked for, thus the routine only +has to add trailing zeros, and this has no limitation (apart from \TeX\ main +memory). -\subsection{No variable declarations are needed} +\csbxint{XTrunc} will expand fully in an |\edef| or a |\write| (|\message|, +|\wlog|, \dots) or in an \csbxint{expr}-ession, or as list argument to +\csbxint{For*}. - There is no notion of a \emph{declaration of a variable}. +Here is an example session where the +user checks that the decimal expansion of $1/66049=1/257^2$ has the maximal +period length $257*256=65792$ (this period length must be a divisor of +$\phi(66049)$ and to check it is the maximal one it is enough to show that +neither $32896$ nor $256$ are periods.) - To do a computation and assign its result to some macro |\z|, the user will employ the |\def|, |\edef|, or |\newcommand| (in \LaTeX) - as usual, keeping in mind that two expansion steps are needed, thus |\edef| - is initially the main tool: -% -\begin{everbatim*} -\def\x{1729728} \def\y{352827927} \edef\z{\xintiiMul {\x}{\y}} -\meaning\z -\end{everbatim*} +\begingroup\small +\everb|@ +$ rlwrap etex -jobname worksheet-66049 +This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016) (preloaded format=etex) + restricted \write18 enabled. +**xintfrac.sty +entering extended mode +(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintfrac.sty +(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xint.sty +(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintcore.sty +(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintkernel.sty)))) +*% we load xinttools for \xintKeep, etc... \xintXTrunc itself has no more -As an alternative to |\edef| the package provides |\oodef| which expands -exactly twice the replacement text, and |\fdef| which applies \fexpan sion to -the replacement text during the definition. -\begin{everbatim*} -\def\x{1729728} \def\y{352827927} \oodef\w {\xintiiMul\x\y} \fdef\z{\xintiiMul {\x}{\y}} -\meaning\w, \meaning\z -\end{everbatim*} +*% any dependency on xinttools.sty since 1.2i -In practice |\oodef| is slower than |\edef|, except for computations ending in -very big final replacement texts (thousands of digits). On the other hand -|\fdef|\IMPORTANT{} appears to be slightly faster than |\edef| already in the -case of expansions leading to only a few dozen digits. +*\input xinttools.sty +(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xinttools.sty) +*\def\m#1;{\message{#1}} -\xintexprname does provide an interface to declare and assign values to -identifiers which can then be used in expressions: \autoref{xintdefvar}. +*\m \the\numexpr 257*257\relax; +66049 +*\m \the\numexpr 257*256\relax; +65792 +*% Thus 1/66049 will have a period length dividing 65792. +*% Let us first check it is indeed periodical. -\subsection{When expandability is too much} +*\edef\Z{\xintXTrunc{66000}{1/66049}} -Let's use the macros of \autoref{ssec:fibonacci} related to Fibonacci numbers. -Notice that the $47$th Fibonacci number is \dtt{\xintthe\FibonacciN {47}} thus -already too big for \TeX{} and \eTeX{}. +*% Let's display the first decimal digits. +*\m \xintXTrunc{208}{\Z}; -The |\FibonacciN| macro found in \autoref{ssec:fibonacci} is completely -expandable, it is even \fexpan dable. We need a wrapper with |\xintthe| -prefix -\begin{everbatim*} -\def\theFibonacciN{\xintthe\FibonacciN} -\end{everbatim*} -to print in the document or to use within |\message| (or \LaTeX\ |typeout|) to -write to the log and terminal. +0.00001514027464458205271843631243470756559523989765174340262532362337052794137 +6856576178291874214598252812306015231116292449545034746930309315810988811337037 +6538630410755651107511090251177156353616254598858423 +*% let's now fetch the trailing digits -\begingroup - \def\A {1859} \def\B {1573} - \edef\X {\theFibonacciN\A} \edef\Y {\theFibonacciN\B} - \edef\GCDAB {\xintiiGCD\A\B}\edef\Z {\theFibonacciN\GCDAB} - \edef\GCDXY{\xintiiGCD\X\Y} +*\m \xintKeep{65792-66000}{\Z};% 208 trailing digits - The |\xintthe| prefix also allows its use it as argument to the \xintname - macros: for example if we are interested in knowing how many digits - $F(1250)$ has, it suffices to issue |\xintLen {\theFibonacciN {1250}}| - (which expands to \dtt{\xintLen {\theFibonacciN {1250}}}). Or if we want to - check the formula $gcd(F(1859),F(1573))=F(gcd(1859,1573))=F(143)$, we only - need% -% -\footnote{The - \csa{xintiiGCD} macro is provided by both the \xintgcdname package (since - |1.0|) and by the \xintname package (since |1.3d|).} -% -\begin{everbatim} -$\xintiiGCD{\theFibonacciN{1859}}{\theFibonacciN{1573}}=% - \theFibonacciN{\xintiiGCD{1859}{1573}}$ -\end{everbatim} -% -which produces: -% -\leftedline{$\dtt{\xintiiGCD{\X}{\Y}}=\dtt{\theFibonacciN{\GCDAB}}$} +0000151402746445820527184363124347075655952398976517434026253236233705279413768 +5657617829187421459825281230601523111629244954503474693030931581098881133703765 +38630410755651107511090251177156353616254598858423 +*% yes they match! we now check that 65792/2 and 65792/257=256 aren't periods. -The |\theFibonacciN| macro expanded its |\xintiiGCD{1859}{1573}| argument via the -services of |\numexpr|: this step allows only things obeying the \TeX{} bound, -naturally! (but \dtt{F(\xintiiPow2{31}}) would be rather big anyhow...). +*\m \xintXTrunc{256}{\Z}; -This is very convenient but of course it repeats the complete evaluation each -time it is done. In practice, it is often useful to store the result of such -evaluations in macros. Any |\edef| will break expandability, but if the goal -is at some point to print something to the |dvi| or |pdf| output, and not only -to the |log| file, then expandability has to be broken one day or another! +0.00001514027464458205271843631243470756559523989765174340262532362337052794137 +6856576178291874214598252812306015231116292449545034746930309315810988811337037 +6538630410755651107511090251177156353616254598858423291798513225029902042423049 +554118911717058547442 +*\m \xintXTrunc{256+256}{\Z}; -Hence, in practice, if we want to print in the document some computation -results, we can proceed like this and avoid having to repeat identical -evaluations: -\begin{everbatim} -\begingroup - \def\A {1859} \def\B {1573} - \edef\X {\theFibonacciN\A} \edef\Y {\theFibonacciN\B} - \edef\GCDAB {\xintiiGCD\A\B}\edef\Z {\theFibonacciN\GCDAB} - \edef\GCDXY{\xintiiGCD\X\Y} -The identity $\gcd(F(\A),F(\B))=F(\gcd(\A,\B))$ can be checked via evaluation -of both sides: $\gcd(F(\A),F(\B))=\gcd(\printnumber\X,\printnumber\Y)= -\printnumber{\GCDXY} = F(\gcd(\A,\B)) = F(\GCDAB) =\printnumber\Z$.\par - % some further computations involving \A, \B, \X, \Y -\endgroup % closing the group removes assignments to \A, \B, ... -% or choose longer names less susceptible to overwrite something. -% Note: there is no LaTeX \newecommand which would be to \edef like \newcommand is to \def -\end{everbatim} -The identity $\gcd(F(\A),F(\B))=F(\gcd(\A,\B))$ can be checked via evaluation -of both sides: $\gcd(F(\A),F(\B))=\gcd(\printnumber\X,\printnumber\Y)= -\printnumber{\GCDXY} = F(\gcd(\A,\B)) = F(\GCDAB) =\printnumber\Z$.\par -\endgroup +0.00001514027464458205271843631243470756559523989765174340262532362337052794137 +6856576178291874214598252812306015231116292449545034746930309315810988811337037 +6538630410755651107511090251177156353616254598858423291798513225029902042423049 +5541189117170585474420505987978621932201850141561567926842192917379521264515738 +3154930430438008145467758785144362518736089872670290239064936637950612424109373 +3440324607488379839210283274538600130206361943405653378552286938485064119063119 +8049932625777831609865402958409665551333 +*% now with 65792/2=32896. Problem: we can't do \xintXTrunc{32896+100}{\Z} -One may legitimately ask the author: why expandability -to such extremes, for things such as big fractions or floating point numbers -(even continued fractions...) which anyhow can not be used directly within -\TeX's primitives such as |\ifnum|? Why insist on a concept -which is foreign to the vast majority of \TeX\ users and even programmers? +*% but only direct \xintXTrunc{32896+100}{1/66049}. Anyway we want to nest it -I have no answer: it made definitely sense at the start of \xintname (see -\autoref{ssec:origins}) and once started I could not stop. +*% hence let's do it all with (slower) \xintKeep, \xintKeepUnbraced. +*\m \xintKeep {-100}{\xintKeepUnbraced{2+65792/2+100}{\Z}}; -\subsection{Possible syntax errors to avoid} +9999848597253554179472815636875652924344047601023482565973746763766294720586231 +434238217081257854017 +*% This confirms 32896 isn't a period length. -\edef\x{\xintMul {3}{5}/\xintMul{7}{9}} +*% To conclude let's write the 66000 digits to the log. -Here is a list of imaginable input errors. Some will cause compilation errors, -others are more annoying as they may pass through unsignaled. -\begin{itemize} -\item using |-| to prefix some macro: |-\xintiiSqr{35}/271|.% -% -\footnote{to the - contrary, this \emph{is} - allowed inside an |\xintexpr|-ession.} -\item using one pair of braces too many |\xintIrr{{\xintiiPow {3}{13}}/243}| (the - computation goes through with no error signaled, but the result is completely - wrong). -\item things like |\xintiiAdd { \x}{\y}| as the space will cause \csa{x} to be - expanded later, most probably within a |\numexpr| thus provoking possibly an - arithmetic overflow. -\item using |[]| and decimal points at the same time |1.5/3.5[2]|, or with a - sign in the denominator |3/-5[7]|. The scientific notation has no such - restriction, the two inputs |1.5/-3.5e-2| and |-1.5e2/3.5| are equivalent: - |\xintRaw{1.5/-3.5e-2}|\dtt{=\xintRaw{1.5/-3.5e-2}}, - |\xintRaw{-1.5e2/3.5}|\dtt{=\xintRaw{-1.5e2/3.5}}. -\item generally speaking, using in a context expecting an integer (possibly - restricted to the \TeX{} bound) a macro or expression which returns a - fraction: |\xinttheexpr 4/2\relax| outputs \dtt{\xinttheexpr 4/2\relax}, - not $2$. Use |\xintNum {\xinttheexpr 4/2\relax}| or |\xinttheiexpr 4/2\relax| - (which rounds the result to the nearest integer, here, the result is already - an integer) or |\xinttheiiexpr 4/2\relax|. Or, divide in your head |4| by - |2| and insert the result directly in the \TeX{} source. -\end{itemize} +*\wlog{\Z} -\subsection{Error messages} +*% We want always more digits: -In situations such as division by zero, the \TeX{} run will be interrupted -with some error message. The user is asked to hit the RETURN key thrice, which -will display additional information. In non-interactive -|nonstopmode| the \TeX{} run goes on uninterrupted and the error data will be -found in the compilation log. +*\wlog{\xintXTrunc{150000}{1/66049}} -Here is an example interactive run: +*\bye +| +\endgroup % $ à cause de fontification de AUCTeX. + +The acute observer will have noticed that there is something funny when one +compares the first digits with those after the middle-period: \begin{everbatim} -! Undefined control sequence. - \ ! / - DivisionByZero (hit thrice) -l.11 \xintiiDivision{123}{0} - -? -! Undefined control sequence. - \ ! / - Division of 123 by 0 -l.11 \xintiiDivision{123}{0} - -? -! Undefined control sequence. - \ ! / - next: {0}{0} -l.11 \xintiiDivision{123}{0} - -? -[1] (./temptest.aux) ) -Output written on temptest.dvi (1 page, 216 bytes). -Transcript written on temptest.log. +0000151402746445820527184363124347075655952398976517434026253236233705279413768... +9999848597253554179472815636875652924344047601023482565973746763766294720586231... \end{everbatim} +Mathematical exercise: can you explain why the two indeed add to |9999...9999|? -This is an experimental feature, which is in preparation for next major -release.% -% -\footnote{The related macros checking or resetting error flags are implemented - in embryonic form but no user interface is provided with |1.2l| release.} -% -For the good functioning of this the macro with the weird appearance -{\catcode`/ 11 \catcode`! 11 \catcode32 11 |\ ! /|} (yes, this is a single -control sequence) must be left undefined. I trust it will be |;-)|.% -% -\footnote{The implementation is cloned from \LaTeX3, the - {\catcode`/ 11 \catcode`! 11 \catcode32 11 |\ ! /|} was chosen for its - shortness.} +You can try your hands at this simpler one: +\begin{everbatim*} +1/49=\xintTrunc{42+5}{1/49}...\newline +\xintTrim{2}{\xintTrunc{21}{1/49}}\newline +\xintKeep{-21}{\xintTrunc{42}{1/49}} +\end{everbatim*} -% Deprecated macros also generate an (expandable) error message. Just hit the -% |RETURN| key once to proceed.\IMPORTANT\ Most deprecated macros at |1.2o| are -% listed either in \autoref{ssec:coredeprecated} or -% \autoref{ssec:xintdeprecated} or \autoref{ssec:xintdeprecatedNum}. All -% were removed at |1.3|. +This was again an example of the type |1/N| with |N| the square of a prime. +One can also find counter-examples within this class: |1/31^2| and |1/37^2| +have an odd period length (|465| and respectively |111|) hence they can not +exhibit the symmetry. -The expression parsers are at |1.2l| still using a slightly less evolved -method which lets \TeX{} display an undefined control sequence name giving -some indication of the underlying problem (we copied this method from the -|bigintcalc| package). The name of the control sequence is the message. +\begin{framed} + Mathematical challenge: prove generally that if the period length of the + decimal expansion of |1/p^r| (with |p| a prime distinct from |2| and |5| and + |r| a positive exponent) is even, then the previously observed symmetry + about the two halves of the period adding to a string of nine's applies. +\end{framed} -\begin{multicols}{2}\parskip0pt\relax -\begin{everbatim} -\xintError:ignored -\xintError:removed -\xintError:inserted -\xintError:unknownfunction -\xintError:we_are_doomed -\xintError:missing_xintthe! -\end{everbatim} -\end{multicols} -Some constructs in \xintexprname-essions use delimited macros and there is -thus possibility in case of an ill-formed expression to end up beyond the -|\relax| end-marker. Such a situation can also occur from a non-terminated -|\numexpr|: -\begin{everbatim} -\xinttheexpr 3 + \numexpr 5+4\relax followed by some LaTeX code... -\end{everbatim} -as the |\numexpr| will swallow the |\relax| whose presence is mandatory for -|\xinttheexpr|, errors will inevitably arise and may -lead to very cryptic messages; but nothing unusual or especially traumatizing -for the daring experienced \TeX/\LaTeX\ user, whose has seen zillions of -un-helpful error messages already in her daily practice of -\TeX/\LaTeX.\footnote{not to mention the \LaTeX\ error messages used by - Emacs AUC\TeX\ mode also for Plain \TeX\ runs...} +\subsection{\csh{xintTFrac}}\label{xintTFrac} +\csa{xintTFrac}|{f}|\etype{\Ff} returns the fractional part, +|f=trunc(f)+frac(f)|. Thus if |f<0|, then |-10| one has +|0<= frac(f)<1|. The |T| stands for `Trunc', and there should exist also +similar macros associated respectively with `Round', `Floor', and `Ceil', each +type of rounding to an integer deserving arguably to be associated with a +fractional ``modulo''. By sheer laziness, the package currently implements +only the ``modulo'' associated with `Truncation'. Other types of modulo may be +obtained more cumbersomely via a combination of the rounding with a subsequent +subtraction from |f|. -\subsection{Package namespace, catcodes} +Notice that the result is filtered through \csbxint{REZ}, and will thus be of +the form |A/B[N]|, where neither |A| nor |B| has trailing zeros. But the +output fraction is not reduced to smallest terms. +The function call in expressions (\csbxint{expr}, \csbxint{floatexpr}) is +|frac|. Inside |\xintexpr..\relax|, the function |frac| is mapped to +\csa{xintTFrac}. Inside |\xintfloatexpr..\relax|, |frac| first applies +\csa{xintTFrac} to its argument (which may be an exact fraction with more +digits than the floating point precision) and only in a second stage makes the +conversion to a floating point number with the precision as set by |\xintDigits| +(default is \dtt{16}). +\begin{everbatim*} +\xintTFrac {1235/97}, \xintTFrac {-1235/97}\newline +\xintTFrac {1235.973}, \xintTFrac {-1235.973}\newline +\xintTFrac {1.122435727e5}\par +\end{everbatim*} -The bundle packages needs that the \csa{space} and \csa{empty} control -sequences are pre-defined with the identical meanings as in Plain \TeX{} (or -\LaTeX2e which has the same macros). +\subsection{\csh{xintRound}}\label{xintRound} -Private macros of \xintkernelname, \xintcorename, \xinttoolsname, -\xintname, \xintfracname, \xintexprname, \xintbinhexname, \xintgcdname, -\xintseriesname, and \xintcfracname{} use one or more underscores |_| as -private letter, to reduce the risk of getting overwritten. They almost -all begin either with |\XINT_| or with |\xint_|, a handful of these -private macros such as \csa{XINTsetupcatcodes}, \csa{XINTdigits} and -those with names such as |\XINTinFloat...| or |\XINTinfloat...| do not -have any underscore in their names (for obscure legacy reasons). +\csa{xintRound}|{x}{f}|\etype{\numx\Ff} returns the start of the decimal +expansion of the fraction |f|, rounded to: +\begin{itemize} +\item if |x>0|, |x| digits after the decimal mark, +\item if |x=0|, an integer, +\item if |x<0|, an integer multiple of |10^{-x}| (in scientific notation).\NewWith{1.4a} +\end{itemize} +The output is the sole digit token \dtt{0} if and only if the input was +exactly zero; else it contains always either a decimal mark (even if |x=0|) or +a scientific part and it conserves the sign of |f| (even if the rounded value +represents the zero value). +\begin{everbatim*} +\xintFor* #1 in {\xintSeq[-1]{7}{-14}}:{\xintRound{#1}{-11e12/7}\newline}% +\xintRound{10}{1e-11}\newline +\xintRound{10}{1/65536}\newline +\end{everbatim*}% +Rounding is done with half-way numbers going towards infinity of +the same sign. -\xintkernelname provides \hyperref[odef]{|\odef|}, \hyperref[oodef]{|\oodef|}, -\hyperref[fdef]{|\fdef|}: if macros with these names already exist -\xinttoolsname will not overwrite them. The same meanings are independently -available under the names |\xintodef|, |\xintoodef|, etc... +\subsection{\csh{xintFloor}}\label{xintFloor} -Apart from |\thexintexpr|, |\thexintiexpr|, ... -all other public macros from the \xintname bundle packages start with |\xint|. +|\xintFloor {f}|\etype{\Ff} returns the largest relative integer |N| with +|N|${}\leqslant{}$|f|. +\begin{everbatim*} +\xintFloor {-2.13}, \xintFloor {-2}, \xintFloor {2.13} +\end{everbatim*} +Note the trailing |[0]|, see \csbxint{iFloor} if it is not desired. -For the good functioning of the macros, standard catcodes are assumed for the -minus sign, the forward slash, the square brackets, the letter `e'. These -requirements are dropped inside an |\xintexpr|-ession: spaces are gobbled, -catcodes mostly do not matter, the |e| of scientific notation may be |E| (on -input) \dots{} +\subsection{\csh{xintCeil}}\label{xintCeil} -If a character used in the |\xintexpr| syntax is made active, -this will surely cause problems; prefixing it with |\string| is one option. -There is \csbxint{exprSafeCatcodes} and \csbxint{exprRestoreCatcodes} to -temporarily turn off potentially active characters. +|\xintCeil {f}|\etype{\Ff} returns the smallest relative integer |N| with +|N|${}>{}$|f|. +\begin{everbatim*} +\xintCeil {-2.13}, \xintCeil {-2}, \xintCeil {2.13} +\end{everbatim*} -\begin{framed} - For advanced \TeX\ users. At loading time of the packages the - catcode configuration may be arbitrary as long as it satisfies the following - requirements: the percent is of category code comment character, the - backslash is of category code escape character, digits have category code - other and letters have category code letter. Nothing else is assumed. -\end{framed} +\subsection{\csh{xintiTrunc}}\label{xintiTrunc} -As pointed out in previous section the control sequence {\catcode`/ 11 - \catcode`! 11 \catcode32 11 |\ ! /|} must be left undefined. +\csa{xintiTrunc}|{x}{f}|\etype{\numx\Ff} returns the integer equal to |10^x| +times what \csa{xintTrunc}|{x}{f}| would produce. Attention that leading zeros +are automatically removed: the output is in strict integer format. +\begin{everbatim*} +\xintFor* #1 in {\xintSeq[-1]{7}{-14}}:{\xintiTrunc{#1}{-11e12/7}\newline}% +\xintiTrunc{10}{1e-11}\newline +\xintiTrunc{10}{1/65536}\par +\end{everbatim*} -\subsection{Origins of the package} -\label{ssec:origins} +\subsection{\csh{xintTTrunc}}\label{xintTTrunc} -|2013/03/28.| Package |bigintcalc| by \textsc{Heiko Oberdiek} already -provides expandable arithmetic operations on ``big integers'', -exceeding the \TeX{} limits (of $2^{31}-1$), so why another% -% -\footnote{this section was written before the \xintfracname package; the - author is not aware of another package allowing expandable - computations with arbitrarily big fractions.} -% -one? +\csa{xintTTrunc}|{f}|\etype{\Ff} truncates to an integer (truncation towards +zero). This is the same as |\xintiTrunc {0}{f}| and also the same as +\csbxint{Num}. -I got started on this in early March 2013, via a thread on the -|c.t.tex| usenet group, where \textsc{Ulrich D\,i\,e\,z} used the -previously cited package together with a macro (|\ReverseOrder|) -which I had contributed to another thread.% -% -\footnote{the \csa{ReverseOrder} could be avoided in that circumstance, - but it does play a crucial r\^ole here.} -% -What I had learned in this -other thread thanks to interaction with \textsc{Ulrich D\,i\,e\,z} and -\textsc{GL} on expandable manipulations of tokens motivated me to -try my hands at addition and multiplication. +\subsection{\csh{xintiRound}}\label{xintiRound} -I wrote macros \csa{bigMul} and \csa{bigAdd} which I posted to the -newsgroup; they appeared to work comparatively fast. These first -versions did not use the \eTeX{} \csa{numexpr} primitive, they worked -one digit at a time, having previously stored carry-arithmetic in -1200 macros. +\csa{xintiRound}|{x}{f}|\etype{\numx\Ff} returns the integer equal to |10^x| +times what \csa{xintRound}|{x}{f}| would return. The output has no leading +zeroes, it is always in strict integer format. +\begin{everbatim*} +\xintFor* #1 in {\xintSeq[-1]{7}{-14}}:{\xintiRound{#1}{-11e12/7}\newline}% +\xintiRound{10}{1e-11}\newline +\xintiRound{10}{1/65536}\par +\end{everbatim*} -I noticed that the |bigintcalc| package used \csa{numexpr} -if available, but (as far as I could tell) not -to do computations many digits at a time. Using \csa{numexpr} for -one digit at a time for \csa{bigAdd} and \csa{bigMul} slowed them -a tiny bit but avoided cluttering \TeX{} memory with the 1200 -macros storing pre-computed digit arithmetic. I wondered if some speed -could be gained by using \csa{numexpr} to do four digits at a time -for elementary multiplications (as the maximal admissible number -for \csa{numexpr} has ten digits). +\subsection{\csh{xintiFloor}}\label{xintiFloor} -|2013/04/14|. This initial \xintname was followed by \xintfracname which -handled exactly fractions and decimal numbers. +|\xintiFloor {f}|\etype{\Ff} does the same as \csbxint{Floor} but without the +trailing |/1[0]|. +\begin{everbatim*} +\xintiFloor {-2.13}, \xintiFloor {-2}, \xintiFloor {2.13} +\end{everbatim*} -|2013/05/25|. Later came \xintexprname and at the same time \xintfracname got -extended to handle floating point numbers. +\subsection{\csh{xintiCeil}}\label{xintiCeil} -|2013/11/22|. Later, \xinttoolsname was detached. +|\xintiCeil {f}|\etype{\Ff} does the same as \csbxint{Ceil} but its output is +without the |/1[0]|. +\begin{everbatim*} +\xintiCeil {-2.13}, \xintiCeil {-2}, \xintiCeil {2.13} +\end{everbatim*} -|2014/10/28|. Release |1.1| significantly extended the \xintexprname parsers. +\subsection{\csh{xintE}}\label{xintE} -|2015/10/10|. Release |1.2| rewrote the core integer routines which had -remained essentially unmodified, apart from a slight improvement of division -early 2014. +|\xintE {f}{x}|\etype{\Ff\numx} multiplies the fraction |f| by $10^x$. The +\emph{second} argument |x| must obey the \TeX{} bounds. Example: +\begin{everbatim*} +\count 255 123456789 \xintE {10}{\count 255} +\end{everbatim*} +Don't feed this example to \csbxint{Num}! -This |1.2| release also got its impulse from a fast -``reversing'' macro, which I wrote after my interest got awakened again as a -result of correspondance with Bruno \textsc{Le Floch} during September 2015: -this new reverse uses a \TeX nique which \emph{requires} the tokens to be -digits. I wrote a routine which works (expandably) in quasi-linear time, but a -less fancy |O(N^2)| variant which I developed concurrently proved to be faster -all the way up to perhaps $7000$ digits, thus I dropped the quasi-linear one. -The less fancy variant has the advantage that \xintname can handle numbers -with more than $19900$ digits (but not much more than $19950$). This is with -the current common values of the input save stack and maximal expansion depth: -$5000$ and $10000$ respectively. +\subsection{\csh{xintCmp}}\label{xintCmp} -\clearpage -\let\xintbundlenameUp\undefined -\csname xintkernelnameUp\endcsname -\section{Macros of the \xintkernelname package} -\RaisedLabel{sec:kernel} +This\etype{\Ff\Ff} compares two fractions |F| and |G| and produces +|-1|, |0|, or |1| according to |FG|. -\localtableofcontents +For choosing branches according to the result of comparing |f| and |g|, see +\csbxint{ifCmp}. -The \xintkernelname package contains mainly the common code base for handling -the load-order of the bundle packages, the management of catcodes at loading -time, definition of common constants and macro utilities which are used -throughout the code etc ... it is automatically loaded by all packages of the -bundle. +\subsection{\csh{xintEq}}\label{xintEq} -It provides a few macros possibly useful in other contexts. +|\xintEq{f}{g}|\etype{\Ff\Ff} returns 1 if |f=g|, 0 otherwise. -\subsection{\csh{odef}, \csh{oodef}, \csh{fdef}} -\label{odef} -\label{oodef} -\label{fdef} +\subsection{\csh{xintNotEq}}\label{xintNotEq} -\csa{oodef}|\controlsequence {}| does -\everb|@ - \expandafter\expandafter\expandafter\def - \expandafter\expandafter\expandafter\controlsequence - \expandafter\expandafter\expandafter{} -| +|\xintNotEq{f}{g}|\etype{\Ff\Ff} returns 0 if |f=g|, 1 otherwise. -This works only for a single -|\controlsequence|, with no parameter text, even without parameters. An -alternative would be: -\everb|@ -\def\oodef #1#{\def\oodefparametertext{#1}% - \expandafter\expandafter\expandafter\expandafter - \expandafter\expandafter\expandafter\def - \expandafter\expandafter\expandafter\oodefparametertext - \expandafter\expandafter\expandafter } -| -\noindent -but it does not allow |\global| as prefix, and, besides, would have anyhow its -use (almost) limited to parameter texts without macro parameter tokens -(except if the expanded thing does not see them, or is designed to deal with -them). +\subsection{\csh{xintGeq}}\label{xintGeq} -There is a similar macro |\odef| with only one expansion of the replacement text -||, and |\fdef| which expands fully || using |\romannumeral-`0|. +This\etype{\Ff\Ff} compares the \emph{absolute values} of two +fractions. +|\xintGeq{f}{g}| outputs |1| if {\catcode`| 12 $|f|\geqslant|g|$} and |0| +if not. -They can be prefixed with |\global|. It appears than |\fdef| is generally a bit -faster than |\edef| when expanding macros from the \xintname bundle, when the -result has a few dozens of digits. |\oodef| needs thousands of digits it seems -to become competitive. +Important: the macro compares \emph{absolute values}. +\subsection{\csh{xintGt}}\label{xintGt} -\subsection{\csh{xintReverseOrder}}\label{xintReverseOrder} +|\xintGt{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$>$|g|, \dtt{0} otherwise. -\csa{xintReverseOrder}\marg{list}\etype{n} does not do any expansion of its -argument and just reverses the order of the tokens in the \meta{list}. Braces -are removed once and the enclosed material, now unbraced, does not get -reversed. Unprotected spaces (of any character code) are gobbled. -% -\leftedline{|\xintReverseOrder{\xintDigitsOf\xintiiPow {2}{100}\to\Stuff}|} -% -\leftedline{gives: - \ttfamily{\string\Stuff\string\to1002\string\xintiiPow\string\xintDigitsOf}} +\subsection{\csh{xintLt}}\label{xintLt} -\xinttoolsname provides a variant \csbxint{RevWithBraces} which keeps brace -pairs in the output, and \fexpan ds its input first. +|\xintLt{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$<$|g|, \dtt{0} otherwise. -For inputs consisting only digit tokens, see \csbxint{ReverseDigits} from -\xintname. +\subsection{\csh{xintGtorEq}}\label{xintGxstorEq} + +|\xintGtorEq{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$\geqslant$|g|, \dtt{0} otherwise. +Extended by \xintfracname to fractions. -\subsection{\csh{xintLength}} -\label{xintLength} +\subsection{\csh{xintLtorEq}}\label{xintLtorEq} -\csa{xintLength}\marg{list}\etype{n} counts how many tokens (or braced items) -there are (possibly none). It does no expansion of its argument, so to use it -to count things in the replacement text of a macro |\x| one should do -|\expandafter\xintLength\expandafter{\x}|. Blanks between items are not -counted. See also \csbxint{NthElt}|{0}| (from \xinttoolsname) -which first \fexpan ds its argument and then applies the same code. -% -\leftedline{|\xintLength {\xintiiPow {2}{100}}|\dtt{=\xintLength - {\xintiiPow{2}{100}}}} -% -\leftedline{${}\neq{}$|\xintLen {\xintiiPow {2}{100}}|\dtt{=\xintLen - {\xintiiPow{2}{100}}}} +|\xintLtorEq{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$\leqslant$|g|, \dtt{0} otherwise. -\subsection{\csh{xintFirstItem}} -\label{xintFirstItem} +\subsection{\csh{xintIsZero}}\label{xintIsZero} -\csa{xintFirstItem}\marg{list}\etype{n} returns the first item of its -argument, one pair of braces removed. If the list has no items the output is -empty.\NewWith{1.4} +|\xintIsZero{f}|\etype{f} returns \dtt{1} if |f=0|, \dtt{0} otherwise. -It does no expansion. For this and the next similar ones, see -|sourcexint.pdf| for comments on limitations. +\subsection{\csh{xintIsNotZero}}\label{xintIsNotZero} -\subsection{\csh{xintLastItem}} -\label{xintLastItem} +|\xintIsNotZero{f}|\etype{f} returns \dtt{1} if |f!=0|, \dtt{0} otherwise. -Added at |1.2i|. +\subsection{\csh{xintIsOne}}\label{xintIsOne} -\csa{xintLastItem}\marg{list}\etype{n} returns the last item -of its argument, one pair of braces removed. If the list has no items the -output is empty. +|\xintIsOne{f}|\etype{f} returns \dtt{1} if |f=1|, \dtt{0} otherwise. -It does no expansion, which should be obtained via suitable |\expandafter|'s. -See also \csbxint{NthElt}|{-1}| from \xinttoolsname which obtains the same -result (but with another code) after having however \fexpan ded its -argument first. +\subsection{\csh{xintOdd}}\label{xintOdd} -\subsection{\csh{xintFirstOne}} -\label{xintFirstOne} +|\xintOdd{f}|\etype{f} returns \dtt{1} if the integer obtained by truncation is +odd, and \dtt{0} otherwise. -\csa{xintFirstOne}\marg{list}\etype{n} returns the first item as a braced -item. I.e. if it was braced the braces are kept, else the braces are added. -It looks like using \csbxint{FirstItem} within braces, but the difference is -when the input was empty. Then the output is empty.\NewWith{1.4} +\subsection{\csh{xintEven}}\label{xintEven} -It does no expansion, which should be obtained via suitable |\expandafter|'s. +|\xintEven{f}|\etype{f} returns \dtt{1} if the integer obtained by truncation is +even, and \dtt{0} otherwise. -\subsection{\csh{xintLastOne}} -\label{xintLastOne} +\subsection{\csh{xintifSgn}}\label{xintifSgn} -\csa{xintLastOne}\marg{list}\etype{n} returns the last item as a braced -item. I.e. if it was braced the braces are kept, else the braces are added. -It looks like using \csbxint{LastItem} within braces, but the -difference is when the input was empty. Then the output is empty.\NewWith{1.4} +\csh{xintifSgn}\marg{f}\marg{A}\marg{B}\marg{C}\etype{\Ff nnn} executes either the +\meta{A}, \meta{B} or \meta{C} code, depending on its first argument being +respectively negative, zero, or positive. -It does no expansion, which should be obtained via suitable |\expandafter|'s. +\subsection{\csh{xintifZero}}\label{xintifZero} -\subsection{\csh{xintReplicate}, \csh{xintreplicate}} -\label{xintreplicate} -\label{xintReplicate} +\csa{xintifZero}\marg{f}\marg{IsZero}\marg{IsNotZero}\etype{\Ff nn} expandably +checks if the first mandatory argument |N| (a number, possibly a fraction if +\xintfracname is loaded, or a macro expanding to one such) is zero or not. It +then either executes the first or the second branch. -\csa{romannumeral}\csa{xintreplicate}|{x}|\marg{stuff}\etype{\numx n} is simply -copied over from \LaTeX3's |\prg_replicate:nn| with some minor changes.% -% -\footnote{I started with the code from Joseph \textsc{Wright} -available on an online site.} +Beware that both branches must be present. -And \csa{xintReplicate}|{x}| integrates the -\csa{romannumeeral} prefix.\NewWith{1.4} +\subsection{\csh{xintifNotZero}}\label{xintifNotZero} -It -does not do any expansion of its second argument but inserts it in the upcoming -token stream precisely |x| times. Using it with a negative |x| raises no error -and does nothing.% -% -\footnote{This behaviour may change in future.} +\csa{xintifNotZero}\marg{N}\marg{IsNotZero}\marg{IsZero}\etype{\Ff nn} +expandably checks if the first mandatory argument |f| is not +zero or is zero. It then either executes the first or the second branch. -Note that expansion must be triggered by a |\romannumeral|. +Beware that both branches must be present. - -\subsection{\csh{xintGobble}, \csh{xintgobble}} -\label{xintgobble} -\label{xintGobble} +\subsection{\csh{xintifOne}}\label{xintifOne} -\csa{romannumeral}\csa{xintgobble}|{x}|\etype{\numx} is a Gobbling macro -written in the spirit of \LaTeX3's |\prg_replicate:nn| (which I cloned as -\csbxint{replicate}.) It gobbles |x| tokens upstream, with |x| allowed to be -as large as \dtt{531440}. Don't use it with |x<0|. +\csa{xintifOne}\marg{N}\marg{IsOne}\marg{IsNotOne}\etype{\Ff nn} expandably +checks if the first mandatory argument |f| is one or not one. It +then either executes the first or the second branch. Beware that both branches +must be present. -And \csa{xintGobble}|{x}| integrates the \csa{romannumeral}.\NewWith{1.4} +\subsection{\csh{xintifOdd}}\label{xintifOdd} -Note that expansion must be triggered by a |\romannumeral|. +\csa{xintifOdd}\marg{N}\marg{odd}\marg{not odd}\etype{\Ff nn} expandably +checks if the first mandatory argument |f|, after truncation to an integer, is +odd or even. It then executes accordingly the first or the second branch. +Beware that both branches must be present. -\csbxint{gobble} looks as if it must be related to \csbxint{Trim} from -\xinttoolsname, but the latter uses different code (using directly -\csbxint{gobble} is not possible because one must make sure not to gobble more -than the number of available items; and counting available items first is an -overhead which \csbxint{Trim} avoids.) It is rather\csbxint{Keep} with a -negative first argument which hands over to \csbxint{gobble} (because in that -case it is needed to count anyhow beforehand the number of items, hence -\csbxint{gobble} can then be used safely.) +\subsection{\csh{xintifCmp}}\label{xintifCmp} -I wrote an \csa{xintcount} in the same spirit as \csa{xintreplicate} and -\csa{xintgobble}. But it needs to be counting hundreds of tokens to be worth -its salt compared to \csbxint{Length}. +\csa{xintifCmp}\marg{f}\marg{g}\marg{if fg}\etype{\Ff\Ff nnn} compares its first two arguments and chooses accordingly +the correct branch. -\subsection{(WIP) \csh{xintUniformDeviate}} -\label{xintUniformDeviate} +\subsection{\csh{xintifEq}}\label{xintifEq} -\csa{xintUniformDeviate}|{x}|\etype{\numx} is a wrapper of engine -|\pdfuniformdeviate| (or |\uniformdeviate|).% -% -\footnote{The |\uniformdeviate| primitive has been added to Xe\TeX\ - and will be available with \TeX Live 2019 release.} -The implementation is to be -considered experimental for the time being.% +\csa{xintifEq}\marg{f}\marg{g}\marg{YES}\marg{NO}\etype{\Ff\Ff nn} checks +equality of its two first arguments and executes accordingly the |YES| or the +|NO| branch. -The argument is expanded in |\numexpr| and the macro itself needs two -expansion steps. It produces like the engine primitive an integer (digit -tokens) with minimal value \dtt{0} and maximal one \dtt{x-1} if |x| is -positive, or minimal value \dtt{x+1} and maximal value \dtt{0} if |x| is -negative. For the discussion next, |x| is supposed positive as this -avoids having to insert absolute values in formulas. +\subsection{\csh{xintifGt}}\label{xintifGt} -The underlying engine Random Number Generator works with an array of 55 28bits -integers. To produce a « uniform » random integer in a given range -\dtt{0..x-1} it produces next pseudo-random |y| (supposedly uniformly -distributed, i.e. non-uniformity can be neglected) such that \dtt{$0\leq y < - 2^{28}$} and the output is the rounding of \dtt{$x*(y/2^{28})$}, with upper -bound |x| remapped to |0|. This has following corollaries: -\begin{enumerate} -\item with |x=2^{29}| or |x=2^{30}| the engine primitive produces only even - numbers, -\item with |x=3*2^{26}| the integers produced by the RNG when taken modulo - three obey the proportion |1:1:2|, not |1:1:1|, -\item with |x=3*2^{14}| there is analogous although weaker non-uniformity of - the random integers when taken modulo 3, -\item generally speaking pure powers of two should generate uniform random - integers, but when the range is divisible by large powers of - two, the non-uniformity may be amplified in surprising ways by modulo - operations. -\end{enumerate} -These observations are not to be construed as criticism of the engine -primitive itself, which comes from MetaPost, as the code comments and more -generally the whole of \emph{The Art of Computer Programming, Vol. 2} stresses -that it should rather be seen as producing random fractions (the unit fraction -being $2^{28}$). Using it as a generator for \emph{integers} is a bit of an -abuse. +\csa{xintifGt}\marg{f}\marg{g}\marg{YES}\marg{NO}\etype{\Ff\Ff nn} +checks if $f>g$ and in that case executes the |YES| branch. -The first goal of \csa{xintUniformDeviate} is to guarantee a better uniformity -for the distribution of random integers in any given range |x|. +\subsection{\csh{xintifLt}}\label{xintifLt} -\emph{If the probability to obtain a given |y| in |0..x-1| is - \verb$(1+e(y))/x$, the ``{relative non-uniformity}'' for that value |y| is - \verb$|e(y)|$.} +\csa{xintifLt}\marg{f}\marg{g}\marg{YES}\marg{NO}\etype{\Ff\Ff nn} +checks if $fM|, \dtt{0} if |N=M|, -and \dtt{-1} if |N1+ and |x<0|, an error is raised. There will also -be an error if |x| exceeds the maximal \eTeX{} number \dtt{\number"7FFFFFFF}, -but the real limit for exponents comes from either the computation time or the -settings of some \TeX\ memory parameters. +\begin{everbatim*} +\xintMinof {{1.23}{1.2299}{1.2301}} and \xintMinof {{-1.23}{-1.2299}{-1.2301}} +\end{everbatim*} -\begin{framed} - Indeed, the maximal power of $2$ which \xintname is able to compute - explicitely is |2^(2^17)=2^131072| which has \dtt{39457} digits. This - exceeds the maximal size on input for the \xintcorename multiplication, hence - any |2^N| with a higher |N| will fail. On the other hand |2^(2^16)| has - \dtt{19729} digits, thus it can be squared once to obtain |2^(2^17)| or - multiplied by anything smaller, thus all exponents up to and including |2^17| - are allowed (because the power operation works by squaring things and making - products). -\end{framed} +\subsection{\csh{xintSum}}\label{xintSum} -% Side remark: after all it does pay to think! I almost melted my CPU trying by -% dichotomy to pin-point the exact maximal allowable |N| for |\xintiiPow 2{N}| -% before finally making the reasoning above. Indeed, each such computation with -% |N>130000| activates the fan of my laptop and results in so warm a keyboard -% that I can hardly go on working on it! And it takes about 12 minutes for each -% |\xintiiPow2{N}| with such |N|'s of the order of $130000$ (a.t.t.o.w.). +This\etype{f{$\to$}{\lowast\Ff}} computes the sum of fractions. The output +will now always be in the form |A/B[n]|. The original, for big integers only +(in strict format), is available as \csa{xintiiSum}. -\subsection{\csh{xintiiFac}}\label{xintiiFac} +\begin{everbatim*} +\xintSum {{1282/2196921}{-281710/291927}{4028/28612}} +\end{everbatim*} -|\xintiiFac|\x\etype{\numx} computes the factorial. +No simplification attempted. -\begin{framed} - The (theoretically) allowable range is $0\leqslant x\leqslant10000$. +\subsection{\csh{xintPrd}}\label{xintPrd} - However the maximal possible computation depends on the values of some memory - parameters of the |tex| executable: with the current default settings of - TeXLive 2015, the maximal computable factorial (a.t.t.o.w. 2015/10/06) turns - out to be $5971!$ which has $19956$ digits.%\footnotemark -\end{framed} +TThis\etype{f{$\to$}{\lowast\Ff}} computes the product of fractions. The output +will now always be in the form |A/B[n]|. The original, for big integers only +(in strict format), is available as \csa{xintiiPrd}. +\begin{everbatim*} +\xintPrd {{1282/2196921}{-281710/291927}{4028/28612}} +\end{everbatim*} +No simplification attempted. -The |factorial| function, or equivalently |!| as post-fix operator is -available in \csbxint{iiexpr}, \csbxint{expr}: \begin{everbatim*} -\printnumber{\xinttheiiexpr 200!\relax}\par +$\xintIsOne {21921379213/21921379213}\neq\xintIsOne {1.00000000000000000000000000000001}$ \end{everbatim*} -See also \csbxint{FloatFac} from package \xintfracname for the float variant, -used in \csbxint{floatexpr}. +\subsection{\csh{xintGCD}}\label{xintGCD} +The greatest common divisor of its two arguments, which are possibly +\emph{fractions}.\etype{\Ff\Ff} -\subsection{\csh{xintiiDivision}}\label{xintiiDivision} +A macro of the same name existed formerly in \xintgcdname but it truncated +its arguments to integers via \csbxint{Num}. +\subsection{\csh{xintLCM}}\label{xintLCM} -|\xintiiDivision|\m\n\etype{ff} produces |{quotient}{remainder}|, in the sense -of (mathematical) Euclidean division: |M = QN + R|, -|0|${}\leq{}$\verb+R < |N|+. So the remainder is always non-negative and the -formula |M = QN + R| always holds independently of the signs of |N| or |M|. -Division by zero is an error (even if |M| vanishes) and returns |{0}{0}|. +The least common multiple of its two arguments, which are possibly +\emph{fractions}.\etype{\Ff\Ff} -\subsection{\csh{xintiiQuo}}\label{xintiiQuo} +A macro of the same name existed formerly in \xintgcdname but it truncated +its arguments to integers via \csbxint{Num}. -|\xintiiQuo|\m\n\etype{ff} computes the quotient from the Euclidean division. +\subsection{\csh{xintGCDof}}\label{xintGCDof} -\subsection{\csh{xintiiRem}}\label{xintiiRem} +\csa{xintGCDof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast\Ff}} computes the +greatest common divisor of a|a|, |b|, \dots{}, which are +possibly\emph{fractions} (i.e. the non-negative generator of the fractional +ideal they generate). The list argument may be a macro as it is \fexpan ded +first. It is a support macro for the |gcd()| function of +\xintexprname. -|\xintiiRem|\m\n\etype{ff} computes the remainder from the Euclidean -division. +A macro of the same name existed formerly in \xintgcdname: it truncated all +its arguments to integers via \csbxint{Num}. It has now been removed and one +must load \xintfracname to get the macro. -\subsection{\csh{xintiiDivRound}}\label{xintiiDivRound} +Added this documentation. See \csbxint{iiGCDof} for the integer +only variant. -|\xintiiDivRound|\m\n\etype{ff} returns the rounded value of the algebraic -quotient $M/N$ of two big integers. The rounding is ``away from zero.'' -\begin{everbatim*} -\xintiiDivRound {100}{3}, \xintiiDivRound {101}{3} -\end{everbatim*} +\subsection{\csh{xintLCMof}}\label{xintLCMof} -\subsection{\csh{xintiiDivTrunc}}\label{xintiiDivTrunc} +\csa{xintLCMof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast\Ff}} computes the least +common multiple of |a|, |b|, \dots{}, which are possibly \emph{fractions}. The +list argument may be a macro, it is \fexpan ded first. If one of the item +vanishes, then also the output. It is a support macro for the |lcm()| function +of \xintexprname. -|\xintiiDivTrunc|\m\n\etype{ff} computes $trunc(M/N)$. For positive arguments -$M,N>0$ it is the same as the Euclidean quotient \csbxint{iiQuo}. -\begin{everbatim*} -\xintiiQuo{1000}{57} (Euclidean), \xintiiDivTrunc{1000}{57} (truncated), -\xintiiDivRound{1000}{57} (rounded)\newline -\xintiiQuo{-1000}{57}, \xintiiDivTrunc{-1000}{57} (t), \xintiiDivRound{-1000}{57} (r)\newline -\xintiiQuo{1000}{-57}, \xintiiDivTrunc{1000}{-57} (t), \xintiiDivRound{1000}{-57} (r)\newline -\xintiiQuo{-1000}{-57}, \xintiiDivTrunc{-1000}{-57} (t), \xintiiDivRound{-1000}{-57} (r)\par -\end{everbatim*} +A macro of the same name existed formerly in \xintgcdname: it truncated all +its arguments to integers via \csbxint{Num}. It has now been removed and one +must load \xintfracname to get the macro. -\subsection{\csh{xintiiDivFloor}}\label{xintiiDivFloor} +Added this documentation. See \csbxint{iiLCMof} for the integer +only variant. -|\xintiiDivFloor|\m\n\etype{ff} computes $floor(M/N)$. For positive divisor -$N>0$ and arbitrary dividend $M$ it is the same as the Euclidean quotient -\csbxint{iiQuo}. -\begin{everbatim*} -\xintiiQuo{1000}{57} (Euclidean), \xintiiDivFloor{1000}{57} (floored)\newline -\xintiiQuo{-1000}{57}, \xintiiDivFloor{-1000}{57}\newline -\xintiiQuo{1000}{-57}, \xintiiDivFloor{1000}{-57}\newline -\xintiiQuo{-1000}{-57}, \xintiiDivFloor{-1000}{-57}\par -\end{everbatim*} +\subsection{\csh{xintDigits}, \csh{xinttheDigits}} +\label{xintDigits} +\label{xinttheDigits} -\subsection{\csh{xintiiMod}}\label{xintiiMod} +The syntax |\xintDigits := D;| assigns the value of |D| to the number of +digits to be used by floating point operations (this uses internally a +|\mathchardef| assignement, and |D| stands for (or expands to) a legal \TeX\ +number). The default is |16|. The maximal value is |32767|. +\begin{framed} + \xintexprname adds\IMPORTANTf{} the variant \csbxint{Digits*} which executes + \csbxint{reloadxinttrig}. +\end{framed} -|\xintiiMod|\m\n\etype{ff} computes $M - N*floor(M/N)$. For positive divisor -$N>0$ and arbitrary dividend $M$ it is the same as the Euclidean remainder -\csbxint{iiRem}. +The expandable macro |\xinttheDigits|\etype{} serves to retrieve (internally +it uses |\number|) the current value. -Formerly, this macro computed $M - N*trunc(M/N)$. The former meaning is -retained as \csa{xintiiModTrunc}. +Spaces do not matter as long as they do not occur in-between digits: \begin{everbatim*} -\xintiiRem {1000}{57} (Euclidean), \xintiiMod {1000}{57} (floored), -\xintiiModTrunc {1000}{57} (truncated)\newline -\xintiiRem {-1000}{57}, \xintiiMod {-1000}{57}, \xintiiModTrunc {-1000}{57}\newline -\xintiiRem {1000}{-57}, \xintiiMod {1000}{-57}, \xintiiModTrunc {1000}{-57}\newline -\xintiiRem {-1000}{-57}, \xintiiMod {-1000}{-57}, \xintiiModTrunc {-1000}{-57}\par +\xintDigits := 24;\xinttheDigits, % +\xintDigits:=36 ;\xinttheDigits, % +\xintDigits:= 16 ;and \xinttheDigits. \end{everbatim*} -\subsection{\csh{xintNum}}\label{xintNum} +% It has always been the case that an active colon |:| was allowed. -|\xintNum|\etype{f} is originally an alias for \csbxint{iNum}. But with -\xintfracname loaded its meaning is \hyperref[xintNumFrac]{modified} to accept -more general inputs. It then becomes an alias to \csbxint{TTrunc} which -truncates the general input to an integer in strict format. +Also |\xintDigits = D;| (i.e.\@ without a colon) is accepted syntax. -% \subsection{Removed macros}\label{ssec:coredeprecated} +An ending active semi-colon |;| is \emph{not} compatible: it can and will +cause low-level \TeX{} errors. But this has a trivial workaround: any +non-expanding token can be used in place of the ending semi-colon. For +example a full stop or a |\relax| token. This +non-expanding ending token will get removed from the token stream. -% These macros were deprecated at |1.2o| and removed at |1.3|. -% |\xintiiFDg| (renamed to \csbxint{FDg}), -% |\xintiiLDg| (renamed to \csbxint{LDg}), -% |\xintiOpp|, -% |\xintiAbs|, -% |\xintiAdd|, -% |\xintCmp| (it gets defined by \xintfracname, so deprecation will usually not be -% seen; the macro with this name from former \xintcorename should have been -% called |\xintiCmp| actually), -% |\xintSgn| (it also gets its proper definition from \xintfracname), -% |\xintiSub|, -% |\xintiMul|, -% |\xintiDivision|, -% |\xintiQuo|, -% |\xintiRem|, -% |\xintiDivRound|, -% |\xintiDivTrunc|, -% |\xintiMod|, -% |\xintiSqr|, -% |\xintiPow|, -% |\xintiFac|. +% This +% restriction always applied, but never got properly documented prior to +% |1.3f| release... It is possible to use |\string;| but then there can not be +% any space separating it from the digits. +The recommended syntax is thus now |\xintDigits := D\relax| (with or without the colon). +This is the syntax in use in most examples from the documentation. +\begin{everbatim*} +\xintDigits = 24\def\xinttheDigits, % only for showing it works! don't do that! +\xintDigits := 36.\xinttheDigits, % one can use a dot in place of semi-colon +\xintDigits = 16\relax and \xinttheDigits.\par % with \relax, even better +\end{everbatim*} -\clearpage -\let\xintcorenameUp\undefined -\csname xintnameUp\endcsname -\def\n{|{N}|} -\def\m{|{M}|} -\def\x{|{x}|} -\section{Macros of the \xintname package} -\RaisedLabel{sec:xint} +\subsection{\csh{xintSetDigits}} +\label{xintSetDigits} -This package loads automatically \xintcorename (and \xintkernelname) hence -all macros described in \autoref{sec:core} are still available. +To be used as |\xintSetDigits|\marg{expression}\ntype{\numx} where the +expression will be fed to |\numexpr|. It is a shortcut for doing +|\xintDigits := \numexpr|\meta{expression}|\relax \relax|. +\begin{everbatim*} +\xintSetDigits{1+2+3+4+5}The value is now \xinttheDigits. +\xintSetDigits{2*8}The value is now \xinttheDigits.\par +\end{everbatim*} +\begin{framed} + See also the \xintexprname-added variant \csbxint{SetDigits*}. +\end{framed} -\etocsetnexttocdepth{subsubsection} -\localtableofcontents +\subsection{\csh{xintFloat}}\label{xintFloat} -This is \texttt{\xintbndlversion} of -\texttt{\xintbndldate}. -Version |1.0| was released |2013/03/28|. -Since |1.1 2014/10/28| the core arithmetic macros have been moved to a separate -package \xintcorename, which is automatically loaded by \xintname. -Only the \csbxint{iiSum}, \csbxint{iiPrd}, \csbxint{iiSquareRoot}, -\csbxint{iiPFactorial}, \csbxint{iiBinomial} genuinely add to the arithmetic -macros from \xintcorename. (\csbxint{iiFac} which computes factorials is -already in \xintcorename.) +The macro |\xintFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} has an optional +argument |P| which replaces the current value of |\xinttheDigits|. The +fraction |f| is then printed in scientific notation with a rounding to |P| digits. -With the exception of \csbxint{Len}, of the «Boolean logic macros» (see -next paragraphs) all macros require inputs being integers in strict format, see \autoref{ssec:inputs}.% -% -\footnote{of -course for conditionals such as \csbxint{iiifCmp} this constraint applies only -to the first two arguments.} -% -The |ii| in the macro names is here as a reminder of that fact. The output is -an integer in strict format, or a pair of two braced such integers for -\csbxint{iiSquareRoot}, with the exception of \csbxint{iiE} which may produce -strings of zero's if its first argument is zero. +That is, on output: the first digit is from |1| to |9|, it is possibly +prefixed by a minus sign and is followed by a dot and |P-1| digits, then a +lower case |e| and an exponent |N|. The trailing zeroes are not trimmed. -Macros \csbxint{DecSplit} and \csbxint{ReverseDigits} are non-arithmetic and -have their own specific rules. +\begin{framed} + There is currently one exceptional case: the zero value, which gets output + as \dtt{\xintFloat{0}}. It is yet to be decided what the final policy will be. +\end{framed} -For all macros described here for which it makes sense, package \xintfracname -defines a similar one without |ii| in its name. This will handle more general -inputs: decimal, scientific numbers, fractions. The |ii| macros provided here -by \xintname can be nested inside macros of \xintfracname but the opposite -does not apply, because the output format of the \xintfracname macros, even -for representing integers, is not understood by the |ii| macros. The «Boolean -macros» \csbxint{AND} etc... are exceptions though, they work fine if served -as inputs some \xintfracname output, despite doing only \fexpan -sion. Prior to |1.2o|, these macros did apply the \csbxint{Num} -or the more general \xintfracname general parsing, but this overhead was -deemed superfluous as it serves only to handle hand-written input and is not -needed if the input is obtained as a nested chain of \xintfracname macros for -example. +Starting with |1.2k|, when the input is a fraction |AeN/BeM| +the output always is the \emph{correct rounding} to |P| digits. Formerly, this +was guaranteed only when |A| and |B| had at most |P+2| digits, or when |B| was +|1| and |A| was arbitrary, but in other cases it was only guaranteed that the +difference between the original fraction and the rounding was at most +\dtt{0.6} unit in the last place (of the output), hence the output could +differ in the last digit (and earlier ones in case of chains of zeros or +nines) from the correct rounding. -Prior to release |1.2o|, \xintname defined additional macros which applied -\csbxint{Num} to their input arguments. All these macros were deprecated at -|1.2o| and have been removed at |1.3|. +Also: for releases |1.2j| and earlier, in the special case when +|A/B| ended up being rounded up to the next power of ten, the output was with +a mantissa of the shape |10.0...0eN|. However, this worked only for |B=1| or +when both |A| and |B| had at most |P+2| digits, because the detection of the +rounding-up to next power of ten was done not on original |A/B| but on an +approximation |A'/B'|, and it could happen that |A'/B'| was itself being +rounded \emph{down} to a power of ten which however was a rounding \emph{up} +of original |A/B|. With the |1.2j| refactoring which achieves correct rounding +in all cases, it was decided not to add to the code the extra overhead of +detecting with 100\% fiability the rounding up to next power of ten (such +overhead would necessitate alterations of the algorithm and as a result we +would end up with a slightly less efficient one; it would make sense in a +model where inputs have their intrinsic precisions which is obeyed by the +implementation of the basic operations, but currently the design decision for +the floating point macros is that when the target precision is |P| the inputs +are rounded first to |P| digits before further processing.) +\begin{everbatim*} +{\def\x{99999999999999994999999999999999/99999999999999999999999999999999}% +\xintFor #1 in {13, 14, 15, 16, 17, 18, 19, 47, 48, 49, 50, 79, 80, 81} +\do{#1: \xintFloat[#1]{\x}\xintifForLast{\par}{\newline}}}% +\end{everbatim*} +As an aside, which is illustrated by the above, rounding is not +transitive in the number of kept digits. +\begin{everbatim*} +{\def\x{137893789173289739179317/13890138013801398}% +\xintFor* #1 in {\xintSeq{4}{20}} +\do{#1: \xintFloat[#1]{\x}\newline}}% +\xintFloat{5/9999999999999999}\newline +\xintFloat[32]{5/9999999999999999}\newline +\xintFloat[48]{5/9999999999999999}\par +\end{everbatim*} -At |1.3d| macros \csbxint{iiGCD} and \csbxint{iiLCM} from package \xintgcdname -are also available from loading \xintname only. They are support macros for -the (multi-arguments) functions \func{gcd} and \func{lcm} in \csbxint{iiexpr}. -See \autoref{ssec:expansions} for the significance of the -\textcolor[named]{PineGreen}{\Numf}, \textcolor[named]{PineGreen}{\emph{f}}, -\textcolor[named]{PineGreen}{\numx} and \textcolor[named]{PineGreen}{$\star$} -margin annotations. +\subsection{\csh{xintPFloat}}\label{xintPFloat} +The macro |\xintPFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} is like +\csbxint{Float} but ``pretty-prints'' the output. Its behaviour has changed +with release |1.2f|\IMPORTANT{}: there is only one simplification rule now +which is that decimal notation (with possibly needed extra zeros) is used in +place of scientific notation when the exponent would end up being between +\dtt{-5} and \dtt{5} inclusive. +If the input vanishes the output will be \dtt{\xintPFloat{0}} with a a decimal +mark.% +% +\footnote{Currently there are no subnormal numbers, and no underflow + because the exponent is only limited by the maximal \TeX\ number; thus + underflow situations would manifest themselves via low-level arithmetic + overflow errors.} +\csbxint{thefloatexpr} applies this macro to its output (or each of +its outputs, if comma separated). -\subsection{\csh{xintiLen}}\label{xintiLen} +Currently trailing zeros are not trimmed. -|\xintiLen|\n\etype{\Numf} returns the length of the number, after its parsing -via \csbxint{iNum}. The count does not include the sign. \begin{everbatim*} -\xintiLen{-12345678901234567890123456789} +\begingroup\def\test #1{#1${}\to{}$\xintPFloat{#1}}% +\string\xintDigits\ at \xinttheDigits +\begin{itemize}[nosep] +\item \test {0} +\item \test {1.23456789e-7} +\item \test {1.23456789e-6} +\item \test {1.23456789e-5} +\item \test {1.23456789e-4} +\item \test {1.23456789e-3} +\item \test {1.23456789e-2} +\item \test {1.23456789e-1} +\item \test {1.23456789e0} +\item \test {1.23456789e1} +\item \test {1.23456789e2} +\item \test {1.23456789e3} +\item \test {1.23456789e4} +\item \test {1.23456789e5} +\item \test {1.23456789e6} +\item \test {1.23456789e7} +\end{itemize} +\endgroup \end{everbatim*} -Prior to |1.2o|, the package defined only \csbxint{Len}, which is extended by -\xintfracname to fractions or decimal numbers, hence acquires a bit more -overhead then. - -\subsection{\csh{xintReverseDigits}} \label{xintReverseDigits} - -\the\dp\strutbox, \the\ht\strutbox, \the\baselineskip -|\xintReverseDigits|\n\etype{f} will reverse the order of the digits of the -number. \csa{xintRev} is the former denomination and is kept as an alias. -Leading zeroes resulting from the operation are not removed. Contrarily to -\csbxint{ReverseOrder} this macro \fexpan ds its argument; it is only usable -with digit tokens. It does \emph{not} apply \csbxint{Num} to its argument (so -this must be done explicitely if the argument is an integer produced from some -\xintfracname macros). It does accept a leading minus sign which will be left -upfront in the output. +\subsection{\csh{xintFloatE}}\label{xintFloatE} -\begingroup +|\xintFloatE [P]{f}{x}|\etype{{\upshape[\numx]}\Ff\numx} multiplies the input +|f| by $10^x$, and +converts it to float format according to the optional first argument or current +value of |\xinttheDigits|. \begin{everbatim*} -\oodef\x{\xintReverseDigits - {98765432109876543210987654321098765432109876543210}}\meaning\x\par -\noindent\oodef\x{\xintReverseDigits {\xintReverseDigits - {98765432109876543210987654321098765432109876543210}}}\meaning\x\par +\xintFloatE {1.23e37}{53} \end{everbatim*} -\endgroup -\subsection{\csh{xintDecSplit}} -\label{xintDecSplit} +\subsection{\csh{xintFloatAdd}}\label{xintFloatAdd} -|\xintDecSplit|\x\n\etype{\numx f} cuts the |N| (a list of digits) into two -pieces |L| and |R|: it outputs |{L}{R}| where the original |N| -is the concatenation |LR|. These two pieces are decided according to |x|: -\begin{itemize}[nosep] -\item for |x>0|, |R| coincides with the |x| least significant digits. If |x| - equals or exceeds the length of |N| the first piece |L| will thus be - \emph{empty}, -\item for |x=0|, |R| is empty, and |L| is all of |N|, -\item for |x<0|, the first piece |L| consists of the \verb+|x|+ most - significant digits and the second piece |R| gets the remaining ones. If |x| - equals or exceeds the length of |N| the second piece |R| will thus be - \emph{empty}. -\end{itemize} -This macro provides public interface to some functionality which is primarily -of internal interest. It operates only (after \fexpan sion) on ``strings'' of -digits tokens: leading zeroes are allowed but a leading sign (even a minus -sign) will provoke an error. +|\xintFloatAdd [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| +and |g| with their float approximations |f'| and |g'| to |P| significant +places or to the precision from |\xintDigits|. It then produces +the sum |f'+g'|, correctly rounded to nearest with the same number of +significant places. -Breaking change with |1.2i|: formerly |N<0| was replaced by its - absolute value. Now, a sign (positive or negative) will create an error. +\subsection{\csh{xintFloatSub}}\label{xintFloatSub} -\subsection{\csh{xintDecSplitL}, \csh{xintDecSplitR}} -\label{xintDecSplitL} -\label{xintDecSplitR} -|\xintDecSplitL|\x\n\etype{\numx f} returns the first piece (unbraced) from -the \csa{xintDecSplit} output. +|\xintFloatSub [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| +and |g| with their float approximations |f'| and |g'| to |P| significant +places or to the precision from |\xintDigits|. It then produces +the difference |f'-g'| correctly rounded to nearest |P|-float. -\noindent|\xintDecSplitR|\x\n\etype{\numx f} returns the second piece -(unbraced) from the \csa{xintDecSplit} output. -\subsection{\csh{xintiiE}}\label{xintiiE} +\subsection{\csh{xintFloatMul}}\label{xintFloatMul} -|\xintiiE|\n\x\etype{f\numx } serves to extend |N| with |x| zeroes. The -parameter |x| must be non-negative. The same output would be obtained via -\csbxint{DSH}|{-x}{N}|, except for |N=0|, as |\xintDSH{-x}{N}| multiplies |N| -by |10^x| hence produces |0| if |N=0| whereas -|\xintiiE{0}{x}| produces |x+1| zeros. -\begin{everbatim*} -\xintiiE {0}{91}\par -\end{everbatim*} -\subsection{\csh{xintDSH}}\label{xintDSH} +|\xintFloatMul [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| +and |g| with their float approximations |f'| and |g'| to |P| (or +|\xinttheDigits|) significant places. It then correctly rounds +the product |f'*g'| to nearest |P|-float. -|\xintDSH|\x\n\etype{\numx f} is parametrized decimal shift. When |x| is -negative, it is like iterating \csbxint{DSL} \verb+|x|+ times (\emph{i.e.} -multiplication by $10^{-x}$). When |x| positive, it is like iterating -\csbxint{DSR} |x| times (and is more efficient), and for a non-negative |N| -this is thus the same as the quotient from the Euclidean division by |10^x|. +See \autoref{ssec:floatingpoint} for more. -\subsection{\csh{xintDSHr}, \csh{xintDSx}}\label{xintDSHr}\label{xintDSx} +\begin{framed} + It is obviously much needed that the author improves its algorithms to avoid + going through the exact |2P| or |2P-1| digits before + throwing to the waste-bin half of those digits ! -|\xintDSHr|\x\n\etype{\numx f} expects |x| to be zero or positive and it -returns then a value |R| which is correlated to the value |Q| returned by -\csbxint{DSH}\x\n{} in the following manner: -\begin{itemize} -\item if |N| is - positive or zero, |Q| and |R| are the quotient and remainder in - the Euclidean division by |10^x| (obtained in a more efficient - manner than using \csa{xintiiDivision}), -\item if |N| is negative let - |Q1| and |R1| be the quotient and remainder in the Euclidean - division by |10^x| of the absolute value of |N|. If |Q1| - does not vanish, then |Q=-Q1| and |R=R1|. If |Q1| vanishes, then - |Q=0| and |R=-R1|. -\item for |x=0|, |Q=N| and |R=0|. -\end{itemize} -So one has |N = 10^x Q + R| if |Q| turns out to be zero or -positive, and |N = 10^x Q - R| if |Q| turns out to be negative, -which is exactly the case when |N| is at most |-10^x|. + % \xintname initially was purely an \emph{exact} arbitrary precision + % arithmetic machine, and the introduction of floating point numbers was an + % after-thought. I got it working in release |1.07 (2013/05/25)| and never had + % time to come back to it. +\end{framed} + +\subsection{\csh{xintFloatDiv}}\label{xintFloatDiv} + + +|\xintFloatDiv [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| +and |g| with their float approximations |f'| and |g'| to |P| (or +|\xinttheDigits|) significant places. It then correctly rounds +the fraction |f'/g'| to nearest |P|-float. + +See \autoref{ssec:floatingpoint} for more. + +Notice in the special situation with |f| and |g| integers that |\xintFloatDiv +[P]{f}{g}| will \emph{not necessarily} give the correct rounding of the +exact fraction |f/g|. Indeed the macro arguments are each first individually +rounded to |P| digits of precision. The correct syntax to get the correctly +rounded integer fraction |f/g| is \csbxint{Float}|[P]{f/g}|. -|\xintDSx|\x\n\etype{\numx f} for |x| negative is exactly as -|\xintDSH|\x\n, \emph{i.e.} multiplication by $10^{-|x|}$. For |x| zero or -positive it returns the two numbers |{Q}{R}| described above, each one within -braces. So |Q| is |\xintDSH|\x\n, and |R| is |\xintDSHr|\x\n, but computed -simultaneously. +\subsection{\csh{xintFloatPow}}\label{xintFloatPow} -\subsection{\csh{xintiiEq}}\label{xintiiEq} +|\xintFloatPow [P]{f}{x}|\etype{{\upshape[\numx]}\Ff\numx} uses either the +optional argument |P| or in its absence the value of |\xinttheDigits|. It +computes a floating approximation to |f^x|. -|\xintiiEq|\n\m\etype{ff} returns 1 if |N=M|, 0 otherwise. +The exponent |x| will be handed over to a |\numexpr|, hence count registers are +accepted on input for this |x|. And the absolute value \verb+|x|+ must obey the +\TeX{} bound. -\subsection{\csh{xintiiNotEq}}\label{xintiiNotEq} +The argument |f| is first rounded to |P| significant places to give +|f'|. The output |Z| is such that the exact |f'^x| differs from +|Z| by an absolute error less than |0.52 ulp(Z)|. +\begin{everbatim*} +\xintFloatPow [8]{3.1415}{1234567890} +\end{everbatim*} -|\xintiiNotEq|\n\m\etype{ff} returns 0 if |N=M|, 1 otherwise. +\subsection{\csh{xintFloatPower}}\label{xintFloatPower} +\csa{xintFloatPower}|[P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Numf} computes a +floating point value |f^g| where the exponent |g| is not constrained to be at +most the \TeX{} bound \dtt{\number "7FFFFFFF}. It may even be a fraction +|A/B| but must simplify to a (possibly big) integer. The exponent of the +\emph{output} however \emph{must} at any rate obey the \TeX{} bound. -\subsection{\csh{xintiiGeq}}\label{xintiiGeq} +The argument |f| is first rounded to |P| significant places to give +|f'|. The output |Z| is then such that the exact |f'^g| differs from +|Z| by an absolute error less than |0.52 ulp(Z)|. -|\xintiiGeq|\n\m\etype{ff} returns 1 if the \emph{absolute value} -of the first number is at least equal to the absolute value of the second -number. If \verb+|N|<|M|+ it returns 0. +This is the macro which is used for the |^| (or |**|) infix operators in +|\xintthefloatexpr...\relax|. In this context (but not directly with the +macro,) half-integer exponents are allowed. This is handled via an integer power +followed by a square-root extraction. The exponent is first rounded to nearest +integer or half-integer so that the computation never raises errors (except +naturally for negative exponent and zero |f|.) The |0.52 ulp(Z)| bound applies +with half-integer exponents too. -Important: the macro compares \emph{absolute values}. -\subsection{\csh{xintiiGt}}\label{xintiiGt} +Notice that this is a bound on the distance from |f'^g| to |Z|, as |f| always +gets rounded to |P| or \csbxint{theDigits} digits. The distance from |f^g| to +|Z| can be much worse if |g| is very large. Roughly, when |g| is negligible +compared to |10^P|, we get an extra difference of up to about |50g ulp(Z)| +which completely dwarfs the |0.52 ulp(Z)|. Thus, if |f| has strictly more than +|P| digits, then the computation must be done with an elevated working +precision |P'|. For example with |g=1000| we should use |P'=P+6| to achieve a +total error at worst slightly bigger than |0.55 ulp(Z)| after the final +rounding from |P'| to |P| digits to get |Z|. -|\xintiiGt|\n\m\etype{ff} returns 1 if |N|$>$|M|, 0 otherwise. +Examples:% +% +\footnote{|\np| is formatting macro from the \url{http://ctan.org/pkg/numprint} + package.} +% +\begin{everbatim*} +\np{\xintFloatPower [8]{3.1415}{3e9}}\newline% Notice that 3e9>2^31 +\np{\xintFloatPower [48]{1.1547}{\xintiiPow {2}{35}}}\newline +\end{everbatim*}% +$2^{35}=\xintiiPow {2}{35}$ exceeds \TeX's bound, but what +counts is the exponent of the result which, while dangerously close to +$2^{31}$ is not quite there yet. -\subsection{\csh{xintiiLt}}\label{xintiiLt} +With expressions: +\begin{everbatim*} +{\xintDigits:=48\relax \np{\xintthefloatexpr 1.1547^(2^35)\relax}} +\end{everbatim*} -|\xintiiLt|\n\m\etype{ff} returns 1 if |N|$<$|M|, 0 otherwise. +There is a subtlety here that the |2^35| will be evaluated as a floating point +number but fortunately it only has \dtt{11} digits, hence the final evaluation +is done with a correct exponent. It would have been safer, and also more +efficient to code the above rather as: +\begin{everbatim} +\xintthefloatexpr 1.1547^\xintiiexpr 2^35\relax\relax +\end{everbatim} -\subsection{\csh{xintiiGtorEq}}\label{xintiiGxstorEq} +Here is an example with +|12^16| as exponent, which has $18$ digits (\dtt{={\xintiiPow{12}{16}}}). +\begin{everbatim*} +{\xintDigits:=12\relax \np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}}\newline +\np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}\newline +{\xintDigits:=27\relax \np{\xintthefloatexpr (1+1e-8)^(12^16)\relax}}\newline +{\xintDigits:=48\relax \np{\xintthefloatexpr (1+1e-8)^(12^16)\relax}} +\end{everbatim*} -|\xintiiGtorEq|\n\m\etype{ff} returns 1 if |N|$\geqslant$|M|, 0 otherwise. -Extended by \xintfracname to fractions. +There is an important difference between |\xintFloatPower[Q]{X}{Y}| and +|\xintthefloatexpr[Q] X^Y\relax|: in the former case the computation is done +with |Q| digits or precision,% +% +\footnote{if |X| and |Y| themselves stand for some +floating point macros with arguments, their respective evaluations obey the +precision |\xinttheDigits| or as set optionally in the macro calls +themselves.} +% +whereas with \csbxint{thefloatexpr}|[Q]| the evaluation of the +expression proceeds with |\xinttheDigits| digits of precision, and the final +result is then rounded to |Q| digits: thus this makes real sense only if used +with |Q<\xinttheDigits|. -\subsection{\csh{xintiiLtorEq}}\label{xintiiLtorEq} +\subsection{\csh{xintFloatSqrt}}\label{xintFloatSqrt} -|\xintiiLtorEq|\n\m\etype{ff} returns 1 if |N|$\leqslant$|M|, 0 otherwise. +\csa{xintFloatSqrt}|[P]{f}|\etype{{\upshape[\numx]}\Ff} computes a floating +point approximation of $\sqrt{|f|}$, either using the optional precision |P| or +the value of |\xinttheDigits|. -\subsection{\csh{xintiiIsZero}}\label{xintiiIsZero} +More precisely since |1.2f| the macro achieves so-called \emph{correct + rounding}:\IMPORTANT{} the produced value is the rounding to |P| significant +places of the abstract exact value, \emph{if the input has itself at most |P| + digits} (and an arbitrary exponent). +\begin{everbatim*} +\xintFloatSqrt [89]{10}\newline +\xintFloatSqrt [89]{100}\newline +\xintFloatSqrt [89]{123456789}\par +\end{everbatim*} -|\xintiiIsZero|\n\etype{f} returns 1 if |N=0|, 0 otherwise. +And now some tests to check that correct rounding applies correctly (sic): +\begin{everbatim*} +The argument has 16 digits, hence escapes initial rounding:\newline +\xintFloatSqrt {5625000075000001}\newline +This one gets rounded hence same value is computed:\newline +\xintFloatSqrt {5625000075000001.4}\newline +but actual value is more like:\newline +\xintFloatSqrt [24]{5625000075000001.4}\newline +\xintFloatSqrt [32]{5625000075000001.4}\newline +The argument has 48 digits, hence escapes initial rounding:\newline +\xintFloatSqrt [48]{562500000000000000000000750000000000000000000001}\newline +\xintFloatSqrt [64]{562500000000000000000000750000000000000000000001}\newline +\xintFloatSqrt [80]{562500000000000000000000750000000000000000000001}\newline +\end{everbatim*} +(we observe in passing illustrations that rounding to nearest is not +transitive.)\par -\subsection{\csh{xintiiIsNotZero}}\label{xintiiIsNotZero} -|\xintiiIsNotZero|\n\etype{f} returns 1 if |N!=0|, 0 otherwise. -\subsection{\csh{xintiiIsOne}}\label{xintiiIsOne} -|\xintiiIsOne|\n\etype{f} returns 1 if |N=1|, 0 otherwise. -\subsection{\csh{xintiiOdd}}\label{xintiiOdd} -|\xintiiOdd|\n\etype{f} is 1 if the number is odd and 0 otherwise. +\subsection{\csh{xintFloatFac}}\label{xintFloatFac} -\subsection{\csh{xintiiEven}}\label{xintiiEven} +\csa{xintFloatFac}|[P]{f}|\etype{{\upshape[\numx]}\Numf} returns the +factorial with either \csa{xinttheDigits} or |P| digits of precision. -|\xintiiEven|\n\etype{f} is 1 if the number is even and 0 otherwise. -\subsection{\csh{xintiiMON}}\label{xintiiMON} -|\xintiiMON|\n\etype{f} computes |(-1)^N|. +The exact theoretical value differs from the calculated one |Y| by an absolute +error strictly less than |0.6 ulp(Y)|. + \begin{everbatim*} -\xintiiMON {-280914019374101929} +$1000!\approx{}$\xintFloatFac [30]{1000} \end{everbatim*} +The computation proceeds via doing explicitely the product, as +the Stirling formula cannot be used for lack so far of |exp/log|. -\subsection{\csh{xintiiMMON}}\label{xintiiMMON} +The maximal allowed argument is $99999999$, but already $100000!$ currently +takes, for \dtt{16} digits of precision, a few seconds on my laptop (it +returns \dtt{2.824229407960348e456573}). -|\xintiiMMON|\n\etype{f} computes |(-1)^{N-1}|. +The |factorial| function is available in \csbxint{floatexpr}: \begin{everbatim*} -\xintiiMMON {280914019374101929} +\xintthefloatexpr factorial(1000)\relax % same as 1000! \end{everbatim*} -\subsection{\csh{xintiiifSgn}}\label{xintiiifSgn} +\subsection{\csh{xintFloatBinomial}}\label{xintFloatBinomial} -\csh{xintiiifSgn}\marg{N}\marg{A}\marg{B}\marg{C}\etype{fnnn} executes either -the \meta{A}, \meta{B} or \meta{C} code, depending on its first argument being -respectively negative, zero, or positive. +\csa{xintFloatBinomial}|[P]{x}{y}|\etype{{\upshape[\numx]}\Numf\Numf} computes +binomial coefficients with either \csa{xinttheDigits} or |P| digits of +precision. -\subsection{\csh{xintiiifZero}}\label{xintiiifZero} +When |x<0| an out-of-range error is raised. Else if |y<0| or if |x binomial (9999.,5000.); +% 3008 +% 0.795895131768 10 +% +% > Digits:=32; +% Digits := 32 +% +% > binomial (9999.,5000.); +% 3008 +% 0.795895131768 10 +% apparemment le binomial de Maple ne sait pas calculer avec plus de +% précision! +% et son dernier chiffre est faux! Pourtant GAMMA(9999.) fonctionne. Sauf si +% je n'ai pas compris quelque chose il me semble donc que le binomial de Maple +% est bogué...binomial(100.,50.); marche lui et binomial(4999.,2000.); aussi, +% bon clairement on a un bug de Maple ! oui binomial(8999.,5000.); ainsi que +% binomial(10999.,5000.); fonctionnent avec Digits:=32 mais **pas** +% binomial(9999.,5000.)... binomial(10000.,5000.); et binomial(9998.,5000.); +% sont OK. Est-ce qu'on gagne quelque chose pour un bug report ? +% > binomial(9999.,5000.); +% 3008 +% 0.795895131768 10 +% > binomial(10000.,5000.); +% 3009 +% 0.1591790263532438948337597273641521 10 +% > binomial(9998.,5000.); +% 3008 +% 0.3979077671466477799149739359402922 10 +% en plus je lui demande 32 chiffres et il m'en sort 34. -\csa{xintiiifNotZero}\marg{N}\marg{IsNotZero}\marg{IsZero}\etype{fnn} -expandably checks if the first mandatory argument |N| is not -zero or is zero. It then either executes the first or the second branch. +The associated function in \csbxint{floatexpr} is \func{binomial}: +\begin{everbatim*} +\xintthefloatexpr binomial(3000,1500)\relax +\end{everbatim*} -Beware that both branches must be present. +The computation is based on the formula |(x-y+1)...x/y!| (here one arranges +|y<=x-y| naturally). -\subsection{\csh{xintiiifOne}}\label{xintiiifOne} -\csa{xintiiifOne}\marg{N}\marg{IsOne}\marg{IsNotOne}\etype{fnn} expandably -checks if the first mandatory argument |N| is one or not one. It -then either executes the first or the second branch. Beware that both branches -must be present. +\subsection{\csh{xintFloatPFactorial}}\label{xintFloatPFactorial} -\subsection{\csh{xintiiifCmp}}\label{xintiiifCmp} +\csa{xintFloatPFactorial}|[P]{x}{y}|\etype{{\upshape[\numx]}\Numf\Numf} +computes the product |(x+1)...y|. -\csa{xintiiifCmp}\marg{A}\marg{B}\marg{AB}\etype{ffnnn} -compares its first two arguments and chooses accordingly the correct branch. -\subsection{\csh{xintiiifEq}}\label{xintiiifEq} -\csa{xintiiifEq}\marg{A}\marg{B}\marg{A=B}\marg{not(A=B)}\etype{ffnn} checks -equality of its two first arguments and executes the corresponding branch. -\subsection{\csh{xintiiifGt}}\label{xintiiifGt} +The arguments must be integers (they are expanded inside |\numexpr|) +and the allowed range is $-100000000\leqslant x, y\leqslant99999999$. If +$x\geqslant y$ the product is considered empty hence returns one (as a +floating point value). +See also \csbxint{iiPFactorial}. -\csa{xintiiifGt}\marg{A}\marg{B}\marg{A>B}\marg{not(A>B)}\etype{ffnn} -checks if $A>B$ and executes the corresponding branch. -\subsection{\csh{xintiiifLt}}\label{xintiiifLt} +The exact theoretical value differs from the calculated one |Y| by an absolute +error strictly less than |0.6 ulp(Y)|. -\csa{xintiiifLt}\marg{A}\marg{B}\marg{A0| and |M^2-d=N| with -|M| the smallest (hence if |N=k^2| is a perfect square then |M=k+1|, |d=2k+1|). +\clearpage +\let\xintfracnameUp\undefined +\csname xintbinhexnameUp\endcsname +\def\n{|{N}|} +\def\m{|{M}|} +\def\x{|{x}|} +\section{Macros of the \xintbinhexname package} +\RaisedLabel{sec:binhex} -\begin{everbatim*} -\xintAssign\xintiiSquareRoot {17000000000000000000000000}\to\A\B -\xintiiSub{\xintiiSqr\A}\B=\A\string^2-\B -\end{everbatim*} +This package provides expandable conversions of (big) integers to +and from binary and hexadecimal. -A rational approximation to $\sqrt{|N|}$ is $|M|-\frac{|d|}{|2M|}$ which is a -majorant and the error is at most |1/2M| (if |N| is a perfect square |k^2| -this gives |k+1/(2k+2)|, not |k|.) +First version of this package was in the |1.08| (|2013/06/07|) release of +\xintname. Its routines remained un-modified until their complete rewrite at +release |1.2m| (|2017/07/31|). The new macros are faster, using techniques +from the |1.2| (|2015/10/10|) release of \xintcorename. But the inputs are now +limited to a few thousand digits, whereas the |1.08| could handle (slowly...) +tens of thousands of digits. -Package \xintfracname has \csbxint{FloatSqrt} for square roots of floating -point numbers. +\autoref{tab:binhexsizes} recapitulates the maximal allowed sizes (they got +increased at |1.2n|): +for macro |\xintFooToBar| in the first column, the value in the second column +is the maximal |N| such that |\edef\X{\xintFooToBar{}}| does not +raise an error with standard \TeX\ memory parameters (input stack +size=\dtt{5000}, expansion depth=\dtt{10000}, parameter stack +size=\dtt{10000}). The tests were done with TL2017 and |etex|. Nested calls +will allow slightly lesser values only. The third column gives the +corresponding maximal size of output. The fourth column gives the \TeX\ +parameter cited in the error message when trying with |N+1| digits. -\subsection{\csh{xintiiSqrt}, \csh{xintiiSqrtR}} -\label{xintiiSqrt}\label{xintiiSqrtR} +\begin{table}[htbp] +\capstart + \centering +\def\E#1#2!{\edef\F{\the\numexpr(#1-\xintLength{#2})/2}% + \relax\romannumeral\xintreplicate{\F}{ }#2% + \romannumeral\xintreplicate{#1-\F-\xintLength{#2}}{ }\relax}% +% non satisfactory because depends on #1 oddness, but well. Temporary destined +% to stay... +\begin{tabular}{r>{\E{19}}c<{!}>{\E{19}}c<{!}r} + \hline + &Max\ length\ of\ input&->\ length\ of\ output&Limiting factor\\ + \csbxint{DecToHex}&6014&4995&input stack size=5000\\ + \csbxint{DecToBin}&6014&19979&input stack size=5000\\ + \csbxint{HexToDec}&8298&9992&input stack size=5000\\ + \csbxint{BinToDec}&19988&6017&input stack size=5000\\ + \csbxint{BinToHex}&19988&4997&input stack size=5000\\ + \csbxint{HexToBin}&4996&19984&input stack size=5000\\ + \csbxint{CHexToBin}&4997&19988&input stack size=5000\\ + \hline +\end{tabular} +\caption{Maximal sizes of inputs (at \texttt{1.2n}) for \xintbinhexname macros}\label{tab:binhexsizes} +\end{table} -\noindent|\xintiiSqrt|\n\ computes the largest integer whose square -is at most equal to |N|.\etype{f} |\xintiiSqrtR| -produces the rounded, not truncated, square root.\etype{f} -\begin{everbatim*} -\begin{itemize}[nosep] -\item \xintiiSqrt {3000000000000000000000000000000000000} -\item \xintiiSqrtR {3000000000000000000000000000000000000} -\item \xintiiSqrt {\xintiiE {3}{100}} -\end{itemize} -\end{everbatim*} +Roughly, base |10| numbers are limited to \dtt{6000} digits, hexadecimal +numbers to (almost) \dtt{5000} digits, and binary numbers to (almost) +\dtt{20000} digits. With the surprising exception of \csbxint{HexToDec} which +allows almost \dtt{8300} hexadecimal digits on input. -\subsection{\csh{xintiiBinomial}}\label{xintiiBinomial} +The argument is first \fexpan ded. +It may optionally have a unique leading minus sign (a plus sign is not +allowed), and leading zeroes. -|\xintiiBinomial{x}{y}|\etype{\numx\numx} computes binomial coefficients. +An input (possibly signed) with no leading zeroes is guaranteed to give an +output without leading zero, with the sole, deliberate, exception of +\csbxint{CHexToBin}: from |N| hexadecimal digits it produces |4N| binary +digits, hence possibly with up to three leading zeroes (if the +input had none.) -If |x<0| an out-of-range error is raised. Else, if |y<0| or if |x99999999$, or even -$x\geqslant 2^{31}$, but $y$ is not too large, one may use an ad hoc function -definition such as: -\begin{everbatim*} -\xintdeffunc mybigbinomial(x,y):=`*`(x-y+1..[1]..x)//y!;% -% without [1], x would have been limited to < 2^31 -\printnumber{\xinttheexpr mybigbinomial(98765432109876543210,10)\relax} -\end{everbatim*} +Converts from decimal to hexadecimal.\etype{f} +\texttt{\string\xintDecToHex \string{\printnumber{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}\string}}\endgraf\noindent\dtt{->\printnumber{\xintDecToHex{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}}} -To get this functionality in macro form, one can do: -\begin{everbatim*} -\xintNewIIExpr\MyBigBinomial [2]{`*`(#1-#2+1..[1]..#1)//#2!} -\printnumber{\MyBigBinomial {98765432109876543210}{10}} -\end{everbatim*} +\subsection{\csh{xintDecToBin}}\label{xintDecToBin} -As we used \csa{xintNewIIExpr}, this macro will only accept strict integers. -Had we used \csa{xintNewExpr} the |\MyBigBinomial| would have accepted general -fractions or decimal numbers, and computed the product at the numerator -without truncating them to integers; but the factorial at the denominator -would truncate its argument. +Converts from decimal to binary.\etype{f} -\subsection{\csh{xintiiPFactorial}}\label{xintiiPFactorial} +\texttt{\string\xintDecToBin \string{\printnumber{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}\string}}\endgraf\noindent\dtt{->\printnumber{\xintDecToBin{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}}} -|\xintiiPFactorial{a}{b}|\etype{\numx\numx} computes the partial factorial -|(a+1)(a+2)...b|. For |a=b| the product is considered empty hence returns |1|. +\subsection{\csh{xintHexToDec}}\label{xintHexToDec} + +Converts from hexadecimal to decimal.\etype{f} -%\begin{framed} - The allowed range -% -% -% - is $-100000000\leqslant a, b\leqslant99999999$. - The - rule is to interpret the formula as the product of the - $j$'s such that $a\printnumber{\xintHexToDec{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}} - Only for $0\leqslant a\leqslant b$ is the behaviour to be considered - stable. For $a>b$ or negative arguments, the definitive rules have not yet - been fixed. +\subsection{\csh{xintBinToDec}}\label{xintBinToDec} -\begin{everbatim*} -\xintiiPFactorial {100}{130} -\end{everbatim*} -%\end{framed} +Converts from binary to decimal.\etype{f} -This theoretical range allows computations whose result values would have more -than the roughly 19950 digits that the arithmetics of \xintname can handle. In -such cases, the computation will end up in a low-level \TeX{} error after a -long time. +\texttt{\string\xintBinToDec + \string{\printnumber{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}\string}}\endgraf\noindent +\dtt{->\printnumber{\xintBinToDec{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}}} -The |pfactorial| function is available in the \xintexprname parsers. -\begin{everbatim*} -\xinttheiiexpr pfactorial(100,130)\relax -\end{everbatim*} +\subsection{\csh{xintBinToHex}}\label{xintBinToHex} -See \csbxint{FloatPFactorial} from package \xintfracname for the float -variant, used in \csbxint{floatexpr}. +Converts from binary to hexadecimal.\etype{f} The input is first zero-filled +to |4N| binary digits, hence the output will have |N| hexadecimal digits +(thus, if the input did not have a leading zero, the output will not either). +\texttt{\string\xintBinToHex + \string{\printnumber{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}\string}}\endgraf\noindent +\dtt{->\printnumber{\xintBinToHex{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}}} -In case values are needed with $b>99999999$, or even $b\geqslant 2^{31}$, but -$b-a$ is not too large, one may use an ad hoc function definition such as: -\begin{everbatim*} -\xintdeffunc mybigpfac(a,b):=`*`(a+1..[1]..b);% -% without [1], b would have been limited to < 2^31 -\printnumber{\xinttheexpr mybigpfac(98765432100,98765432120)\relax} -\end{everbatim*} +\subsection{\csh{xintHexToBin}}\label{xintHexToBin} -\subsection{\csh{xintiiMax}}\label{xintiiMax} +Converts from hexadecimal to binary. Up to three leading zeroes of the output +are trimmed.\etype{f} -|\xintiiMax|\n\m\etype{ff} returns the largest of the two in the sense -of the order structure on the relative integers (\emph{i.e.} the right-most -number if they are put on a line with positive numbers on the right): -|\xintiiMax {-5}{-6}|\dtt{=\xintiiMax{-5}{-6}}. +\texttt{\string\xintHexToBin + \string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent +\dtt{->\printnumber{\xintHexToBin{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}} -\subsection{\csh{xintiiMin}}\label{xintiiMin} +\subsection{\csh{xintCHexToBin}}\label{xintCHexToBin} -|\xintiiMin|\n\m\etype{ff} returns the smallest of the two in the sense of the -order structure on the relative integers (\emph{i.e.} the left-most number if -they are put on a line with positive numbers on the right): |\xintiiMin -{-5}{-6}|\dtt{=\xintiiMin{-5}{-6}}. +Converts from hexadecimal to binary.\etype{f} Same as \csbxint{HexToBin}, but +an input with |N| hexadecimal digits will give an output with exactly |4N| +binary digits, leading zeroes are not trimmed. -\subsection{\csh{xintiiMaxof}}\label{xintiiMaxof} +\texttt{\string\xintCHexToBin + \string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent +\dtt{->\printnumber{\xintCHexToBin{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}} -\csa{xintiiMaxof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns the -maximum. The list argument may be a macro, it is \fexpan ded first. +This can be combined with \csbxint{BinToHex} for round-trips preserving +leading zeroes for |4N| binary digits numbers, whereas using +\csbxint{HexToBin} gives reproducing round-trips only for |4N| binary numbers +numbers not starting with |0000|. +\begin{everbatim*} +This zero-fills to 4N digits the input, hence gives here a leading zero in output: +\xintBinToHex{0001111}\newline +Chaining, we end up with 4N-3 digits, as three binary zeroes are trimmed: +\xintHexToBin{\xintBinToHex{0001111}}\newline +But this will always reproduce the initial input zero-filled to length 4N: +\xintCHexToBin{\xintBinToHex{0001111}}\par +Another example (visible space characters manually inserted):\newline +$000000001111101001010001\xrightarrow{\text{\string\xintBinToHex}} +\xintBinToHex{000000001111101001010001}\xrightarrow{\text{\string\xintHexToBin\hphantom{X}}} +\text{\textvisiblespace\textvisiblespace\textvisiblespace} +\xintHexToBin{\xintBinToHex{000000001111101001010001}}$\newline +$000000001111101001010001\xrightarrow{\text{\string\xintBinToHex}} +\xintBinToHex{000000001111101001010001}\xrightarrow{\text{\string\xintCHexToBin}} +\xintCHexToBin{\xintBinToHex{000000001111101001010001}}$ +\par +\end{everbatim*} -\subsection{\csh{xintiiMinof}}\label{xintiiMinof} +\clearpage +\let\xintbinhexnameUp\undefined +\csname xintgcdnameUp\endcsname +\def\n{|{N}|} +\def\m{|{M}|} +\def\x{|{x}|} +\section{Macros of the \xintgcdname package} +\RaisedLabel{sec:gcd} -\csa{xintiiMinof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns the -minimum. The list argument may be a macro, it is \fexpan ded first. +This package was included in the original release |1.0| (|2013/03/28|) of the +\xintname bundle. -\subsection{\csh{xintifTrueAelseB}} -\label{xintifTrueAelseB} -\csa{xintifTrueAelseB}\marg{f}\marg{true branch}\marg{false branch}\etype{fnn} -is a synonym for \csbxint{iiifNotZero}. -{\small - \noindent |\xintiiifnotzero| is lowercase companion macro.\par } +At |1.3d| macros \csbxint{iiGCD} and \csbxint{iiLCM} are copied over to +\xintname, hence \func{gcd} and \func{lcm} functions in \csbxint{iiexpr} were +available simply from loading only \xintexprname, and the \xintgcdname dependency +got removed. -Note 1: as it does only \fexpan sion on its argument it fails with inputs such -as |--0|. But with \xintfracname loaded, it does work fine if nested with -other \xintfracname macros, because the output format of such macros is fine -as input to \csbxint{iiifNotZero}. This remark applies to all other «Boolean -logic» macros next. +\begin{framed} +From |1.1| to |1.3f| the package loaded only \xintcorename, +not \xintname and neither \xinttoolsname. -Note 2: prior to |1.2o| this macro was using \csbxint{ifNotZero} which applies -\csbxint{Num} to its argument (or gets redefined by \xintfracname to handle -general decimal numbers or fractions). Hence it would have -worked with input such as |--0|. But it was decided at |1.2o| that the -overhead was not worth it. The same remark applies to the other «Boolean -logic» type macros next. +But at |1.4| it loads automatically both \xintname and \xinttoolsname (the +latter being a requirement since |1.09h| of the \csbxint{TypesetEuclideAlgorithm} and +\csbxint{TypesetBezoutAlgorithm} macros). -\subsection{\csh{xintifFalseAelseB}} -\label{xintifFalseAelseB} +The macros \csbxint{iiGCD} and \csbxint{iiLCM} got relocated into +\xintname. \IMPORTANTf The macros \csbxint{GCD}, \csbxint{LCM}, +\csbxint{GCDof}, and \csbxint{LCMof} are \emph{removed}: +\xintfracname provides under these names more powerful macros handling +general fractions and not only integers. +\end{framed} -\csa{xintifFalseAelseB}\marg{f}\marg{false branch}\marg{true - branch}\etype{fnn} is a synonym for \csbxint{iiifZero}. +\localtableofcontents -{\small - \noindent |\xintiiifzero| is lowercase companion macro.\par } +\subsection{\csh{xintBezout}}\label{xintBezout} -\subsection{\csh{xintNOT}}\label{xintNOT} +|\xintBezout|\n\m\etype{\Numf\Numf} returns three numbers |U|, |V|, +|D| within braces where |D| is the (non-negative) GCD, and \dtt{UN + VM = D}. +\begin{everbatim*} +\oodef\X{\xintBezout {10000}{1113}}\meaning\X\par +\xintAssign {\xintBezout {10000}{1113}}\to\U\V\D +U: \meaning\U, V: \meaning\V, D: \meaning\D\par +AU+BV: \xinttheiiexpr 10000*\U+1113*\V\relax\par +\noindent\oodef\X{\xintBezout {123456789012345}{9876543210321}}\meaning\X\par +\xintAssign \X\to\U\V\D +U: \meaning\U, V: \meaning\V, D: \meaning\D\par +AU+BV: \xinttheiiexpr 123456789012345*\U+9876543210321*\V\relax +\end{everbatim*} -\csa{xintNOT}\etype{f} is a synonym for \csa{xintiiIsZero}. +\subsection{\csh{xintEuclideAlgorithm}}\label{xintEuclideAlgorithm} -{\small |\xintiiiszero| serves as lowercase companion macro.\par} +|\xintEuclideAlgorithm|\n\m\etype{\Numf\Numf} applies the Euclide algorithm +and keeps a copy of all quotients and remainders. +\begin{everbatim*} +\edef\X{\xintEuclideAlgorithm {10000}{1113}}\meaning\X +\end{everbatim*} +The first item is the number of steps, the second is |N|, the +third is the GCD, the fourth is |M| then the first quotient and +remainder, the second quotient and remainder, \dots until the +final quotient and last (zero) remainder. -\subsection{\csh{xintAND}}\label{xintAND} +\subsection{\csh{xintBezoutAlgorithm}}\label{xintBezoutAlgorithm} -|\xintAND{f}{g}|\etype{ff} returns \dtt{1} if |f!=0| and |g!=0| and \dtt{0} -otherwise. +|\xintBezoutAlgorithm|\n\m\etype{\Numf\Numf} applies the Euclide algorithm +and keeps a copy of all quotients and remainders. Furthermore it computes the +entries of the successive products of the 2 by 2 matrices +$\left(\vcenter{\halign {\,#&\,#\cr q & 1 \cr 1 & 0 \cr}}\right)$ formed from +the quotients arising in the algorithm. +\begin{everbatim*} +\edef\X{\xintBezoutAlgorithm {10000}{1113}}\printnumber{\meaning\X} +\end{everbatim*} -\subsection{\csh{xintOR}}\label{xintOR} +The first item is the number of steps, the second is |N|, then +|0|, |1|, the GCD, |M|, |1|, |0|, the first quotient, the first +remainder, the top left entry of the first matrix, the bottom left +entry, and then these four things at each step until the end. -|\xintOR{f}{g}|\etype{ff} returns \dtt{1} if |f!=0| or |g!=0| and \dtt{0} -otherwise. +\subsection{\csh{xintTypesetEuclideAlgorithm}}\label{xintTypesetEuclideAlgorithm} -\subsection{\csh{xintXOR}}\label{xintXOR} +This macro is just an example of how to organize the data returned by +\csa{xintEuclideAlgorithm}.\ntype{\Numf\Numf} Copy the source code to a new +macro and modify it to what is needed. -|\xintXOR{f}{g}|\etype{ff} returns \dtt{1} if exactly one of |f| or |g| -is true (i.e. non-zero), else \dtt{0}. +\leftedline{|\xintTypesetEuclideAlgorithm {123456789012345}{9876543210321}|} +\xintTypesetEuclideAlgorithm {123456789012345}{9876543210321} -\subsection{\csh{xintANDof}}\label{xintANDof} +\subsection{\csh{xintTypesetBezoutAlgorithm}}% +\label{xintTypesetBezoutAlgorithm} -\csa{xintANDof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns \dtt{1} if -all are true (i.e. non zero) and \dtt{0} otherwise. The list argument may be a -macro, it (or rather its first token) is \fexpan ded first to deliver its -items. +This macro is just an example of how to organize the data returned by +\csa{xintBezoutAlgorithm}.\ntype{\Numf\Numf} Copy the source code to a new +macro and modify it to what is needed. -\subsection{\csh{xintORof}}\label{xintORof} +\leftedline{|\xintTypesetBezoutAlgorithm {10000}{1113}|} +\xintTypesetBezoutAlgorithm {10000}{1113} -\csa{xintORof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns \dtt{1} if at -least one is true (i.e. does not vanish), else it produces \dtt{0}. The list -argument may be a macro, it is \fexpan ded first. +\clearpage +\let\xintgcdnameUp\undefined +\csname xintseriesnameUp\endcsname +\def\n{|{N}|} +\def\m{|{M}|} +\def\x{|{x}|} +\section{Macros of the \xintseriesname package} +\RaisedLabel{sec:series} -\subsection{\csh{xintXORof}}\label{xintXORof} +This package was first released with version |1.03| (|2013/04/14|) of the +\xintname bundle. -\csa{xintXORof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns \dtt{1} if an -odd number of them are true (i.e. do not vanish), else it produces \dtt{0}. -The list argument may be a macro, it is \fexpan ded first. +The \Ff{} expansion type of various macro arguments is only a \Numf{} if only +\xintname but not \xintfracname is loaded. The macro \csbxint{iSeries} is +special and expects summing big integers obeying the strict format, even if +\xintfracname is loaded. -\subsection{\csh{xintiiGCD}} -\label{xintiiGCD} +The arguments serving as indices are of the \numx{} expansion type. -|\xintiiGCD|\n\m\etype{ff} computes the greatest common divisor. It is -positive, except when both |N| and |M| vanish, in which case the macro returns -zero. -% -\leftedline{\csa{xintiiGCD}|{10000}{1113}|\dtt{=\xintiiGCD{10000}{1113}}} -% -\leftedline{|\xintiiGCD{123456789012345}{9876543210321}=|\dtt - {\xintiiGCD{123456789012345}{9876543210321}}} +In some cases one or two of the macro arguments are only expanded at a later +stage not immediately. -At |1.3d|, this macro (which is used by the \func{gcd} function in -\csbxint{iiexpr}) was copied over to \xintname, thus removing a partial -dependency of \xintexprname on \xintgcdname. +\begin{framed} + Since |1.3|, \csbxint{Add} and \csbxint{Sub} use systematically the least + common multiple of the denominators. Some of the comments in this chapter + refer to the earlier situation where often the denominators were simply + multiplied together. \emph{They have yet to be updated to reflect the new + situation brought by the |1.3| release.} Some of these comments may now be + off-synced from the actual computation results and thus may be wrong. +\end{framed} +%% \clearpage -At |1.4| \xintgcdname requires \xintname and the latter is thus the one -providing the macro. +\localtableofcontents -\subsection{\csh{xintiiLCM}} -\label{xintiiLCM} +\subsection{\csh{xintSeries}}\label{xintSeries} -|\xintiiLCM|\n\m\etype{ff} computes the least common multiple. It is positive, -except if one of |N| or |M| vanish, in which case the macro returns zero. -% -\leftedline{\csa{xintiiLCM}|{10000}{1113}|\dtt{=\xintiiLCM{10000}{1113}}} +\csa{xintSeries}|{A}{B}{\coeff}|\etype{\numx\numx\Ff} computes +$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|. The initial and final indices +must obey the |\numexpr| constraint of expanding to numbers at most |2^31-1|. +The |\coeff| macro must be a one-parameter \fexpan dable macro, taking on +input an explicit number |n| and producing some number or fraction |\coeff{n}|; +it is expanded at the time it is +needed.% % -\leftedline{|\xintiiLCM{123456789012345}{9876543210321}=|\dtt - {\xintiiLCM{123456789012345}{9876543210321}}} - -At |1.3d|, this macro (which is used by the \func{lcm} function in -\csbxint{iiexpr}) was copied over to \xintname, thus removing a partial -dependency of \xintexprname on \xintgcdname. -At |1.4| \xintgcdname requires \xintname and the latter is thus the one -providing the macro. +\begin{everbatim*} +\def\coeff #1{\xintiiMON{#1}/#1.5} % (-1)^n/(n+1/2) +\fdef\w {\xintSeries {0}{50}{\coeff}} % we want to re-use it +\fdef\z {\xintJrr {\w}[0]} % the [0] for a microsecond gain. +% \xintJrr preferred to \xintIrr: a big common factor is suspected. +% But numbers much bigger would be needed to show the greater efficiency. +\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} = \xintFrac\z \] +\end{everbatim*} -\subsection{\csh{xintiiGCDof}}\label{xintiiGCDof} +The definition of |\coeff| as |\xintiiMON{#1}/#1.5| is quite suboptimal. It +allows |#1| to be a big integer, but anyhow only small integers are accepted +as initial and final indices (they are of the \numx{} type). Second, when the +\xintfracname parser sees the |#1.5| it will remove the dot hence create a +denominator with one digit more. For example |1/3.5| turns internally into +|10/35| whereas it would be more efficient to have |2/7|. For info here is the +non-reduced |\w|: +\[\xintFrac\w\] +It would have been bigger still in releases earlier than |1.1|: now, the +\xintfracname \csbxint{Add} routine does not multiply blindly denominators +anymore, it checks if one is a multiple of the other. However it does not +practice systematic reduction to lowest terms. -\csa{xintiiGCDof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast f}} computes the -greatest common divisor of the integers |a|, |b|, \dots{}. It is a support -macro for the |gcd()| function of the \csbxint{iiexpr} parser. +A more efficient way to code |\coeff| is illustrated next. +\begin{everbatim*} +\def\coeff #1{\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}% +% The [0] in \coeff is a tiny optimization: in its presence the \xintfracname parser +% sees something which is already in internal format. +\fdef\w {\xintSeries {0}{50}{\coeff}} +\[\sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12}=\xintFrac\w\] +\end{everbatim*} +The reduced form |\z| as displayed above only differs from this one by a +factor of \dtt{\xintNum {\xintDenominator\w/\xintDenominator\z}}. -It replaces the \csbxint{GCDof} which was formerly provided by \xintgcdname -and is now available via \xintfracname in a version handling also -fractions. +\setlength{\columnsep}{0pt} +\everb|@ +\def\coeffleibnitz #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]} +\cnta 1 +\loop +% in this loop we recompute from scratch each partial sum! +% we can afford that, as \xintSeries is fast enough. +\noindent\hbox to 2em{\hfil\texttt{\the\cnta.} }% + \xintTrunc {12}{\xintSeries {1}{\cnta}{\coeffleibnitz}}\dots +\endgraf +\ifnum\cnta < 30 \advance\cnta 1 \repeat +| +\begin{multicols}{3} + \def\coeffleibnitz #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]} \cnta 1 + \loop + \noindent\hbox to 2em{\hfil\dtt{\the\cnta.} }% + \xintTrunc {12}{\xintSeries {1}{\cnta}{\coeffleibnitz}}\dots + \endgraf + \ifnum\cnta < 30 \advance\cnta 1 \repeat +\end{multicols} -\subsection{\csh{xintiiLCMof}}\label{xintiiLCMof} +\subsection{\csh{xintiSeries}}\label{xintiSeries} -\csa{xintiiLCMof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast f}} computes the -least common multiple of the integers |a|, |b|, \dots{}. It is a support -macro for the |lcm()| function of the \csbxint{iiexpr} parser. +\def\coeff #1{\xintiTrunc {40} + {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% -It replaces the \csbxint{LCMof} which was formerly provided by \xintgcdname -and is now available via \xintfracname in a version handling also -fractions. +\csa{xintiSeries}|{A}{B}{\coeff}|\etype{\numx\numx f} computes + $\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}| where |\coeff{n}| + must \fexpan d to a (possibly long) integer in the strict format. +\everb|@ +\def\coeff #1{\xintiTrunc {40}{\xintiiMON{#1}/#1.5}}% +% better: +\def\coeff #1{\xintiTrunc {40} + {\the\numexpr 2*\xintiiMON{#1}\relax/\the\numexpr 2*#1+1\relax [0]}}% +% better still: +\def\coeff #1{\xintiTrunc {40} + {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% +% (-1)^n/(n+1/2) times 10^40, truncated to an integer. +\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx + \xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\dots\] +| -\subsection{\csh{xintLen}}\label{xintLen} +\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx \xintTrunc +{40}{\xintiSeries {0}{50}{\coeff}[-40]}\] -|\xintLen|\etype{\Numf} is originally an alias for \csbxint{iLen}. But with -\xintfracname loaded its meaning is \hyperref[xintLenFrac]{modified} to accept -more general inputs. +We should have cut out at +least the last two digits: truncating errors originating with the first +coefficients of the sum will never go away, and each truncation +introduces an uncertainty in the last digit, so as we have 40 terms, we +should trash the last two digits, or at least round at 38 digits. It is +interesting to compare with the computation where rounding rather than +truncation is used, and with the decimal +expansion of the exactly computed partial sum of the series: +\everb|@ +\def\coeff #1{\xintiRound {40} % rounding at 40 + {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% +% (-1)^n/(n+1/2) times 10^40, rounded to an integer. +\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx + \xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\] +\def\exactcoeff #1% + {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}% +\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} + = \xintTrunc {50}{\xintSeries {0}{50}{\exactcoeff}}\dots\] +| -% \subsection{Removed macros (they require \xintfracname)}\label{ssec:xintdeprecated} +\def\coeff #1{\xintiRound {40} + {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% +% (-1)^n/(n+1/2) times 10^40, rounded to an integer. +\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx + \xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\] +\def\exactcoeff #1% + {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}% +\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} + = \xintTrunc {50}{\xintSeries {0}{50}{\exactcoeff}}\dots\] +This shows indeed that our sum of truncated terms +estimated wrongly the 39th and 40th digits of the exact result% +% +\footnote{as the series is alternating, we can roughly expect an error + of $\sqrt{40}$ and the last two digits are off by 4 units, which is + not contradictory to our expectations.} +% +and that the sum of rounded terms fared a bit better. -% These macros now require \xintfracname. They have been removed from \xintname -% at |1.3|. -% |\xintEq|, -% |\xintNeq|, -% |\xintGeq|, -% |\xintGt|, -% |\xintLt|, -% |\xintGtorEq|, -% |\xintLtorEq|, -% |\xintIsZero|, -% |\xintIsNotZero|, -% |\xintIsOne|, -% |\xintOdd|, -% |\xintEven|, -% |\xintifSgn|, -% |\xintifCmp|, -% |\xintifEq|, -% |\xintifGt|, -% |\xintifLt|, -% |\xintifZero|, -% |\xintifNotZero|, -% |\xintifOne|, -% |\xintifOdd|. +\subsection{\csh{xintRationalSeries}}\label{xintRationalSeries} -% With the exception of |\xintNeq| which was renamed to |\xintNotEq|, the above -% listed macros all belong to \xintfracname. -% At |1.4|, these macros formerly available via \xintgcdname have been moved to -% \xintfracname as well. -% |\xintGCD|, -% |\xintLCM|, -% |\xintGCDof|, -% |\xintLCMof|. +\noindent \csa{xintRationalSeries}|{A}{B}{f}{\ratio}|\etype{\numx\numx\Ff\Ff} +evaluates $\sum_{\text{|n=A|}}^{\text{|n=B|}}$|F(n)|, where |F(n)| is specified +indirectly via the data of |f=F(A)| and the one-parameter macro |\ratio| which +must be such that |\macro{n}| expands to |F(n)/F(n-1)|. The name indicates that +\csa{xintRationalSeries} was designed to be useful in the cases where +|F(n)/F(n-1)| is a rational function of |n| but it may be anything expanding to +a fraction. The macro |\ratio| must be an expandable-only compatible macro and +expand to its value after iterated full expansion of its first item. |A| and +|B| are fed to a |\numexpr| hence may be count registers or arithmetic +expressions built with such; they must obey the \TeX{} bound. The initial term +|f| may be a macro |\f|, it will be expanded to its value representing |F(A)|. -% \subsection{Removed macros (they used \csh{xintNum})}\label{ssec:xintdeprecatedNum} +\begin{everbatim*} +\def\ratio #1{2/#1[0]}% 2/n, to compute exp(2) +\cnta 0 % previously declared count +\begin{quote} +\loop \fdef\z {\xintRationalSeries {0}{\cnta}{1}{\ratio }}% +\noindent$\sum_{n=0}^{\the\cnta} \frac{2^n}{n!}= + \xintTrunc{12}\z\dots= + \xintFrac\z=\xintFrac{\xintIrr\z}$\vtop to 5pt{}\par +\ifnum\cnta<20 \advance\cnta 1 \repeat +\end{quote} +\end{everbatim*} -% These macros filtered their arguments via \csbxint{Num}. They got deprecated -% at |1.2o| and removed at |1.3|: -% |\xintMON|, -% |\xintMMON|, -% |\xintiMax|, -% |\xintiMin|, -% |\xintiMaxof|, -% |\xintiMinof|, -% |\xintiSquareRoot|, -% |\xintiSqrt|, -% |\xintiSqrtR|, -% |\xintiBinomial|, -% |\xintiPFactorial|. +\begin{everbatim*} +\def\ratio #1{-1/#1[0]}% -1/n, comes from the series of exp(-1) +\cnta 0 % previously declared count +\begin{quote} +\loop +\fdef\z {\xintRationalSeries {0}{\cnta}{1}{\ratio }}% +\noindent$\sum_{n=0}^{\the\cnta} \frac{(-1)^n}{n!}= + \xintTrunc{20}\z\dots=\xintFrac{\z}=\xintFrac{\xintIrr\z}$% + \vtop to 5pt{}\par +\ifnum\cnta<20 \advance\cnta 1 \repeat +\end{quote} +\end{everbatim*} -\subsection{(WIP) \csh{xintRandomDigits}}\label{xintRandomDigits} -\begin{framed} - All randomness related macros are Work-In-Progress: implementation and user - interface may change. They work only if the \TeX\ engine provides the - \csa{uniformdeviate} or \csa{pdfuniformdeviate} primitive. See - \csbxint{UniformDeviate} for additional information. -\end{framed} + \def\ratioexp #1#2{\xintDiv{#1}{#2}}% #1/#2 -|\xintRandomDigits{N}|\etype{\numx} expands in two steps to |N| random decimal -digits. The argument must be non-negative and is limited by \TeX\ memory -parameters. -On \TeX Live 2018 with input save stack size at \dtt{5000} the -maximal allowed |N| is at most \dtt{19984} (tested within a |\write| to an -auxiliary file, the macro context may cause a reduced maximum). +\medskip We can incorporate an indeterminate if we define |\ratio| to be +a macro with two parameters: |\def\ratioexp + #1#2{\xintDiv{#1}{#2}}|\texttt{\%}| x/n: x=#1, n=#2|. +Then, if |\x| expands to some fraction |x|, the +macro % +% +\leftedline{|\xintRationalSeries {0}{b}{1}{\ratioexp{\x}}|} +will compute $\sum_{n=0}^{n=b} x^n/n!$:\par \begin{everbatim*} -\pdfsetrandomseed 271828182 -\xintRandomDigits{92} +\cnta 0 +\def\ratioexp #1#2{\xintDiv{#1}{#2}}% #1/#2 +\loop +\noindent +$\sum_{n=0}^{\the\cnta} (.57)^n/n! = \xintTrunc {50} + {\xintRationalSeries {0}{\cnta}{1}{\ratioexp{.57}}}\dots$ + \vtop to 5pt {}\endgraf +\ifnum\cnta<50 \advance\cnta 10 \repeat \end{everbatim*} -\TeXnote the digits are produced eight by eight by the same method which would -result from \csbxint{UniformDeviate}|{100000000}| but with less overhead. - -% \subsection{\csh{\xintOneRandomDigit}}\label{xintOneRandomDigit} +Observe that in this last example the |x| was directly inserted; if it +had been a more complicated explicit fraction it would have been +worthwile to use |\ratioexp\x| with |\x| defined to expand to its value. +In the further situation where this fraction |x| is not explicit but +itself defined via a complicated, and time-costly, formula, it should be +noted that \csa{xintRationalSeries} will do again the evaluation of |\x| +for each term of the partial sum. The easiest is thus when |x| can be +defined as an |\edef|. If however, you are in an expandable-only context +and cannot store in a macro like |\x| the value to be used, a variant of +\csa{xintRationalSeries} is needed which will first evaluate this |\x| and then +use this result without recomputing it. This is \csbxint{RationalSeriesX}, +documented next. -\subsection{(WIP) \csh{xintXRandomDigits}}\label{xintXRandomDigits} +Here is a slightly more complicated evaluation: +\begin{everbatim*} +\cnta 1 +\begin{multicols}{2} +\loop \fdef\z {\xintRationalSeries + {\cnta} + {2*\cnta-1} + {\xintiiPow {\the\cnta}{\cnta}/\xintiiFac{\cnta}} + {\ratioexp{\the\cnta}}}% +\fdef\w {\xintRationalSeries {0}{2*\cnta-1}{1}{\ratioexp{\the\cnta}}}% +\noindent +$\sum_{n=\the\cnta}^{\the\numexpr 2*\cnta-1\relax} \frac{\the\cnta^n}{n!}/% + \sum_{n=0}^{\the\numexpr 2*\cnta-1\relax} \frac{\the\cnta^n}{n!} = + \xintTrunc{8}{\xintDiv\z\w}\dots$ \vtop to 5pt{}\endgraf +\ifnum\cnta<20 \advance\cnta 1 \repeat +\end{multicols} +\end{everbatim*} -|\xintXRandomDigits{N}|\retype{\numx} expands under exhaustive expansion -(|\edef|, |\write|, |\csname| ...) to |N| random decimal -digits. The argument must be non-negative. -For example: -\begin{everbatim} -\newwrite\out -\immediate\openout\out=\jobname-out.txt -\immediate\write\out{\xintXRandomDigits{4500000}} -\immediate\closeout\out -\end{everbatim} -creates a \dtt{4500001} bytes file (it ends with a line feed character). -Trying with \dtt{5000000} raises this error: -\begin{everbatim} -Runaway text? -588875947168511582764514135070217555354479805240439407753451354223283\ETC. -! TeX capacity exceeded, sorry [main memory size=5000000]. - 666515098 - -l.15 ...ate\write\out{\xintXRandomDigits{5000000}} - -No pages of output. -Transcript written on temp.log. -\end{everbatim} -This can be lifted by increasing the \TeX\ memory settings (installation -dependent). -\TeXnote the digits are produced eight by eight by the same method which would -result from \csbxint{UniformDeviate}|{100000000}| but with less overhead. +\subsection{\csh{xintRationalSeriesX}}\label{xintRationalSeriesX} -\subsection{(WIP) \csh{xintiiRandRange}}\label{xintiiRandRange} -|\xintiiRandRange{A}|\etype{f} expands to a random (big) integer |N| -such that |0<=N8|, if we proceed -immediately after having set the seed. If we add some entropy in any way, then -it is slightly more credible; but I think that for each seed the period is -something like |2^{27}(2^{55}-1)55|,% +Let |\ratio| be such a two-parameter macro; note the subtle differences +between% % -\footnote{Compare the result of exercise 3.2.2-30 in TAOCP, vol II.} +\leftedline{|\xintRationalSeries {A}{B}{\first}{\ratio{\g}}|} % -so we expect at most about |2^{110}55| -``points in time'', and this is already small compared to the |10^40| -from example above. Thus already we are very far from being intrinsically -able to generate all numbers with fourty digits as random numbers, and this -makes the previous section about usage of \csbxint{XRandomDigits} to generate -millions of digits a bit comical... - -\TeXnote the digits are produced eight by eight by the same method which would -result from \csbxint{UniformDeviate}|{100000000}| but with less overhead. - -\subsection{(WIP) \csh{xintiiRandRangeAtoB}}\label{xintiiRandRangeAtoB} +\leftedline{and |\xintRationalSeriesX {A}{B}{\first}{\ratio}{\g}|.} First the +location of braces differ... then, in the former case |\first| is a +\emph{no-parameter} macro expanding to a fractional number, and in the latter, +it is a +\emph{one-parameter} macro which will use |\g|. Furthermore the |X| variant +will expand |\g| at the very beginning whereas the former non-|X| former variant +will evaluate it each time it needs it (which is bad if this +evaluation is time-costly, but good if |\g| is a big explicit fraction +encapsulated in a macro). -|\xintiiRandRangeAtoB{A}{B}|\etype{ff} expands to a random (big) integer |N| -such that |A<=N0|. -\begin{everbatim*} -\xintNumerator {178000/25600000[17]}\newline -\xintNumerator {312.289001/20198.27}\newline -\xintNumerator {178000e-3/256e5}\newline -\xintNumerator {178.000/25600000} -\end{everbatim*} +Thus +decimal numbers such as |0.123| (equivalently +|123[-3]|) give less computing intensive tasks than fractions such as |1/712|: +in the case of decimal numbers the (raw) denominators originate in the +coefficients of the series themselves, powers of ten of the input within +brackets being treated separately. And even then the +numerators will grow with the size of the input in a sort of linear way, the +coefficient being given by the order of series: here 10 from the log and 9 from +the exp, so 90. One more digit in the input means 90 more digits in the +numerator of the output: obviously we can not go on composing such partial sums +of series and hope that \xintname will joyfully do all at the speed of light! -\subsection{\csh{xintDenominator}}\label{xintDenominator} +Hence, truncating the output (or better, rounding) is the only way to go if one +needs a general calculus of special functions. This is why the package +\xintseriesname provides, besides \csbxint{Series}, \csbxint{RationalSeries}, or +\csbxint{PowerSeries} which compute \emph{exact} sums, +\csbxint{FxPtPowerSeries} for fixed-point computations and a (tentative naive) +\csbxint{FloatPowerSeries}. -The input data\etype{\Ff} is parsed as if by \csbxint{Raw} into |A/B[N]| -format and -the macro outputs |B| if |N>0|, or |B| extended by \verb+|N|+ zeroes if |N<=0|. -\begin{everbatim*} -\xintDenominator {178000/25600000[17]}\newline -\xintDenominator {312.289001/20198.27}\newline -\xintDenominator {178000e-3/256e5}\newline -\xintDenominator {178.000/25600000} -\end{everbatim*} +\subsection{\csh{xintPowerSeries}}\label{xintPowerSeries} -\subsection{\csh{xintRawWithZeros}}\label{xintRawWithZeros} +\csa{xintPowerSeries}|{A}{B}{\coeff}{f}|\etype{\numx\numx\Ff\Ff} +evaluates the sum +$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot |f|^{\text{|n|}}$. The +initial and final indices are given to a |\numexpr| expression. The |\coeff| +macro (which, as argument to \csa{xintPowerSeries} is expanded only at the time +|\coeff{n}| is needed) should be defined as a one-parameter expandable macro, +its input will be an explicit number. -This macro parses the input\etype{\Ff} and outputs |A/B|, with |A| -as would be returned by \csa{xintNumerator}|{f}| and |B| as would be returned by -\csa{xintDenominator}|{f}|. -\begin{everbatim*} -\xintRawWithZeros{178000/25600000[17]}\newline -\xintRawWithZeros{312.289001/20198.27}\newline -\xintRawWithZeros{178000e-3/256e5}\newline -\xintRawWithZeros{178.000/25600000}\newline -\xintRawWithZeros{\the\numexpr 571*987\relax.123e-10/\the\numexpr-201+59\relax e-7} -\end{everbatim*} +The |f| can be either a fraction directly input or a macro |\f| expanding to +such a fraction. It is actually more efficient to encapsulate an explicit +fraction |f| in such a macro, if it has big numerators and denominators (`big' +means hundreds of digits) as it will then take less space in the processing +until being (repeatedly) used. -\subsection{\csh{xintREZ}}\label{xintREZ} +This macro computes the \emph{exact} result (one can use it also for +polynomial evaluation), using a Horner scheme which helps avoiding a +denominator build-up (this problem however, even if using a naive additive +approach, is much less acute since release |1.1| and its new policy regarding +\csbxint{Add}). -The input\etype{\Ff} is first parsed into |A/B[N]| as by \csbxint{Raw}, then -trailing zeroes of |A| and |B| are suppressed and |N| is accordingly adjusted. \begin{everbatim*} -\xintREZ {178000/25600000[17]} +\def\geom #1{1[0]} % the geometric series +\def\f {5/17[0]} +\[ \sum_{n=0}^{n=20} \Bigl(\frac 5{17}\Bigr)^n + =\xintFrac{\xintIrr{\xintPowerSeries {0}{20}{\geom}{\f}}} + =\xintFrac{\xinttheexpr (17^21-5^21)/12/17^20\relax}\] \end{everbatim*} -This macro is used internally by various other constructs; its implementation -was redone entirely at |1.3a|, and it got faster on long inputs. - -\subsection{\csh{xintIrr}}\label{xintIrr} - -This puts the fraction\etype{\Ff} into its unique irreducible form: \begin{everbatim*} -\xintIrr {178.256/256.1780}, \xintIrr {178000/25600000[17]} +\def\coefflog #1{1/#1[0]}% 1/n +\def\f {1/2[0]}% +\[ \log 2 \approx \sum_{n=1}^{20} \frac1{n\cdot 2^n} + = \xintFrac {\xintIrr {\xintPowerSeries {1}{20}{\coefflog}{\f}}}\] +\[ \log 2 \approx \sum_{n=1}^{50} \frac1{n\cdot 2^n} + = \xintFrac {\xintIrr {\xintPowerSeries {1}{50}{\coefflog}{\f}}}\] \end{everbatim*} -The current implementation does not cleverly first factor powers of -2 and 5, and |\xintIrr {2/3[100]}| will execute the -Euclidean division of |2|\raisebox{.5ex}{|.|}|10^{100}| by |3|, which is a bit -stupid as it could have known that the \dtt{100} trailing zeros can not bring -any divisibility by \dtt{3}. - -Starting with release |1.08|, \csa{xintIrr} does not remove the trailing |/1| -when the output is an integer. This was deemed better for various (questionable?) -reasons, anyway the output format is since \emph{always} |A/B| with |B>0|, even -in cases where it turns out that |B=1|. -Use \csbxint{PRaw} on top of \csa{xintIrr} if it is needed to get rid of such a -trailing |/1|. - -\subsection{\csh{xintPIrr}}\label{xintPIrr} -This puts the fraction\etype{\Ff} into irreducible form, -\emph{keeping as is the - decimal part} |[N]| from raw internal |A/B[N]| format. -(|P| stands here for \emph{Partial}) \begin{everbatim*} -\xintPIrr {178.256/256.1780}, \xintPIrr {178000/25600000[17]} +\setlength{\columnsep}{0pt} +\begin{multicols}{3} +\cnta 1 % previously declared count +\loop % in this loop we recompute from scratch each partial sum! +% we can afford that, as \xintPowerSeries is fast enough. +\noindent\hbox to 2em{\hfil\texttt{\the\cnta.} }% + \xintTrunc {12} + {\xintPowerSeries {1}{\cnta}{\coefflog}{\f}}\dots +\endgraf +\ifnum \cnta < 30 \advance\cnta 1 \repeat +\end{multicols} \end{everbatim*} -Notice that the output always has the ending |[N]|, which is exactly the -opposite of \csbxint{Irr}'s behaviour. The interest of this macro is mainly in -handling fractions which somehow acquired a big |[N]| (perhaps from input in -scientific notation) and for which the reduced fraction would have a very -large number of digits. This large number of digits can considerably slow-down -computations done afterwards. - -For example package \href{http://ctan.org/pkg/polexpr}{polexpr} uses -\csa{xintPIrr} when differentiating a polynomial, or in setting up a Sturm -chain for localization of the real roots of a polynomial. This is relevant to -polynomials whose coefficients were input in decimal notation, as this -automatically creates internally some |[N]|. Keeping and combining those -|[N]|'s during computations significantly increases their speed. - -\subsection{\csh{xintJrr}}\label{xintJrr} -This also puts the fraction\etype{\Ff} into its unique irreducible form: \begin{everbatim*} -\xintJrr {178.256/256.178} +\def\coeffarctg #1{1/\the\numexpr\ifodd #1 -2*#1-1\else2*#1+1\fi\relax }% +% the above gives (-1)^n/(2n+1). The sign being in the denominator, +% **** no [0] should be added ****, +% else nothing is guaranteed to work (even if it could by sheer luck) +% Notice in passing this aspect of \numexpr: +% **** \numexpr -(1)\relax is ilegal !!! **** +\def\f {1/25[0]}% 1/5^2 +\[\mathrm{Arctg}(\frac15)\approx \frac15\sum_{n=0}^{15} \frac{(-1)^n}{(2n+1)25^n} += \xintFrac{\xintIrr {\xintDiv {\xintPowerSeries {0}{15}{\coeffarctg}{\f}}{5}}}\] \end{everbatim*} -This is (supposedly, not tested for ages) faster than \csa{xintIrr} for -fractions having some big common factor in the numerator and the denominator. -\begin{everbatim*} -\xintJrr {\xintiiPow{\xintiiFac {15}}{3}/% - \xintiiPrd{{\xintiiFac{10}}{\xintiiFac{30}}{\xintiiFac{5}}}} -\end{everbatim*} -But to notice the difference one would need computations with much bigger -numbers than in this example. As \csbxint{Irr}, \csa{xintJrr} does not remove -the trailing |/1| from a fraction reduced to an integer. +\subsection{\csh{xintPowerSeriesX}}\label{xintPowerSeriesX} -\subsection{\csh{xintPRaw}}\label{xintPRaw} +%{\small\hspace*{\parindent}New with release |1.04|.\par} -|PRaw|\etype{\Ff} stands for ``pretty raw''. It does like \csbxint{Raw} apart -from removing the |[N]| part if |N=0| and removing the |B| if |B=1|. +\noindent This is the same as \csbxint{PowerSeries}\ntype{\numx\numx\Ff\Ff} +apart +from the fact that the last parameter |f| is expanded once and for all before +being then used repeatedly. If the |f| parameter is to be an explicit big +fraction with many (dozens) digits, rather than using it directly it is slightly +better to have some macro |\g| defined to expand to the explicit fraction and +then use \csbxint{PowerSeries} with |\g|; but if |f| has not yet been evaluated +and will be the output of a complicated expansion of some |\f|, and if, due to +an expanding only context, doing |\edef\g{\f}| is no option, then +\csa{xintPowerSeriesX} should be used with |\f| as last parameter. +% \begin{everbatim*} -\xintPRaw {123e10/321e10}, \xintPRaw {123e9/321e10}, \xintPRaw {\xintIrr{861/123}} +\def\ratioexp #1#2{\xintDiv {#1}{#2}}% x/n +% These are the (-1)^{n-1}/n of the log(1+h) series: +\def\coefflog #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]}% +% Let L(h) be the first 10 terms of the log(1+h) series and +% let E(t) be the first 10 terms of the exp(t) series. +% The following computes L(E(a/10)-1) for a=1,..., 12. +\begin{multicols}{3}\raggedcolumns +\cnta 1 +\loop +\noindent\xintTrunc {18}{% + \xintPowerSeriesX {1}{10}{\coefflog} + {\xintSub + {\xintRationalSeries {0}{9}{1[0]}{\ratioexp{\the\cnta[-1]}}} + {1}}}\dots +\endgraf +\ifnum\cnta < 12 \advance \cnta 1 \repeat +\end{multicols} \end{everbatim*} -\subsection{\csh{xintFracToSci}}\label{xintFracToSci} -\csa{FracToSci}\etype{\Ff} is not really part of public interface. It is a -macro used by \csbxint{expr} for output, on data which is guaranteed to be -in raw \xintfracname format (apart from lacking possibly a denominator and/or the -|[N]| postfix). It is basically like \csbxint{PRaw} but -using scientific notation in the output.\NewWith{1.4} +\subsection{\csh{xintFxPtPowerSeries}}\label{xintFxPtPowerSeries} -Use with care, and always with the argument nested in at least one -\xintfracname macro, such as \csbxint{Raw} or \csbxint{Irr}. +\csa{xintFxPtPowerSeries}|{A}{B}{\coeff}{f}{D}|\etype{\numx\numx} +computes +$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot |f|^{\,\text{|n|}}$ with each + term of the series truncated to |D| digits\etype{\Ff\Ff\numx} + after the decimal point. As + usual, |A| and |B| are completely expanded through their inclusion in a + |\numexpr| expression. Regarding |D| it will be similarly be expanded each + time it is used inside an \csa{xintTrunc}. The one-parameter macro |\coeff| + is similarly expanded at the time it is used inside the + computations. Idem for |f|. If |f| itself is some complicated macro it is + thus better to use the variant \csbxint{FxPtPowerSeriesX} which expands it + first and then uses the result of that expansion. -\begin{everbatim*} -\xintFracToSci {\xintRaw{123e10/321e10}}, -\xintFracToSci {\xintRaw{123e9/321e10}}, -\xintFracToSci {\xintIrr{861/123}} -\end{everbatim*} +The current (|1.04|) implementation is: the first power |f^A| is +computed exactly, then \emph{truncated}. Then each successive power is +obtained from the previous one by multiplication by the exact value of +|f|, and truncated. And |\coeff{n}|\raisebox{.5ex}{|.|}|f^n| is obtained +from that by multiplying by |\coeff{n}| (untruncated) and then +truncating. Finally the sum is computed exactly. Apart from that +\csa{xintFxPtPowerSeries} (where |FxPt| means `fixed-point') is like +\csa{xintPowerSeries}. -\subsection{\csh{xintDecToString}}\label{xintDecToString} +There should be a variant for things of the type $\sum c_n \frac {f^n}{n!}$ to +avoid having to compute the factorial from scratch at each coefficient, the same +way \csa{xintFxPtPowerSeries} does not compute |f^n| from scratch at each |n|. +Perhaps in the next package release. -This is\etype{\Ff} a macro tailored for printing decimal numbers. It does not -trim trailing zeros, use |\xintDecToString{\xintREZ{}}| for that. +\def\coeffexp #1{1/\xintiiFac {#1}[0]}% [0] for faster parsing +\def\f {-1/2[0]}% +\newcount\cnta -\begin{everbatim*} -\xintDecToString {123456789e5}\newline -\xintDecToString {123456789e-5}\newline -\xintDecToString {12345e-10}\newline -\xintDecToString {12345e-10/123}\newline % leaves the denominator as is -\xintDecToString {1234567890000e-6}\newline % does not trim trailing zeros -\xintDecToString {\xintREZ{1234567890000e-6}}\par % does trim trailing zeros -\end{everbatim*} -Consider it an unstable macro, what it does exactly is yet to be decided. It -is a backport from \href{http://ctan.org/pkg/polexpr}{polexpr}'s -|\PolDecToString|, which has now been made an alias to it. +\setlength{\multicolsep}{0pt} -\subsection{\csh{xintTrunc}}\label{xintTrunc} +\begin{multicols}{3}[% +\centeredline{$e^{-\frac12}\approx{}$}]% +\cnta 0 +\noindent\loop +$\xintFxPtPowerSeries {0}{\cnta}{\coeffexp}{\f}{20}$\\ +\ifnum\cnta<19 +\advance\cnta 1 +\repeat\par +\end{multicols} +\everb|@ +\def\coeffexp #1{1/\xintiiFac {#1}[0]}% 1/n! +\def\f {-1/2[0]}% [0] for faster input parsing +\cnta 0 % previously declared \count register +\noindent\loop +$\xintFxPtPowerSeries {0}{\cnta}{\coeffexp}{\f}{20}$\\ +\ifnum\cnta<19 \advance\cnta 1 \repeat\par +| -\csa{xintTrunc}|{x}{f}|\etype{\numx\Ff} returns the integral part, a dot -(standing for the decimal mark), and -then the first |x| digits of the decimal expansion of the fraction |f|, except -when the fraction is (or evaluates to) zero, then it simply prints \dtt{0} -(with no dot). -\begin{framed} - The argument |x| must be non-negative, the behaviour is currently undefined - when |x<0| and will provoke errors. -\end{framed} +% +\leftedline{|\xintFxPtPowerSeries {0}{19}{\coeffexp}{\f}{25}=| +\dtt{\xintFxPtPowerSeries {0}{19}{\coeffexp}{\f}{25}}} +\fdef\z{\xintIrr {\xintPowerSeries {0}{19}{\coeffexp}{\f}}} +% -Except when the input is (or evaluates to) exactly zero, the output contains -exactly |x| digits after the decimal mark, thus the output may be -\dtt{0.00...0} or \dtt{-0.00...0}, indicating that the original fraction was -positive, respectively negative. +\texttt{\hyphenchar\font45 }% +It is no difficulty for \xintfracname to compute exactly, with the help +of \csa{xintPowerSeries}, the nineteenth partial sum, and to then give +(the start of) its exact decimal expansion: +% +\leftedline{|\xintPowerSeries {0}{19}{\coeffexp}{\f}| ${}= + \displaystyle\xintFrac{\z}$% + \vphantom{\vrule height 20pt depth 12pt}}% +% +\leftedline{${}=\xintTrunc {30}{\z}\dots$} Thus, one should always +estimate a priori how many ending digits are not reliable: if there are +|N| terms and |N| has |k| digits, then digits up to but excluding the +last |k| may usually be trusted. If we are optimistic and the series is +alternating we may even replace |N| with $\sqrt{|N|}$ to get the number |k| +of digits possibly of dubious significance. -\begin{framed} - \textbf{Warning:} \emph{it is not yet decided is this behaviour is - definitive.} +\subsection{\csh{xintFxPtPowerSeriesX}}\label{xintFxPtPowerSeriesX} - Currently \xintfracname has no notion of a positive zero or a negative zero. - Hence transitivity of \csbxint{Trunc} is broken for the case where the first - truncation gives on output \dtt{0.00...0} or \dtt{-0.00...0}: a second - truncation to less digits will then output \dtt{0}, whereas if it had been - applied directly to the initial input it would have produced \dtt{0.00...0} - or respectively \dtt{-0.00...0} (with less zeros). - If \xintfracname distinguished zero, positive zero, and - negative zero it would be possible to maintain transitivity. +\noindent\csa{xintFxPtPowerSeriesX}|{A}{B}{\coeff}{\f}{D}|% +\ntype{\numx\numx} +computes, exactly as +\csa{xintFxPtPowerSeries}, the sum of +|\coeff{n}|\raisebox{.5ex}{|.|}|\f^n|\etype{\Ff\Ff\numx} from |n=A| to |n=B| with each term +of the series being \emph{truncated} to |D| digits after the decimal +point. The sole difference is that |\f| is first expanded and it +is the result of this which is used in the computations. - The problem would also be fixed, even without distinguishing a negative zero - on input, if \csbxint{Trunc} always produced \dtt{0.00...0} (with no sign) - when the mathematical result is zero, discarding the information on original - input being positive, zero, or negative. - I have multiple times hesitated about what to do and must postpone again - final decision. -\end{framed} +Let us illustrate this on the numerical exploration of the identity +% +\leftedline{|log(1+x) = -log(1/(1+x))|} +% +Let |L(h)=log(1+h)|, and |D(h)=L(h)+L(-h/(1+h))|. Theoretically thus, +|D(h)=0| but we shall evaluate |L(h)| and |-h/(1+h)| keeping only 10 +terms of their respective series. We will assume $|h|<0.5$. With only +ten terms kept in the power series we do not have quite 3 digits +precision as $2^{10}=1024$. So it wouldn't make sense to evaluate things +more precisely than, say circa 5 digits after the decimal points. \begin{everbatim*} -\xintTrunc {16}{-803.2028/20905.298}\newline -\xintTrunc {20}{-803.2028/20905.298}\newline -\xintTrunc {10}{\xintPow {-11}{-11}}\newline -\xintTrunc {12}{\xintPow {-11}{-11}}\newline -\xintTrunc {50}{\xintPow {-11}{-11}}\newline -\xintTrunc {12}{\xintAdd {-1/3}{3/9}}\par +\cnta 0 +\def\coefflog #1{\the\numexpr\ifodd#1 1\else-1\fi\relax/#1[0]}% (-1)^{n-1}/n +\def\coeffalt #1{\the\numexpr\ifodd#1 -1\else1\fi\relax [0]}% (-1)^n +\begin{multicols}2 +\loop +\noindent \hbox to 2.5cm {\hss\texttt{D(\the\cnta/100): }}% +\xintAdd {\xintFxPtPowerSeriesX {1}{10}{\coefflog}{\the\cnta [-2]}{5}} + {\xintFxPtPowerSeriesX {1}{10}{\coefflog} + {\xintFxPtPowerSeriesX {1}{10}{\coeffalt}{\the\cnta [-2]}{5}} + {5}}\endgraf +\ifnum\cnta < 49 \advance\cnta 7 \repeat +\end{multicols} \end{everbatim*} -The digits printed are exact up to and including the last one. - - -\subsection{\csh{xintXTrunc}}\label{xintXTrunc} -\csa{xintXTrunc}|{x}{f}|\retype{\numx\Ff} is similar to \csbxint{Trunc} with -the following important differences: -\begin{itemize}[nosep] -\item it is completely expandable but not -\fexpan dable, as is indicated by the hollow star in the margin, -\item hence it can not be used as argument to the other package macros, but as - it \fexpan ds its |{f}| argument, it accepts arguments expressed with other - \xintfracname macros, -\item it requires |x>0|, -\item contrarily to \csbxint{Trunc} the number of digits on output is not - limited to about \dtt{19950} and may go well beyond \dtt{100000} (this is - mainly useful for outputting a decimal expansion to a file), -\item when the mathematical result is zero, it always prints it as - \dtt{0.00...0} or \dtt{-0.00...0} with |x| zeros after the decimal mark. -\end{itemize} +Let's say we evaluate functions on |[-1/2,+1/2]| with values more or less also +in |[-1/2,+1/2]| and we want to keep 4 digits of precision. So, roughly we need +at least 14 terms in series like the geometric or log series. Let's make this +15. Then it doesn't make sense to compute intermediate summands with more than 6 +digits precision. So we compute with 6 digits +precision but return only 4 digits (rounded) after the decimal point. +This result with 4 post-decimal points precision is then used as input +to the next evaluation. +\begin{everbatim*} +\begin{multicols}2 +\loop +\noindent \hbox to 2.5cm {\hss\texttt{D(\the\cnta/100): }}% +\dtt{\xintRound{4} + {\xintAdd {\xintFxPtPowerSeriesX {1}{15}{\coefflog}{\the\cnta [-2]}{6}} + {\xintFxPtPowerSeriesX {1}{15}{\coefflog} + {\xintRound {4}{\xintFxPtPowerSeriesX {1}{15}{\coeffalt} + {\the\cnta [-2]}{6}}} + {6}}% + }}\endgraf +\ifnum\cnta < 49 \advance\cnta 7 \repeat +\end{multicols} +\end{everbatim*} -\textbf{Warning:} -transitivity is broken too (see discussion of \csbxint{Trunc}), due to the -sign in the last item. Hence \emph{the definitive policy is yet to be fixed.} +Not bad... I have cheated a bit: the `four-digits precise' numeric +evaluations were left unrounded in the final addition. However the inner +rounding to four digits worked fine and made the next step faster than +it would have been with longer inputs. The morale is that one should not +use the raw results of \csa{xintFxPtPowerSeriesX} with the |D| digits +with which it was computed, as the last are to be considered garbage. +Rather, one should keep from the output only some smaller number of +digits. This will make further computations faster and not less precise. +I guess there should be some macro to do this final truncating, or +better, rounding, at a given number |D'0| one has -|0<= frac(f)<1|. The |T| stands for `Trunc', and there should exist also -similar macros associated respectively with `Round', `Floor', and `Ceil', each -type of rounding to an integer deserving arguably to be associated with a -fractional ``modulo''. By sheer laziness, the package currently implements -only the ``modulo'' associated with `Truncation'. Other types of modulo may be -obtained more cumbersomely via a combination of the rounding with a subsequent -subtraction from |f|. +% This section contains: +% \begin{enumerate} +% \item an \hyperref[ssec:cfracoverview]{overview} of the package functionalities, +% \item a description of each one of the package macros, +% \item further illustration of their use via the study of the +% \hyperref[ssec:e-convergents]{convergents of $e$}. +% \end{enumerate} -Notice that the result is filtered through \csbxint{REZ}, and will thus be of -the form |A/B[N]|, where neither |A| nor |B| has trailing zeros. But the -output fraction is not reduced to smallest terms. +\subsection{Package overview}\label{ssec:cfracoverview} -The function call in expressions (\csbxint{expr}, \csbxint{floatexpr}) is -|frac|. Inside |\xintexpr..\relax|, the function |frac| is mapped to -\csa{xintTFrac}. Inside |\xintfloatexpr..\relax|, |frac| first applies -\csa{xintTFrac} to its argument (which may be an exact fraction with more -digits than the floating point precision) and only in a second stage makes the -conversion to a floating point number with the precision as set by |\xintDigits| -(default is \dtt{16}). -\begin{everbatim*} -\xintTFrac {1235/97}, \xintTFrac {-1235/97}\newline -\xintTFrac {1235.973}, \xintTFrac {-1235.973}\newline -\xintTFrac {1.122435727e5}\par -\end{everbatim*} +The package computes partial quotients and convergents of a fraction, or +conversely start from coefficients and obtain the corresponding fraction; three +macros \csbxint {CFrac}, \csbxint {GCFrac} and \csbxint {GGCFrac} are +for typesetting (the first two assume that the coefficients are numeric +quantities acceptable by the \xintfracname \csbxint{Frac} macro, the +last one will display arbitrary material), the others +can be nested (if applicable) or see their outputs further processed by other +macros from the \xintname bundle, particularly the macros of \xinttoolsname +dealing with sequences of braced items or comma separated lists. -\subsection{\csh{xintRound}}\label{xintRound} +A \emph{simple} continued fraction has coefficients +|[c0,c1,...,cN]| (usually called partial quotients, but I +dislike this entrenched terminology), where |c0| is a positive or +negative integer and the others are positive integers. -\csa{xintRound}|{x}{f}|\etype{\numx\Ff} returns the start of the decimal -expansion of the fraction |f|, rounded to |x| digits precision after the decimal -point. The argument |x| should be non-negative. Only when |f| evaluates exactly -to zero does \csa{xintRound} return |0| without decimal point. When |f| is not -zero, its sign is given in the output, also when the digits printed are all -zero. +Typesetting is usually done via the |amsmath| macro |\cfrac|: \begin{everbatim*} -\xintRound {16}{-803.2028/20905.298}\newline -\xintRound {20}{-803.2028/20905.298}\newline -\xintRound {10}{\xintPow {-11}{-11}}\newline -\xintRound {12}{\xintPow {-11}{-11}}\newline -\xintRound {12}{\xintAdd {-1/3}{3/9}}\par +\[ c_0 + \cfrac{1}{c_1+\cfrac1{c_2+\cfrac1{c_3+\cfrac1{\ddots}}}}\] \end{everbatim*} -\subsection{\csh{xintFloor}}\label{xintFloor} - -|\xintFloor {f}|\etype{\Ff} returns the largest relative integer |N| with -|N|${}\leqslant{}$|f|. +Here is a concrete example: \begin{everbatim*} -\xintFloor {-2.13}, \xintFloor {-2}, \xintFloor {2.13} +\[ \xintFrac {208341/66317}=\xintCFrac {208341/66317}\]% \end{everbatim*} -Note the trailing |[0]|, see \csbxint{iFloor} if it is not desired. - -\subsection{\csh{xintCeil}}\label{xintCeil} +But it is the macro \csbxint{CFrac} which did all the work of \emph{computing} +the continued fraction \emph{and} using |\cfrac| from |amsmath| to typeset +it. -|\xintCeil {f}|\etype{\Ff} returns the smallest relative integer |N| with -|N|${}>{}$|f|. +A \emph{generalized} continued fraction has the same structure but the +numerators are not restricted to be $1$, and numbers used in the continued +fraction may be arbitrary, also fractions, irrationals, complex, +indeterminates.% +% +\footnote{\xintcfracname may be used with indeterminates, + for basic conversions from one inline format to another, but not for + actual computations. See \csbxint{GGCFrac}.} +% +The \emph{centered} continued fraction is an +example: \begin{everbatim*} -\xintCeil {-2.13}, \xintCeil {-2}, \xintCeil {2.13} +\[ \xintFrac {915286/188421}=\xintGCFrac {5+-1/7+1/39+-1/53+-1/13} + =\xintCFrac {915286/188421}\] \end{everbatim*} -\subsection{\csh{xintiTrunc}}\label{xintiTrunc} +The macro \csbxint{GCFrac}, contrarily to +\csbxint{CFrac}, does not compute anything, it just typesets starting from a +generalized continued fraction in inline format, which in this example +was input literally. We also used \csa{xintCFrac} +for comparison of the two types of continued fractions. -\csa{xintiTrunc}|{x}{f}|\etype{\numx\Ff} returns the integer equal to |10^x| -times what \csa{xintTrunc}|{x}{f}| would produce. +To let \TeX{} compute the centered continued fraction of |f| there is +\csbxint{FtoCC}: \begin{everbatim*} -\xintiTrunc {16}{-803.2028/20905.298}\newline -\xintiTrunc {10}{\xintPow {-11}{-11}}\newline -\xintiTrunc {12}{\xintPow {-11}{-11}}\par +\[\xintFrac {915286/188421}\to\xintFtoCC {915286/188421}\] \end{everbatim*} - -In particular \csa{xintiTrunc}|{0}{f}|'s output is in strict integer format -contrarily to \csa{xintTrunc}|{0}{f}| which produces an output with a decimal -mark, except if |f| turns out to be zero. - -\subsection{\csh{xintTTrunc}}\label{xintTTrunc} - -\csa{xintTTrunc}|{f}|\etype{\Ff} truncates to an integer (truncation towards -zero). This is the same as |\xintiTrunc {0}{f}| and also the same as -\csbxint{Num}. - -\subsection{\csh{xintiRound}}\label{xintiRound} - -\csa{xintiRound}|{x}{f}|\etype{\numx\Ff} returns the integer equal to |10^x| -times what \csa{xintRound}|{x}{f}| would return. +The package macros are expandable and may be nested (naturally \csa{xintCFrac} +and \csa{xintGCFrac} must be at the top level, as they deal with typesetting). \begin{everbatim*} -\xintiRound {16}{-803.2028/20905.298}\newline -\xintiRound {10}{\xintPow {-11}{-11}}\par +\[\xintGCFrac {\xintFtoCC{915286/188421}}\] \end{everbatim*} -In particular \csa{xintiRound}|{0}{f}|'s output is in strict integer format -contrarily to \csa{xintRound}|{0}{f}| which produces an output with a decimal -mark, except if |f| turns out to be zero. - -\subsection{\csh{xintiFloor}}\label{xintiFloor} - -|\xintiFloor {f}|\etype{\Ff} does the same as \csbxint{Floor} but without the -trailing |/1[0]|. +The `inline' format expected on input by \csbxint{GCFrac} is +% +\leftedline{$a_0+b_0/a_1+b_1/a_2+b_2/a_3+\cdots+b_{n-2}/a_{n-1}+b_{n-1}/a_n$} +% +Fractions among the coefficients are allowed but they must be enclosed +within braces. Signed integers may be left without braces (but the |+| +signs are mandatory). No spaces are allowed around the plus and fraction +symbols. The coefficients may themselves be macros, as long as these +macros are \fexpan dable. \begin{everbatim*} -\xintiFloor {-2.13}, \xintiFloor {-2}, \xintiFloor {2.13} +\[ \xintFrac{\xintGCtoF {1+-1/57+\xintPow {-3}{7}/\xintiiQuo {132}{25}}} + = \xintGCFrac {1+-1/57+\xintPow {-3}{7}/\xintiiQuo {132}{25}}\] \end{everbatim*} - -\subsection{\csh{xintiCeil}}\label{xintiCeil} - -|\xintiCeil {f}|\etype{\Ff} does the same as \csbxint{Ceil} but its output is -without the |/1[0]|. +To compute the actual fraction one has \csbxint{GCtoF}: \begin{everbatim*} -\xintiCeil {-2.13}, \xintiCeil {-2}, \xintiCeil {2.13} +\[\xintFrac{\xintGCtoF {1+-1/57+\xintPow {-3}{7}/\xintiiQuo {132}{25}}}\] \end{everbatim*} - -\subsection{\csh{xintE}}\label{xintE} - -|\xintE {f}{x}|\etype{\Ff\numx} multiplies the fraction |f| by $10^x$. The -\emph{second} argument |x| must obey the \TeX{} bounds. Example: +For non-numeric input there is \csbxint{GGCFrac}. \begin{everbatim*} -\count 255 123456789 \xintE {10}{\count 255} +\[\xintGGCFrac {a_0+b_0/a_1+b_1/a_2+b_2/\ddots+\ddots/a_{n-1}+b_{n-1}/a_n}\] \end{everbatim*} -Don't feed this example to \csbxint{Num}! - -\subsection{\csh{xintCmp}}\label{xintCmp} - -This\etype{\Ff\Ff} compares two fractions |F| and |G| and produces -|-1|, |0|, or |1| according to |FG|. - -For choosing branches according to the result of comparing |f| and |g|, see -\csbxint{ifCmp}. - -\subsection{\csh{xintEq}}\label{xintEq} - -|\xintEq{f}{g}|\etype{\Ff\Ff} returns 1 if |f=g|, 0 otherwise. - -\subsection{\csh{xintNotEq}}\label{xintNotEq} - -|\xintNotEq{f}{g}|\etype{\Ff\Ff} returns 0 if |f=g|, 1 otherwise. - - -\subsection{\csh{xintGeq}}\label{xintGeq} - -This\etype{\Ff\Ff} compares the \emph{absolute values} of two -fractions. -|\xintGeq{f}{g}| outputs |1| if {\catcode`| 12 $|f|\geqslant|g|$} and |0| -if not. - -Important: the macro compares \emph{absolute values}. - -\subsection{\csh{xintGt}}\label{xintGt} - -|\xintGt{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$>$|g|, \dtt{0} otherwise. - -\subsection{\csh{xintLt}}\label{xintLt} - -|\xintLt{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$<$|g|, \dtt{0} otherwise. - -\subsection{\csh{xintGtorEq}}\label{xintGxstorEq} - -|\xintGtorEq{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$\geqslant$|g|, \dtt{0} otherwise. -Extended by \xintfracname to fractions. - -\subsection{\csh{xintLtorEq}}\label{xintLtorEq} - -|\xintLtorEq{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$\leqslant$|g|, \dtt{0} otherwise. - -\subsection{\csh{xintIsZero}}\label{xintIsZero} - -|\xintIsZero{f}|\etype{f} returns \dtt{1} if |f=0|, \dtt{0} otherwise. - -\subsection{\csh{xintIsNotZero}}\label{xintIsNotZero} - -|\xintIsNotZero{f}|\etype{f} returns \dtt{1} if |f!=0|, \dtt{0} otherwise. - -\subsection{\csh{xintIsOne}}\label{xintIsOne} - -|\xintIsOne{f}|\etype{f} returns \dtt{1} if |f=1|, \dtt{0} otherwise. - -\subsection{\csh{xintOdd}}\label{xintOdd} - -|\xintOdd{f}|\etype{f} returns \dtt{1} if the integer obtained by truncation is -odd, and \dtt{0} otherwise. - -\subsection{\csh{xintEven}}\label{xintEven} - -|\xintEven{f}|\etype{f} returns \dtt{1} if the integer obtained by truncation is -even, and \dtt{0} otherwise. - -\subsection{\csh{xintifSgn}}\label{xintifSgn} - -\csh{xintifSgn}\marg{f}\marg{A}\marg{B}\marg{C}\etype{\Ff nnn} executes either the -\meta{A}, \meta{B} or \meta{C} code, depending on its first argument being -respectively negative, zero, or positive. - -\subsection{\csh{xintifZero}}\label{xintifZero} - -\csa{xintifZero}\marg{f}\marg{IsZero}\marg{IsNotZero}\etype{\Ff nn} expandably -checks if the first mandatory argument |N| (a number, possibly a fraction if -\xintfracname is loaded, or a macro expanding to one such) is zero or not. It -then either executes the first or the second branch. - -Beware that both branches must be present. - -\subsection{\csh{xintifNotZero}}\label{xintifNotZero} - -\csa{xintifNotZero}\marg{N}\marg{IsNotZero}\marg{IsZero}\etype{\Ff nn} -expandably checks if the first mandatory argument |f| is not -zero or is zero. It then either executes the first or the second branch. - -Beware that both branches must be present. - -\subsection{\csh{xintifOne}}\label{xintifOne} - -\csa{xintifOne}\marg{N}\marg{IsOne}\marg{IsNotOne}\etype{\Ff nn} expandably -checks if the first mandatory argument |f| is one or not one. It -then either executes the first or the second branch. Beware that both branches -must be present. - -\subsection{\csh{xintifOdd}}\label{xintifOdd} - -\csa{xintifOdd}\marg{N}\marg{odd}\marg{not odd}\etype{\Ff nn} expandably -checks if the first mandatory argument |f|, after truncation to an integer, is -odd or even. It then executes accordingly the first or the second branch. -Beware that both branches must be present. - -\subsection{\csh{xintifCmp}}\label{xintifCmp} - -\csa{xintifCmp}\marg{f}\marg{g}\marg{if fg}\etype{\Ff\Ff nnn} compares its first two arguments and chooses accordingly -the correct branch. - -\subsection{\csh{xintifEq}}\label{xintifEq} - -\csa{xintifEq}\marg{f}\marg{g}\marg{YES}\marg{NO}\etype{\Ff\Ff nn} checks -equality of its two first arguments and executes accordingly the |YES| or the -|NO| branch. - -\subsection{\csh{xintifGt}}\label{xintifGt} - -\csa{xintifGt}\marg{f}\marg{g}\marg{YES}\marg{NO}\etype{\Ff\Ff nn} -checks if $f>g$ and in that case executes the |YES| branch. - -\subsection{\csh{xintifLt}}\label{xintifLt} - -\csa{xintifLt}\marg{f}\marg{g}\marg{YES}\marg{NO}\etype{\Ff\Ff nn} -checks if $f200 \textcolor{red}{#1}\else #1\fi} + $$\xintFtoCx {+\cfrac1\\ \highlight}{104348/33215}\endcfrac$$ +| -To be used as |\xintSetDigits|\marg{expression}\ntype{\numx} where the -expression will be fed to |\numexpr|. It is a shortcut for doing -|\xintDigits := \numexpr|\meta{expression}|\relax \relax|. +Due to the different and extremely cumbersome syntax of |\cfrac| under +\LaTeX{} it proves a bit tortuous to obtain there the same effect. +Actually, it is partly for this purpose that |1.09m| added \csbxint +{GGCFrac}. We thus use \csa{xintFtoCx} with a suitable separator, and\; +then the whole thing as argument to \csbxint{GGCFrac}: \begin{everbatim*} -\xintSetDigits{1+2+3+4+5}The value is now \xinttheDigits. -\xintSetDigits{2*8}The value is now \xinttheDigits.\par +\def\highlight #1{\ifnum #1>200 \fcolorbox{blue}{white}{\boldmath\color{red}$#1$}% + \else #1\fi} +\[\xintGGCFrac {\xintFtoCx {+1/\highlight}{208341/66317}}\] \end{everbatim*} -\begin{framed} - See also the \xintexprname-added variant \csbxint{SetDigits*}. -\end{framed} - -\subsection{\csh{xintFloat}}\label{xintFloat} +\subsection{\csh{xintFtoGC}}\label{xintFtoGC} -The macro |\xintFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} has an optional -argument |P| which replaces the current value of |\xinttheDigits|. The -fraction |f| is then printed in scientific notation with a rounding to |P| digits. - -That is, on output: the first digit is from |1| to |9|, it is possibly -prefixed by a minus sign and is followed by a dot and |P-1| digits, then a -lower case |e| and an exponent |N|. The trailing zeroes are not trimmed. +\csa{xintFtoGC}|{f}|\etype{\Ff} does the same as \csa{xintFtoCx}|{+1/}{f}|. Its +output may thus be used in the package macros expecting such an `inline +format'. +% This continued fraction is a \emph{simple} one, not a +% \emph{generalized} one, but as it is produced in the format used for +% user input of generalized continued fractions, the macro was called +% \csa{xintFtoGC} rather than \csa{xintFtoC} for example. +% +\begin{everbatim*} +566827/208524=\xintFtoGC {566827/208524} +\end{everbatim*} -\begin{framed} - There is currently one exceptional case: the zero value, which gets output - as \dtt{\xintFloat{0}}. It is yet to be decided what the final policy will be. -\end{framed} +\subsection{\csh{xintFGtoC}}\label{xintFGtoC} -Starting with |1.2k|, when the input is a fraction |AeN/BeM| -the output always is the \emph{correct rounding} to |P| digits. Formerly, this -was guaranteed only when |A| and |B| had at most |P+2| digits, or when |B| was -|1| and |A| was arbitrary, but in other cases it was only guaranteed that the -difference between the original fraction and the rounding was at most -\dtt{0.6} unit in the last place (of the output), hence the output could -differ in the last digit (and earlier ones in case of chains of zeros or -nines) from the correct rounding. +\csa{xintFGtoC}|{f}{g}|\etype{\Ff\Ff} computes the common initial coefficients +to +two given fractions |f| and |g|. Notice that any real number |fx>g| +will then necessarily share with |f| and |g| these common initial coefficients +for its regular continued fraction. The coefficients are output as a sequence of +braced numbers. This list can then be manipulated via macros from +\xinttoolsname, or other macros of \xintcfracname. -Also: for releases |1.2j| and earlier, in the special case when -|A/B| ended up being rounded up to the next power of ten, the output was with -a mantissa of the shape |10.0...0eN|. However, this worked only for |B=1| or -when both |A| and |B| had at most |P+2| digits, because the detection of the -rounding-up to next power of ten was done not on original |A/B| but on an -approximation |A'/B'|, and it could happen that |A'/B'| was itself being -rounded \emph{down} to a power of ten which however was a rounding \emph{up} -of original |A/B|. With the |1.2j| refactoring which achieves correct rounding -in all cases, it was decided not to add to the code the extra overhead of -detecting with 100\% fiability the rounding up to next power of ten (such -overhead would necessitate alterations of the algorithm and as a result we -would end up with a slightly less efficient one; it would make sense in a -model where inputs have their intrinsic precisions which is obeyed by the -implementation of the basic operations, but currently the design decision for -the floating point macros is that when the target precision is |P| the inputs -are rounded first to |P| digits before further processing.) \begin{everbatim*} -{\def\x{99999999999999994999999999999999/99999999999999999999999999999999}% -\xintFor #1 in {13, 14, 15, 16, 17, 18, 19, 47, 48, 49, 50, 79, 80, 81} -\do{#1: \xintFloat[#1]{\x}\xintifForLast{\par}{\newline}}}% +\fdef\test{\xintFGtoC{-5262046/89233}{-5314647/90125}}\texttt{\meaning\test} \end{everbatim*} -As an aside, which is illustrated by the above, rounding is not -transitive in the number of kept digits. \begin{everbatim*} -{\def\x{137893789173289739179317/13890138013801398}% -\xintFor* #1 in {\xintSeq{4}{20}} -\do{#1: \xintFloat[#1]{\x}\newline}}% -\xintFloat{5/9999999999999999}\newline -\xintFloat[32]{5/9999999999999999}\newline -\xintFloat[48]{5/9999999999999999}\par +\fdef\test{\xintFGtoC{3.141592653}{3.141592654}}\texttt{\meaning\test} \end{everbatim*} - - - -\subsection{\csh{xintPFloat}}\label{xintPFloat} - -The macro |\xintPFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} is like -\csbxint{Float} but ``pretty-prints'' the output. Its behaviour has changed -with release |1.2f|\IMPORTANT{}: there is only one simplification rule now -which is that decimal notation (with possibly needed extra zeros) is used in -place of scientific notation when the exponent would end up being between -\dtt{-5} and \dtt{5} inclusive. - -If the input vanishes the output will be \dtt{\xintPFloat{0}} with a a decimal -mark.% -% -\footnote{Currently there are no subnormal numbers, and no underflow - because the exponent is only limited by the maximal \TeX\ number; thus - underflow situations would manifest themselves via low-level arithmetic - overflow errors.} - -\csbxint{thefloatexpr} applies this macro to its output (or each of -its outputs, if comma separated). - -Currently trailing zeros are not trimmed. - \begin{everbatim*} -\begingroup\def\test #1{#1${}\to{}$\xintPFloat{#1}}% -\string\xintDigits\ at \xinttheDigits -\begin{itemize}[nosep] -\item \test {0} -\item \test {1.23456789e-7} -\item \test {1.23456789e-6} -\item \test {1.23456789e-5} -\item \test {1.23456789e-4} -\item \test {1.23456789e-3} -\item \test {1.23456789e-2} -\item \test {1.23456789e-1} -\item \test {1.23456789e0} -\item \test {1.23456789e1} -\item \test {1.23456789e2} -\item \test {1.23456789e3} -\item \test {1.23456789e4} -\item \test {1.23456789e5} -\item \test {1.23456789e6} -\item \test {1.23456789e7} -\end{itemize} -\endgroup +\fdef\test{\xintFGtoC{3.1415926535897932384}{3.1415926535897932385}}\meaning\test \end{everbatim*} - - -\subsection{\csh{xintFloatE}}\label{xintFloatE} - -|\xintFloatE [P]{f}{x}|\etype{{\upshape[\numx]}\Ff\numx} multiplies the input -|f| by $10^x$, and -converts it to float format according to the optional first argument or current -value of |\xinttheDigits|. \begin{everbatim*} -\xintFloatE {1.23e37}{53} +\xintRound {30}{\xintCstoF{\xintListWithSep{,}{\test}}} \end{everbatim*} - -\subsection{\csh{xintFloatAdd}}\label{xintFloatAdd} - - -|\xintFloatAdd [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| -and |g| with their float approximations |f'| and |g'| to |P| significant -places or to the precision from |\xintDigits|. It then produces -the sum |f'+g'|, correctly rounded to nearest with the same number of -significant places. - - -\subsection{\csh{xintFloatSub}}\label{xintFloatSub} - - -|\xintFloatSub [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| -and |g| with their float approximations |f'| and |g'| to |P| significant -places or to the precision from |\xintDigits|. It then produces -the difference |f'-g'| correctly rounded to nearest |P|-float. - - -\subsection{\csh{xintFloatMul}}\label{xintFloatMul} - - -|\xintFloatMul [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| -and |g| with their float approximations |f'| and |g'| to |P| (or -|\xinttheDigits|) significant places. It then correctly rounds -the product |f'*g'| to nearest |P|-float. - -See \autoref{ssec:floatingpoint} for more. - -\begin{framed} - It is obviously much needed that the author improves its algorithms to avoid - going through the exact |2P| or |2P-1| digits before - throwing to the waste-bin half of those digits ! - - % \xintname initially was purely an \emph{exact} arbitrary precision - % arithmetic machine, and the introduction of floating point numbers was an - % after-thought. I got it working in release |1.07 (2013/05/25)| and never had - % time to come back to it. -\end{framed} - -\subsection{\csh{xintFloatDiv}}\label{xintFloatDiv} - - -|\xintFloatDiv [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| -and |g| with their float approximations |f'| and |g'| to |P| (or -|\xinttheDigits|) significant places. It then correctly rounds -the fraction |f'/g'| to nearest |P|-float. - -See \autoref{ssec:floatingpoint} for more. - -Notice in the special situation with |f| and |g| integers that |\xintFloatDiv -[P]{f}{g}| will \emph{not necessarily} give the correct rounding of the -exact fraction |f/g|. Indeed the macro arguments are each first individually -rounded to |P| digits of precision. The correct syntax to get the correctly -rounded integer fraction |f/g| is \csbxint{Float}|[P]{f/g}|. - -\subsection{\csh{xintFloatPow}}\label{xintFloatPow} - -|\xintFloatPow [P]{f}{x}|\etype{{\upshape[\numx]}\Ff\numx} uses either the -optional argument |P| or in its absence the value of |\xinttheDigits|. It -computes a floating approximation to |f^x|. - -The exponent |x| will be handed over to a |\numexpr|, hence count registers are -accepted on input for this |x|. And the absolute value \verb+|x|+ must obey the -\TeX{} bound. - -The argument |f| is first rounded to |P| significant places to give -|f'|. The output |Z| is such that the exact |f'^x| differs from -|Z| by an absolute error less than |0.52 ulp(Z)|. \begin{everbatim*} -\xintFloatPow [8]{3.1415}{1234567890} +\xintRound {30}{\xintCtoF{\test}} +\end{everbatim*} +\begin{everbatim*} +\fdef\test{\xintFGtoC{1.41421356237309}{1.4142135623731}}\meaning\test \end{everbatim*} -\subsection{\csh{xintFloatPower}}\label{xintFloatPower} - -\csa{xintFloatPower}|[P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Numf} computes a -floating point value |f^g| where the exponent |g| is not constrained to be at -most the \TeX{} bound \dtt{\number "7FFFFFFF}. It may even be a fraction -|A/B| but must simplify to a (possibly big) integer. The exponent of the -\emph{output} however \emph{must} at any rate obey the \TeX{} bound. +\subsection{\csh{xintFtoCC}}\label{xintFtoCC} -The argument |f| is first rounded to |P| significant places to give -|f'|. The output |Z| is then such that the exact |f'^g| differs from -|Z| by an absolute error less than |0.52 ulp(Z)|. +\csa{xintFtoCC}|{f}|\etype{\Ff} returns the `centered' continued fraction of +|f|, in `inline format'. % +\begin{everbatim*} +566827/208524=\xintFtoCC {566827/208524} +\end{everbatim*} +\begin{everbatim*} +\[\xintFrac{566827/208524} = \xintGCFrac{\xintFtoCC{566827/208524}}\] +\end{everbatim*} -This is the macro which is used for the |^| (or |**|) infix operators in -|\xintthefloatexpr...\relax|. In this context (but not directly with the -macro,) half-integer exponents are allowed. This is handled via an integer power -followed by a square-root extraction. The exponent is first rounded to nearest -integer or half-integer so that the computation never raises errors (except -naturally for negative exponent and zero |f|.) The |0.52 ulp(Z)| bound applies -with half-integer exponents too. +\subsection{\csh{xintCstoF}}\label{xintCstoF} +\csa{xintCstoF}|{a,b,c,d,...,z}|\etype{f} computes the fraction corresponding to +the coefficients, which may be fractions or even macros expanding to such +fractions. The final fraction may then be highly reducible. -Notice that this is a bound on the distance from |f'^g| to |Z|, as |f| always -gets rounded to |P| or \csbxint{theDigits} digits. The distance from |f^g| to -|Z| can be much worse if |g| is very large. Roughly, when |g| is negligible -compared to |10^P|, we get an extra difference of up to about |50g ulp(Z)| -which completely dwarfs the |0.52 ulp(Z)|. Thus, if |f| has strictly more than -|P| digits, then the computation must be done with an elevated working -precision |P'|. For example with |g=1000| we should use |P'=P+6| to achieve a -total error at worst slightly bigger than |0.55 ulp(Z)| after the final -rounding from |P'| to |P| digits to get |Z|. +\emph{Usage of this macro requires the user to load} \xinttoolsname.\IMPORTANT -Examples:% -% -\footnote{|\np| is formatting macro from the \url{http://ctan.org/pkg/numprint} - package.} -% +Starting with +release |1.09m| spaces before commas are allowed and trimmed automatically +(spaces after commas were already silently handled in earlier releases). \begin{everbatim*} -\np{\xintFloatPower [8]{3.1415}{3e9}}\newline% Notice that 3e9>2^31 -\np{\xintFloatPower [48]{1.1547}{\xintiiPow {2}{35}}}\newline -\end{everbatim*}% -$2^{35}=\xintiiPow {2}{35}$ exceeds \TeX's bound, but what -counts is the exponent of the result which, while dangerously close to -$2^{31}$ is not quite there yet. +\[\xintGCFrac {-1+1/3+1/-5+1/7+1/-9+1/11+1/-13}= + \xintSignedFrac{\xintCstoF {-1,3,-5,7,-9,11,-13}}=\xintSignedFrac{\xintGCtoF + {-1+1/3+1/-5+1/7+1/-9+1/11+1/-13}}\] +\end{everbatim*} +\begin{everbatim*} +\[\xintGCFrac{{1/2}+1/{1/3}+1/{1/4}+1/{1/5}}=\xintFrac{\xintCstoF {1/2,1/3,1/4,1/5}}\] +\end{everbatim*} +% +A generalized continued fraction may produce a reducible fraction +(\csa{xintCstoF} tries its best not to accumulate in a silly way superfluous +factors but will not do simplifications which would be obvious to a human, like +simplification by 3 in the result above). + +\subsection{\csh{xintCtoF}}\label{xintCtoF} -With expressions: +\csa{xintCtoF}|{{a}{b}{c}...{z}}|\etype{f} computes the fraction corresponding +to the coefficients, which may be fractions or even macros. \begin{everbatim*} -{\xintDigits:=48\relax \np{\xintthefloatexpr 1.1547^(2^35)\relax}} +\xintCtoF {\xintApply {\xintiiPow 3}{\xintSeq {1}{5}}} \end{everbatim*} - -There is a subtlety here that the |2^35| will be evaluated as a floating point -number but fortunately it only has \dtt{11} digits, hence the final evaluation -is done with a correct exponent. It would have been safer, and also more -efficient to code the above rather as: -\begin{everbatim} -\xintthefloatexpr 1.1547^\xintiiexpr 2^35\relax\relax -\end{everbatim} - -Here is an example with -|12^16| as exponent, which has $18$ digits (\dtt{={\xintiiPow{12}{16}}}). \begin{everbatim*} -{\xintDigits:=12\relax \np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}}\newline -\np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}\newline -{\xintDigits:=27\relax \np{\xintthefloatexpr (1+1e-8)^(12^16)\relax}}\newline -{\xintDigits:=48\relax \np{\xintthefloatexpr (1+1e-8)^(12^16)\relax}} +\[ \xintFrac{14946960/4805083}=\xintCFrac {14946960/4805083}\] \end{everbatim*} +In the example above the power of $3$ was already pre-computed via the expansion +done by |\xintApply|, but if we try with |\xintApply { \xintiiPow 3}| where the +space will stop this expansion, we can check that |\xintCtoF| will itself +provoke the needed coefficient expansion.% ok -There is an important difference between |\xintFloatPower[Q]{X}{Y}| and -|\xintthefloatexpr[Q] X^Y\relax|: in the former case the computation is done -with |Q| digits or precision,% -% -\footnote{if |X| and |Y| themselves stand for some -floating point macros with arguments, their respective evaluations obey the -precision |\xinttheDigits| or as set optionally in the macro calls -themselves.} -% -whereas with \csbxint{thefloatexpr}|[Q]| the evaluation of the -expression proceeds with |\xinttheDigits| digits of precision, and the final -result is then rounded to |Q| digits: thus this makes real sense only if used -with |Q<\xinttheDigits|. - -\subsection{\csh{xintFloatSqrt}}\label{xintFloatSqrt} - -\csa{xintFloatSqrt}|[P]{f}|\etype{{\upshape[\numx]}\Ff} computes a floating -point approximation of $\sqrt{|f|}$, either using the optional precision |P| or -the value of |\xinttheDigits|. +\subsection{\csh{xintGCtoF}}\label{xintGCtoF} -More precisely since |1.2f| the macro achieves so-called \emph{correct - rounding}:\IMPORTANT{} the produced value is the rounding to |P| significant -places of the abstract exact value, \emph{if the input has itself at most |P| - digits} (and an arbitrary exponent). +\csa{xintGCtoF}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} computes the fraction +defined by the inline generalized continued fraction. Coefficients may be +fractions but must then be put within braces. They can be macros. The plus signs +are mandatory. \begin{everbatim*} -\xintFloatSqrt [89]{10}\newline -\xintFloatSqrt [89]{100}\newline -\xintFloatSqrt [89]{123456789}\par +\[\xintGCFrac {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}} = +\xintFrac{\xintGCtoF {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}} = +\xintFrac{\xintIrr{\xintGCtoF + {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}}}\] \end{everbatim*} -And now some tests to check that correct rounding applies correctly (sic): \begin{everbatim*} -The argument has 16 digits, hence escapes initial rounding:\newline -\xintFloatSqrt {5625000075000001}\newline -This one gets rounded hence same value is computed:\newline -\xintFloatSqrt {5625000075000001.4}\newline -but actual value is more like:\newline -\xintFloatSqrt [24]{5625000075000001.4}\newline -\xintFloatSqrt [32]{5625000075000001.4}\newline -The argument has 48 digits, hence escapes initial rounding:\newline -\xintFloatSqrt [48]{562500000000000000000000750000000000000000000001}\newline -\xintFloatSqrt [64]{562500000000000000000000750000000000000000000001}\newline -\xintFloatSqrt [80]{562500000000000000000000750000000000000000000001}\newline +\[ \xintGCFrac{{1/2}+{2/3}/{4/5}+{1/2}/{1/5}+{3/2}/{5/3}} = + \xintFrac{\xintGCtoF {{1/2}+{2/3}/{4/5}+{1/2}/{1/5}+{3/2}/{5/3}}} \] \end{everbatim*} -(we observe in passing illustrations that rounding to nearest is not -transitive.)\par - +The macro tries its best not to accumulate superfluous factor in the +denominators, but doesn't reduce the fraction to irreducible form before +returning it and does not do simplifications which would be obvious to a human. +\subsection{\csh{xintCstoCv}}\label{xintCstoCv} +\csa{xintCstoCv}|{a,b,c,d,...,z}|\etype{f} returns the sequence of the +corresponding convergents, each one within braces. +\emph{Usage of this macro requires the user to load} \xinttoolsname.\IMPORTANT -\subsection{\csh{xintFloatFac}}\label{xintFloatFac} +It is allowed to use fractions as coefficients (the computed +convergents have then no reason to be the real convergents of the final +fraction). When the coefficients are integers, the convergents are irreducible +fractions, but otherwise it is not necessarily the case. +\begin{everbatim*} +\xintListWithSep:{\xintCstoCv{1,2,3,4,5,6}} +\end{everbatim*} +\begin{everbatim*} +\xintListWithSep:{\xintCstoCv{1,1/2,1/3,1/4,1/5,1/6}} +\end{everbatim*} +\begin{everbatim*} +\[\xintListWithSep{\to}{\xintApply\xintFrac{\xintCstoCv {\xintPow + {-.3}{-5},7.3/4.57,\xintCstoF{3/4,9,-1/3}}}}\] +\end{everbatim*} -\csa{xintFloatFac}|[P]{f}|\etype{{\upshape[\numx]}\Numf} returns the -factorial with either \csa{xinttheDigits} or |P| digits of precision. +\subsection{\csh{xintCtoCv}}\label{xintCtoCv} +\csa{xintCtoCv}|{{a}{b}{c}...{z}}|\etype{f} returns the sequence of the +corresponding convergents, each one within braces. +\begin{everbatim*} +\fdef\test{\xintCtoCv {11111111111}}\texttt{\meaning\test} +\end{everbatim*} +\subsection{\csh{xintGCtoCv}}\label{xintGCtoCv} -The exact theoretical value differs from the calculated one |Y| by an absolute -error strictly less than |0.6 ulp(Y)|. +\csa{xintGCtoCv}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} returns the list of +the corresponding convergents. The coefficients may be fractions, but must then +be inside braces. Or they may be macros, too. +The convergents will in the general case be reducible. To put them into +irreducible form, one needs one more step, for example it can be done +with |\xintApply\xintIrr|. \begin{everbatim*} -$1000!\approx{}$\xintFloatFac [30]{1000} +\[\xintListWithSep{,}{\xintApply\xintFrac + {\xintGCtoCv{3+{-2}/{7/2}+{3/4}/12+{-56}/3}}}\] +\[\xintListWithSep{,}{\xintApply\xintFrac{\xintApply\xintIrr + {\xintGCtoCv{3+{-2}/{7/2}+{3/4}/12+{-56}/3}}}}\] \end{everbatim*} -The computation proceeds via doing explicitely the product, as -the Stirling formula cannot be used for lack so far of |exp/log|. -The maximal allowed argument is $99999999$, but already $100000!$ currently -takes, for \dtt{16} digits of precision, a few seconds on my laptop (it -returns \dtt{2.824229407960348e456573}). -The |factorial| function is available in \csbxint{floatexpr}: +\subsection{\csh{xintFtoCv}}\label{xintFtoCv} + +\csa{xintFtoCv}|{f}|\etype{\Ff} returns the list of the (braced) convergents of +|f|, with no separator. To be treated with \csbxint{AssignArray} or +\csbxint{ListWithSep}. \begin{everbatim*} -\xintthefloatexpr factorial(1000)\relax % same as 1000! +\[\xintListWithSep{\to}{\xintApply\xintFrac{\xintFtoCv{5211/3748}}}\] \end{everbatim*} -\subsection{\csh{xintFloatBinomial}}\label{xintFloatBinomial} - -\csa{xintFloatBinomial}|[P]{x}{y}|\etype{{\upshape[\numx]}\Numf\Numf} computes -binomial coefficients with either \csa{xinttheDigits} or |P| digits of -precision. - -When |x<0| an out-of-range error is raised. Else if |y<0| or if |x binomial (9999.,5000.); -% 3008 -% 0.795895131768 10 -% -% > Digits:=32; -% Digits := 32 -% -% > binomial (9999.,5000.); -% 3008 -% 0.795895131768 10 -% apparemment le binomial de Maple ne sait pas calculer avec plus de -% précision! -% et son dernier chiffre est faux! Pourtant GAMMA(9999.) fonctionne. Sauf si -% je n'ai pas compris quelque chose il me semble donc que le binomial de Maple -% est bogué...binomial(100.,50.); marche lui et binomial(4999.,2000.); aussi, -% bon clairement on a un bug de Maple ! oui binomial(8999.,5000.); ainsi que -% binomial(10999.,5000.); fonctionnent avec Digits:=32 mais **pas** -% binomial(9999.,5000.)... binomial(10000.,5000.); et binomial(9998.,5000.); -% sont OK. Est-ce qu'on gagne quelque chose pour un bug report ? -% > binomial(9999.,5000.); -% 3008 -% 0.795895131768 10 -% > binomial(10000.,5000.); -% 3009 -% 0.1591790263532438948337597273641521 10 -% > binomial(9998.,5000.); -% 3008 -% 0.3979077671466477799149739359402922 10 -% en plus je lui demande 32 chiffres et il m'en sort 34. -The associated function in \csbxint{floatexpr} is \func{binomial}: +\csa{xintCntoF}|{N}{\macro}|\etype{\numx f} computes the fraction |f| having +coefficients |c(j)=\macro{j}| for |j=0,1,...,N|. The |N| parameter is given to a +|\numexpr|. The values of the coefficients, as returned by |\macro| do not have +to be positive, nor integers, and it is thus not necessarily the case that the +original |c(j)| are the true coefficients of the final |f|. \begin{everbatim*} -\xintthefloatexpr binomial(3000,1500)\relax +\def\macro #1{\the\numexpr 1+#1*#1\relax} \xintCntoF {5}{\macro} \end{everbatim*} -The computation is based on the formula |(x-y+1)...x/y!| (here one arranges -|y<=x-y| naturally). - - -\subsection{\csh{xintFloatPFactorial}}\label{xintFloatPFactorial} +This example shows that the fraction is output with a trailing number in square +brackets (representing a power of ten), this is for consistency with what do +most macros of \xintfracname, and does not have to be always this annoying |[0]| +as the coefficients may for example be numbers in scientific notation. To avoid +these trailing square brackets, for example if the coefficients are known to be integers, there is always the possibility to filter the output via +\csbxint{PRaw}, or \csbxint{Irr} (the latter is overkill in the case of integer +coefficients, as the fraction is guaranteed to be irreducible then). -\csa{xintFloatPFactorial}|[P]{x}{y}|\etype{{\upshape[\numx]}\Numf\Numf} -computes the product |(x+1)...y|. +\subsection{\csh{xintGCntoF}}\label{xintGCntoF} +\csa{xintGCntoF}|{N}{\macroA}{\macroB}|\etype{\numx ff} returns the fraction |f| +corresponding to the inline generalized continued fraction +|a0+b0/a1+b1/a2+....+b(N-1)/aN|, with |a(j)=\macroA{j}| and |b(j)=\macroB{j}|. +The |N| parameter is given to a |\numexpr|. +\begin{everbatim*} +\def\coeffA #1{\the\numexpr #1+4-3*((#1+2)/3)\relax }% +\def\coeffB #1{\the\numexpr \ifodd #1 -\fi 1\relax }% (-1)^n +\[\xintGCFrac{\xintGCntoGC {6}{\coeffA}{\coeffB}} = + \xintFrac{\xintGCntoF {6}{\coeffA}{\coeffB}}\] +\end{everbatim*} +There is also \csbxint{GCntoGC} to get the `inline format' continued +fraction. +\subsection{\csh{xintCntoCs}}\label{xintCntoCs} +\csa{xintCntoCs}|{N}{\macro}|\etype{\numx f} produces the comma separated list +of the corresponding coefficients, from |n=0| to |n=N|. The |N| is given to a +|\numexpr|. % +\begin{everbatim*} +\xintCntoCs {5}{\macro} +\end{everbatim*} +\begin{everbatim*} +\[ \xintFrac{\xintCntoF{5}{\macro}}=\xintCFrac{\xintCntoF {5}{\macro}}\] +\end{everbatim*} -The arguments must be integers (they are expanded inside |\numexpr|) -and the allowed range is $-100000000\leqslant x, y\leqslant99999999$. If -$x\geqslant y$ the product is considered empty hence returns one (as a -floating point value). -See also \csbxint{iiPFactorial}. +\subsection{\csh{xintCntoGC}}\label{xintCntoGC} +% +\csa{xintCntoGC}|{N}{\macro}|\etype{\numx f} evaluates the |c(j)=\macro{j}| from +|j=0| to |j=N| and returns a continued fraction written in inline format: +|{c(0)}+1/{c(1)}+1/...+1/{c(N)}|. The parameter |N| is given to a |\numexpr|. +The coefficients, after expansion, are, as shown, being enclosed in an added +pair of braces, they may thus be fractions. +\begin{everbatim*} +\def\macro #1{\the\numexpr\ifodd#1 -1-#1\else1+#1\fi\relax/\the\numexpr 1+#1*#1\relax} +\fdef\x{\xintCntoGC {5}{\macro}}\meaning\x +\[\xintGCFrac{\xintCntoGC {5}{\macro}}\] +\end{everbatim*} -The exact theoretical value differs from the calculated one |Y| by an absolute -error strictly less than |0.6 ulp(Y)|. +\subsection{\csh{xintGCntoGC}}\label{xintGCntoGC} -The associated function in \csbxint{floatexpr} is \func{pfactorial}: +\csa{xintGCntoGC}|{N}{\macroA}{\macroB}|\etype{\numx ff} evaluates the +coefficients and then returns the corresponding +|{a0}+{b0}/{a1}+{b1}/{a2}+...+{b(N-1)}/{aN}| inline generalized fraction. |N| is +givent to a |\numexpr|. The coefficients are enclosed into pairs +of braces, and may thus be fractions, the fraction slash will not be +confused in further processing by the continued fraction slashes. +% \begin{everbatim*} -\xintthefloatexpr pfactorial(2500,5000)\relax +\def\an #1{\the\numexpr #1*#1*#1+1\relax}% +\def\bn #1{\the\numexpr \ifodd#1 -\fi 1*(#1+1)\relax}% +$\xintGCntoGC {5}{\an}{\bn}=\xintGCFrac {\xintGCntoGC {5}{\an}{\bn}} = +\displaystyle\xintFrac {\xintGCntoF {5}{\an}{\bn}}$\par \end{everbatim*} -\xintDigits:=16\relax - -\subsection{\csh{xintFrac}}\label{xintFrac} +\subsection{\csh{xintCstoGC}}\label{xintCstoGC} -This is a \LaTeX{} only macro,\etype{\Ff} to be used in math mode only. It -will print a fraction, internally represented as something equivalent to -|A/B[n]| as |\frac {A}{B}10^n|. The power of ten is omitted when |n=0|, the -denominator is omitted when it has value one, the number being separated from -the power of ten by a |\cdot|. |$\xintFrac {178.000/25600000}$| gives $\xintFrac -{178.000/25600000}$, |$\xintFrac {178.000/1}$| gives $\xintFrac {178.000/1}$, -|$\xintFrac {3.5/5.7}$| gives $\xintFrac {3.5/5.7}$, and |$\xintFrac {\xintNum - {\xintiiFac{10}/|\allowbreak|\xintiiSqr{\xintiiFac {5}}}}$| gives $\xintFrac -{\xintNum {\xintiiFac{10}/\xintiiSqr{\xintiiFac {5}}}}$. As shown by the examples, -simplification of the input (apart from removing the decimal points and moving -the minus sign to the numerator) is not done automatically and must be the -result of macros such as |\xintIrr|, |\xintREZ|, or |\xintNum| (for fractions -being in fact integers.) +\csa{xintCstoGC}|{a,b,..,z}|\etype{f} transforms a comma separated list (or +something expanding to such a list) into an `inline format' continued fraction +|{a}+1/{b}+1/...+1/{z}|. The coefficients are just copied and put within braces, +without expansion. The output can then be used in \csbxint{GCFrac} for example. +\begin{everbatim*} +\[\xintGCFrac {\xintCstoGC {-1,1/2,-1/3,1/4,-1/5}}=\xintSignedFrac{\xintCstoF {-1,1/2,-1/3,1/4,-1/5}}\] +\end{everbatim*} +\subsection{\csh{xintiCstoF}, \csh{xintiGCtoF}, \csh{xintiCstoCv}, \csh{xintiGCtoCv}}\label{xintiCstoF} +\label{xintiGCtoF} +\label{xintiCstoCv} +\label{xintiGCtoCv} -\subsection{\csh{xintSignedFrac}}\label{xintSignedFrac} +Essentially\etype{f} the same as the corresponding macros without the +`i', but for integer-only input. Infinitesimally faster, mainly for +internal use by the package. +\subsection{\csh{xintGCtoGC}}\label{xintGCtoGC} -This is as \csbxint{Frac}\etype{\Ff} except that a negative fraction has the -sign put in front, not in the numerator. +\csa{xintGCtoGC}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} expands (with the +usual meaning) each one of the coefficients and returns an inline continued +fraction of the same type, each expanded coefficient being enclosed within +braces. +% \begin{everbatim*} -\[\xintFrac{-355/113}=\xintSignedFrac {-355/113}\] +\fdef\x {\xintGCtoGC {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/% + \xintiiFac {6}+\xintCstoF {2,-7,-5}/16}} \meaning\x \end{everbatim*} -\subsection{\csh{xintFwOver}}\label{xintFwOver} +To be honest I have forgotten for which purpose I wrote this macro in the first +place. -This does the same as \csa{xintFrac}\etype{\Ff} except that the \csa{over} -primitive is used for the fraction (in case the denominator is not one; and a -pair of braces contains the |A\over B| part). |$\xintFwOver {178.000/25600000}$| -gives $\xintFwOver {178.000/25600000}$, |$\xintFwOver {178.000/1}$| gives -$\xintFwOver {178.000/1}$, |$\xintFwOver {3.5/5.7}$| gives $\xintFwOver -{3.5/5.7}$, and |$\xintFwOver {\xintNum {\xintiiFac{10}/\xintiiSqr{\xintiiFac - {5}}}}$| gives $\xintFwOver {\xintNum {\xintiiFac{10}/\xintiiSqr{\xintiiFac - {5}}}}$. +\subsection{Euler's number \texorpdfstring{$e$}{e}}\label{ssec:e-convergents} -\subsection{\csh{xintSignedFwOver}}\label{xintSignedFwOver} +Let us explore +the convergents of Euler's number $e$. +\smallskip The volume of computation is kept minimal by the following steps: +\begin{itemize} +\item a comma separated list of the first 36 coefficients is produced by + \csbxint{CntoCs}, +\item this is then given to \csbxint{iCstoCv} which produces the list of the + convergents (there is also \csbxint{CstoCv}, but our + coefficients being integers we used the infinitesimally + faster \csbxint{iCstoCv}), +\item then the whole list was converted into a sequence of one-line paragraphs, + each convergent becomes the argument to a macro printing it + together with its decimal expansion with 30 digits after the decimal point. +\item A count register |\cnta| was used to give a line count serving as a visual + aid: we could also have done that in an expandable way, but well, let's relax + from time to time\dots +\end{itemize} -This is as \csbxint{FwOver}\etype{\Ff} except that a negative fraction has the -sign put in front, not in the numerator. \begin{everbatim*} -\[\xintFwOver{-355/113}=\xintSignedFwOver {-355/113}\] +\def\cn #1{\the\numexpr\ifcase \numexpr #1+3-3*((#1+2)/3)\relax + 1\or1\or2*(#1/3)\fi\relax } +% produces the pattern 1,1,2,1,1,4,1,1,6,1,1,8,... which are the +% coefficients of the simple continued fraction of e-1. +\cnta 0 +\def\mymacro #1{\advance\cnta by 1 + \noindent + \hbox to 3em {\hfil\small\dtt{\the\cnta.} }% + $\xintTrunc {30}{\xintAdd {1[0]}{#1}}\dots= + \xintFrac{\xintAdd {1[0]}{#1}}$}% +\xintListWithSep{\vtop to 6pt{}\vbox to 12pt{}\par} + {\xintApply\mymacro{\xintiCstoCv{\xintCntoCs {35}{\cn}}}} \end{everbatim*} -\subsection{\csh{xintLen}}\label{xintLenFrac} -The original \csbxint{Len} macro\etype{\Ff} is extended to accept a fraction -on input: the length of |A/B[n]| is the length of |A| plus the length of |B| -plus the absolute value of |n| and minus one (an integer input as |N| is -internally represented in a form equivalent to |N/1[0]| so the minus one means -that the extended \csa{xintLen} behaves the same as the original for -integers). +\smallskip + +% The actual computation of the list of all 36 convergents accounts for +% only 8\% of the total time (total time equal to about 5 hundredths of a second +% in my testing, on my laptop): another 80\% is occupied with the computation of +% the truncated decimal expansions (and the addition of 1 to everything as the +% formula gives the continued fraction of $e-1$). + +One can with no problem compute +much bigger convergents. Let's get the 200th convergent. It turns out to +have the same first 268 digits after the decimal point as $e-1$. Higher +convergents get more and more digits in proportion to their index: the 500th +convergent already gets 799 digits correct! To allow speedy compilation of the +source of this document when the need arises, I limit here to the 200th +convergent. +% (getting the 500th took about 1.2s on my laptop last time I tried, +% and the 200th convergent is obtained ten times faster). \begin{everbatim*} -\xintLen{201710/298219}=\xintLen{201710}+\xintLen{298219}-1\newline -\xintLen{1234/1}=\xintLen{1234}=\xintLen{1234[0]}=\xintiLen{1234}\newline -\xintLen{-1e3/5.425} (\xintRaw {-1e3/5.425})\par +\fdef\z {\xintCntoF {199}{\cn}}% +\begingroup\parindent 0pt \leftskip 2.5cm +\indent\llap {Numerator = }\printnumber{\xintNumerator\z}\par +\indent\llap {Denominator = }\printnumber{\xintDenominator\z}\par +\indent\llap {Expansion = }\printnumber{\xintTrunc{268}\z}\dots\par\endgroup \end{everbatim*} -The length is computed on the |A/B[n]| which would have been returned by -\csbxint{Raw}, as illustrated by the last example above. -|\xintLen| is only for use with such (scientific) numbers or fractions. See -also \csbxint{NthElt} from \xinttoolsname. See also \csbxint{Length} (which -however does not expand its argument) from \xintkernelname for counting more -general tokens (or rather braced items). + +One can also use a centered continued fraction: we get more digits but there are +also more computations as the numerators may be either +$1$ or $-1$. \clearpage -\let\xintfracnameUp\undefined -\csname xintbinhexnameUp\endcsname +\let\xintcfracnameUp\undefined +\csname xinttoolsnameUp\endcsname \def\n{|{N}|} \def\m{|{M}|} \def\x{|{x}|} -\section{Macros of the \xintbinhexname package} -\RaisedLabel{sec:binhex} - -\localtableofcontents - -This package provides expandable conversions of (big) integers to -and from binary and hexadecimal. - -First version of this package was in the |1.08| (|2013/06/07|) release of -\xintname. Its routines remained un-modified until their complete rewrite at -release |1.2m| (|2017/07/31|). The new macros are faster, using techniques -from the |1.2| (|2015/10/10|) release of \xintcorename. But the inputs are now -limited to a few thousand digits, whereas the |1.08| could handle (slowly...) -tens of thousands of digits. - -\autoref{tab:binhexsizes} recapitulates the maximal allowed sizes (they got -increased at |1.2n|): -for macro |\xintFooToBar| in the first column, the value in the second column -is the maximal |N| such that |\edef\X{\xintFooToBar{}}| does not -raise an error with standard \TeX\ memory parameters (input stack -size=\dtt{5000}, expansion depth=\dtt{10000}, parameter stack -size=\dtt{10000}). The tests were done with TL2017 and |etex|. Nested calls -will allow slightly lesser values only. The third column gives the -corresponding maximal size of output. The fourth column gives the \TeX\ -parameter cited in the error message when trying with |N+1| digits. +\section{Macros of the \xinttoolsname package} -\begin{table}[htbp] -\capstart - \centering -\def\E#1#2!{\edef\F{\the\numexpr(#1-\xintLength{#2})/2}% - \relax\romannumeral\xintreplicate{\F}{ }#2% - \romannumeral\xintreplicate{#1-\F-\xintLength{#2}}{ }\relax}% -% non satisfactory because depends on #1 oddness, but well. Temporary destined -% to stay... -\begin{tabular}{r>{\E{19}}c<{!}>{\E{19}}c<{!}r} - \hline - &Max\ length\ of\ input&->\ length\ of\ output&Limiting factor\\ - \csbxint{DecToHex}&6014&4995&input stack size=5000\\ - \csbxint{DecToBin}&6014&19979&input stack size=5000\\ - \csbxint{HexToDec}&8298&9992&input stack size=5000\\ - \csbxint{BinToDec}&19988&6017&input stack size=5000\\ - \csbxint{BinToHex}&19988&4997&input stack size=5000\\ - \csbxint{HexToBin}&4996&19984&input stack size=5000\\ - \csbxint{CHexToBin}&4997&19988&input stack size=5000\\ - \hline -\end{tabular} -\caption{Maximal sizes of inputs (at \texttt{1.2n}) for \xintbinhexname macros}\label{tab:binhexsizes} -\end{table} +\RaisedLabel{sec:tools} -Roughly, base |10| numbers are limited to \dtt{6000} digits, hexadecimal -numbers to (almost) \dtt{5000} digits, and binary numbers to (almost) -\dtt{20000} digits. With the surprising exception of \csbxint{HexToDec} which -allows almost \dtt{8300} hexadecimal digits on input. +These utilities used to be provided within the \xintname package; since |1.09g| +(|2013/11/22|) they have been moved to an independently usable package +\xinttoolsname, which has none of the \xintname facilities regarding big +numbers. Whenever relevant release |1.09h| has made the macros |\long| so they +accept |\par| tokens on input. -The argument is first \fexpan ded. -It may optionally have a unique leading minus sign (a plus sign is not -allowed), and leading zeroes. +The completely expandable utilities (up to \csbxint{iloop}) are documented +first, then the non expandable utilities. -An input (possibly signed) with no leading zeroes is guaranteed to give an -output without leading zero, with the sole, deliberate, exception of -\csbxint{CHexToBin}: from |N| hexadecimal digits it produces |4N| binary -digits, hence possibly with up to three leading zeroes (if the -input had none.) +\autoref{sec:examples} +gives additional (also dated) examples of use of macros of this package. -Inputs with leading zeroes usually produce outputs with an unspecified, -case-dependent, number of leading zeroes (\csbxint{BinToHex} always uses the -minimal number of hexadecimal digits needed to represent the binary digits, -inclusive of leading zeroes if present.) +\localtableofcontents -The macros converting from binary or decimal are robust against -non terminated inputs like |\the\numexpr 2+3| or |\the\mathcode`\-|. The macro -\csbxint{HexToDec} also but not \csbxint{HexToBin} and \csbxint{CHexToBin} -(anyway there are no primitive in (e)-\TeX\ to my knowledge which will -generate hexadecimal digits and may force expansion of next token). +\subsection{\csh{xintRevWithBraces}}\label{xintRevWithBraces} -Hexadecimal digits |A..F| must be in uppercase. Category code for them on -input may be \emph{letter} or \emph{other}. On output they are of category -code \emph{letter}, and in uppercase. +%{\small New in release |1.06|.\par} -Low-level unrecoverable errors will happen if for example a supposedly binary -input contains other digits than |0| and |1|. Inputs can not start with a -|0b|, |0x|, |#x|, |"| or similar prefix: only digits/letters according to the -binary, decimal, or hexadecimal notation. +\edef\X{\xintRevWithBraces{12345}} +\edef\y{\xintRevWithBraces\X} +\expandafter\def\expandafter\w\expandafter + {\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}} +% +\csa{xintRevWithBraces}\marg{list}\etype{f} first does the \fexpan sion of its +argument then it reverses the order of the tokens, or braced material, it +encounters, maintaining existing braces and adding a brace pair around each +naked token encountered. Space tokens (in-between top level braces or naked +tokens) are gobbled. This macro is mainly thought out for use on a \meta{list} +of such braced material; with such a list as argument the \fexpan sion will only +hit against the first opening brace, hence do nothing, and the braced stuff may +thus be macros one does not want to expand. +% +\leftedline{|\edef\x{\xintRevWithBraces{12345}}|} +% +\leftedline{|\meaning\x:|\dtt{\meaning\X}} +% +\leftedline{|\edef\y{\xintRevWithBraces\x}|} +% +\leftedline{|\meaning\y:|\dtt{\meaning\y}} +% +The examples above could be defined with |\edef|'s because the braced material +did not contain macros. Alternatively: +% +\leftedline{|\expandafter\def\expandafter\w\expandafter|} +% +\leftedline{|{\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}}|} +% +\leftedline{|\meaning\w:|\dtt{\meaning\w}} +% +The macro \csa{xintReverseWithBracesNoExpand}\etype{n} does the same job +without the initial expansion of its argument. -With this package loaded additionally to \xintexprname, hexadecimal input is -possible in expressions: simply by using the prefix |"|. Such hexadecimal -numbers may have a fractional part. Lowercase hexadecimal letters are -currently \emph{not} recognized as such in expressions. -Currently the |p| postfix notation from standard programming languages -standing for an extra -power of two multiplicand is not implemented. -% \clearpage +\subsection{\csh{xintZapFirstSpaces}, \csh{xintZapLastSpaces}, \csh{xintZapSpaces}, \csh{xintZapSpacesB}} +\label{xintZapFirstSpaces} +\label{xintZapLastSpaces} +\label{xintZapSpaces} +\label{xintZapSpacesB} +%{\small New with release |1.09f|.\par} -\subsection{\csh{xintDecToHex}}\label{xintDecToHex} +\csa{xintZapFirstSpaces}\marg{stuff}\etype{n} does not do \emph{any} expansion +of its argument, nor brace removal of any sort, nor does it alter \meta{stuff} +in anyway apart from stripping away all \emph{leading} spaces. -Converts from decimal to hexadecimal.\etype{f} +This macro will be mostly of interest to programmers who will know what I will +now be talking about. \emph{The essential points, naturally, are the complete + expandability and the fact that no brace removal nor any other alteration is + done to the input.} -\texttt{\string\xintDecToHex \string{\printnumber{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}\string}}\endgraf\noindent\dtt{->\printnumber{\xintDecToHex{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}}} +\TeX's input scanner already converts consecutive blanks into single space +tokens, but |\xintZapFirstSpaces| handles successfully also inputs with +consecutive multiple space tokens. +However, it is assumed that \meta{stuff} does not contain (except inside braced +sub-material) space tokens of character code distinct from $32$. -\subsection{\csh{xintDecToBin}}\label{xintDecToBin} +It expands in two steps, and if the goal is to apply it to the +expansion text of |\x| to define |\y|, then one can do: +|\odef\y{\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}| +(one can also define a wrapper macro to |\xintZapFirstSpaces| in order to +expand once the argument first, but \xinttoolsname not being a programming +layer, it provides no «Generate Variants» facilities). -Converts from decimal to binary.\etype{f} +Other use case: inside a macro which received a parameter |#1|, one can do +|\oodef\x{\xintZapFirstSpaces {#1}}|, or, if |#1|, after leading spaces have +been stripped can accept |\edef| expansion, one can do +|\edef\x{\xintZapFirstSpaces{#1}}|. -\texttt{\string\xintDecToBin \string{\printnumber{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}\string}}\endgraf\noindent\dtt{->\printnumber{\xintDecToBin{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}}} +\begingroup +\def\x { \a { \X } { \b \Y } } +% +\leftedline{|\xintZapFirstSpaces { \a { \X } { \b \Y } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}}+++} +\endgroup -\subsection{\csh{xintHexToDec}}\label{xintHexToDec} +\medskip -Converts from hexadecimal to decimal.\etype{f} +\noindent\csbxint{ZapLastSpaces}\marg{stuff}\etype{n} does not do \emph{any} expansion of +its argument, nor brace removal of any sort, nor does it alter \meta{stuff} in +anyway apart from stripping away all \emph{ending} spaces. The same remarks as +for \csbxint{ZapFirstSpaces} apply. -\texttt{\string\xintHexToDec - \string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent -\dtt{->\printnumber{\xintHexToDec{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}} +\begingroup +\def\x { \a { \X } { \b \Y } } +% +\leftedline{|\xintZapLastSpaces { \a { \X } { \b \Y } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzaplastspaces\expandafter{\x}}}+++} +\endgroup -\subsection{\csh{xintBinToDec}}\label{xintBinToDec} +\medskip -Converts from binary to decimal.\etype{f} +\noindent\csbxint{ZapSpaces}\marg{stuff}\etype{n} does not do \emph{any} +expansion of its +argument, nor brace removal of any sort, nor does it alter \meta{stuff} in +anyway apart from stripping away all \emph{leading} and all \emph{ending} +spaces. The same remarks as for \csbxint{ZapFirstSpaces} apply. -\texttt{\string\xintBinToDec - \string{\printnumber{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}\string}}\endgraf\noindent -\dtt{->\printnumber{\xintBinToDec{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}}} +\begingroup +\def\x { \a { \X } { \b \Y } } +% +\leftedline{|\xintZapSpaces { \a { \X } { \b \Y } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapspaces\expandafter{\x}}}+++} +\endgroup -\subsection{\csh{xintBinToHex}}\label{xintBinToHex} +\medskip -Converts from binary to hexadecimal.\etype{f} The input is first zero-filled -to |4N| binary digits, hence the output will have |N| hexadecimal digits -(thus, if the input did not have a leading zero, the output will not either). +\noindent\csbxint{ZapSpacesB}\marg{stuff}\etype{n} does not do \emph{any} +expansion of +its argument, nor does it alter \meta{stuff} in anyway apart from stripping away +all leading and all ending spaces and possibly removing one level of braces if +\meta{stuff} had the shape |{braced}|. The same remarks as for +\csbxint{ZapFirstSpaces} apply. -\texttt{\string\xintBinToHex - \string{\printnumber{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}\string}}\endgraf\noindent -\dtt{->\printnumber{\xintBinToHex{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}}} +\begingroup +\def\x { \a { \X } { \b \Y } } +% +\leftedline{|\xintZapSpacesB { \a { \X } { \b \Y } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++} +\def\x { { \a { \X } { \b \Y } } } +% +\leftedline{|\xintZapSpacesB { { \a { \X } { \b \Y } } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++} +\endgroup + The spaces here at the start and end of the output come from the braced + material, and are not removed (one would need a second application for that; + recall though that the \xintname zapping macros do not expand their argument). -\subsection{\csh{xintHexToBin}}\label{xintHexToBin} +\subsection{\csh{xintCSVtoList}} +\label{xintCSVtoList} +\label{xintCSVtoListNoExpand} -Converts from hexadecimal to binary. Up to three leading zeroes of the output -are trimmed.\etype{f} -\texttt{\string\xintHexToBin - \string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent -\dtt{->\printnumber{\xintHexToBin{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}} +\csa{xintCSVtoList}|{a,b,c...,z}|\etype{f} returns |{a}{b}{c}...{z}|. A +\emph{list} is by +convention in this manual simply a succession of tokens, where each braced thing +will count as one item (``items'' are defined according to the rules of \TeX{} +for fetching undelimited parameters of a macro, which are exactly the same rules +as for \LaTeX{} and macro arguments [they are the same things]). The word +`list' in `comma separated list of items' has its usual linguistic meaning, +and then an ``item'' is what is delimited by commas. -\subsection{\csh{xintCHexToBin}}\label{xintCHexToBin} +So \csa{xintCSVtoList} takes on input a `comma separated list of items' and +converts it into a `\TeX{} list of braced items'. The argument to +|\xintCSVtoList| may be a macro: it will first be +\hyperref[ssec:expansions]{\fexpan ded}. Hence the item before the first comma, +if it is itself a macro, will be expanded which may or may not be a good thing. +A space inserted at the start of the first item serves to stop that expansion +(and disappears). The macro \csbxint{CSVtoListNoExpand}\etype{n} does the same +job without +the initial expansion of the list argument. -Converts from hexadecimal to binary.\etype{f} Same as \csbxint{HexToBin}, but -an input with |N| hexadecimal digits will give an output with exactly |4N| -binary digits, leading zeroes are not trimmed. +Apart from that no expansion of the items is done and the list items may thus be +completely arbitrary (and even contain perilous stuff such as unmatched |\if| +and |\fi| tokens). -\texttt{\string\xintCHexToBin - \string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent -\dtt{->\printnumber{\xintCHexToBin{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}} +Contiguous spaces and tab characters, are collapsed by \TeX{} +into single spaces. All such spaces around commas% +% +\footnote{and multiple space tokens are not a problem; but those at the + top level (not hidden inside braces) \emph{must} be of character code + |32|.} +% +\fbox{are removed}, as well as +the spaces at the start and the spaces at the end of the list.% +% +\footnote{let us recall that this is all done completely expandably... + There is absolutely no alteration of any sort of the item apart from + the stripping of initial and final space tokens (of character code + |32|) and brace removal if and only if the item apart from intial and + final spaces (or more generally multiple |char 32| space tokens) is + braced.} +% +The items may contain explicit |\par|'s or +empty lines (converted by the \TeX{} input parsing into |\par| tokens). -This can be combined with \csbxint{BinToHex} for round-trips preserving -leading zeroes for |4N| binary digits numbers, whereas using -\csbxint{HexToBin} gives reproducing round-trips only for |4N| binary numbers -numbers not starting with |0000|. -\begin{everbatim*} -This zero-fills to 4N digits the input, hence gives here a leading zero in output: -\xintBinToHex{0001111}\newline -Chaining, we end up with 4N-3 digits, as three binary zeroes are trimmed: -\xintHexToBin{\xintBinToHex{0001111}}\newline -But this will always reproduce the initial input zero-filled to length 4N: -\xintCHexToBin{\xintBinToHex{0001111}}\par -Another example (visible space characters manually inserted):\newline -$000000001111101001010001\xrightarrow{\text{\string\xintBinToHex}} -\xintBinToHex{000000001111101001010001}\xrightarrow{\text{\string\xintHexToBin\hphantom{X}}} -\text{\textvisiblespace\textvisiblespace\textvisiblespace} -\xintHexToBin{\xintBinToHex{000000001111101001010001}}$\newline -$000000001111101001010001\xrightarrow{\text{\string\xintBinToHex}} -\xintBinToHex{000000001111101001010001}\xrightarrow{\text{\string\xintCHexToBin}} -\xintCHexToBin{\xintBinToHex{000000001111101001010001}}$ -\par -\end{everbatim*} +\begingroup -\clearpage -\let\xintbinhexnameUp\undefined -\csname xintgcdnameUp\endcsname -\def\n{|{N}|} -\def\m{|{M}|} -\def\x{|{x}|} -\section{Macros of the \xintgcdname package} -\RaisedLabel{sec:gcd} +\edef\X{\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , { {x , + y} } }} -\localtableofcontents +% +\leftedline{|\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , + { {x , y} } }|} +% +\leftedline{|->|% +{\makeatletter\dtt{\expandafter\strip@prefix\meaning\X}}} -This package was included in the original release |1.0| (|2013/03/28|) of the -\xintname bundle. +One sees on this example how braces protect commas from +sub-lists to be perceived as delimiters of the top list. Braces around an entire +item are removed, even when surrounded by spaces before and/or after. Braces for +sub-parts of an item are not removed. -! Since release |1.09a| the macros filter their inputs through the \csbxint{Num} -! macro, so one can use count registers, or fractions as long as they reduce to -! integers. +We observe also that there is a slight difference regarding the brace stripping +of an item: if the braces were not surrounded by spaces, also the initial and +final (but no other) spaces of the \emph{enclosed} material are removed. This is +the only situation where spaces protected by braces are nevertheless removed. -! Since release |1.1|, the two ``|typeset|'' macros require the explicit -! loading by the user of package \xinttoolsname. +From the rules above: for an empty argument (only spaces, no braces, no comma) +the output is +\dtt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist { }}} +(a list with one empty item), +for ``|{}|'' the output is +\dtt{\expandafter\detokenize\expandafter + {\romannumeral0\xintcsvtolist { {} }}} +(again a list with one empty item, the braces were removed), +for ``|{ }|'' the output is +\dtt{\expandafter\detokenize\expandafter + {\romannumeral0\xintcsvtolist {{ }}}} +(again a list with one empty item, the braces were removed and then +the inner space was removed), +for ``| { }|'' the output is +\dtt{\expandafter\detokenize\expandafter +{\romannumeral0\xintcsvtolist { { }}}} (again a list with one empty item, the initial space served only to stop the expansion, so this was like ``|{ }|'' as input, the braces were removed and the inner space was stripped), +for ``\texttt{\ \{\ \ \}\ }'' the output is +\dtt{\expandafter\detokenize\expandafter +{\romannumeral0\xintcsvtolist { { } }}} (this time the ending space of the first +item meant that after brace removal the inner spaces were kept; recall though +that \TeX{} collapses on input consecutive blanks into one space token), +for ``|,|'' the output consists of two consecutive +empty items +\dtt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist + {,}}}. Recall that on output everything is braced, a |{}| is an ``empty'' +item. +% +Most of the above is mainly irrelevant for every day use, apart perhaps from the +fact to be noted that an empty input does not give an empty output but a +one-empty-item list (it is as if an ending comma was always added at the end of +the input). -At |1.3d| macros \csbxint{iiGCD} and \csbxint{iiLCM} are copied over to -\xintname, hence \func{gcd} and \func{lcm} functions in \csbxint{iiexpr} were -available simply from loading only \xintexprname, and the \xintgcdname dependency -got removed. +\def\y { \a,\b,\c,\d,\e} +\expandafter\def\expandafter\Y\expandafter{\romannumeral0\xintcsvtolist{\y}} +\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode} +\expandafter\def\expandafter\T\expandafter{\romannumeral0\xintcsvtolist{\t}} -\begin{framed} -From |1.1| to |1.3f| the package loaded only \xintcorename, -not \xintname and neither \xinttoolsname. +% +\leftedline{|\def\y{ \a,\b,\c,\d,\e} \xintCSVtoList\y->|% + {\makeatletter\dtt{\expandafter\strip@prefix\meaning\Y}}} +% +\leftedline{|\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} +% +\leftedline +{|\xintCSVtoList\t->|\makeatletter\dtt{\expandafter\strip@prefix\meaning\T}} +% +The results above were automatically displayed using \TeX's primitive +\csa{meaning}, which adds a space after each control sequence name. These spaces +are not in the actual braced items of the produced lists. The first items |\a| +and |\if| were either preceded by a space or braced to prevent expansion. The +macro \csa{xintCSVtoListNoExpand} would have done the same job without the +initial expansion of the list argument, hence no need for such protection but if +|\y| is defined as |\def\y{\a,\b,\c,\d,\e}| we then must do: +% +\leftedline{|\expandafter\xintCSVtoListNoExpand\expandafter {\y}|} Else, we +may have direct use: % +% +\leftedline{|\xintCSVtoListNoExpand + {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} +% +\leftedline{|->|\dtt{\expandafter\detokenize\expandafter + {\romannumeral0\xintcsvtolistnoexpand + {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}}}} +% +Again these spaces are an artefact from the use in the source of the document of +\csa{meaning} (or rather here, \csa{detokenize}) to display the result of using +\csa{xintCSVtoListNoExpand} (which is done for real in this document +source). -But at |1.4| it loads automatically both \xintname and \xinttoolsname (the -latter being a requirement since |1.09h| of the \csbxint{TypesetEuclideAlgorithm} and -\csbxint{TypesetBezoutAlgorithm} macros). +For the similar conversion from comma separated list to braced items list, but +without removal of spaces around the commas, there is +\csa{xintCSVtoListNonStripped}\etype{f} and +\csa{xintCSVtoListNonStrippedNoExpand}\etype{n}. -The macros \csbxint{iiGCD} and \csbxint{iiLCM} got relocated into -\xintname. \IMPORTANTf The macros \csbxint{GCD}, \csbxint{LCM}, -\csbxint{GCDof}, and \csbxint{LCMof} are \emph{removed}: -\xintfracname provides under these names more powerful macros handling -general fractions and not only integers. -\end{framed} +\endgroup +\subsection{\csh{xintNthElt}}\label{xintNthElt} -\subsection{\csh{xintBezout}}\label{xintBezout} -|\xintBezout|\n\m\etype{\Numf\Numf} returns three numbers |U|, |V|, -|D| within braces where |D| is the (non-negative) GCD, and \dtt{UN + VM = D}. -\begin{everbatim*} -\oodef\X{\xintBezout {10000}{1113}}\meaning\X\par -\xintAssign {\xintBezout {10000}{1113}}\to\U\V\D -U: \meaning\U, V: \meaning\V, D: \meaning\D\par -AU+BV: \xinttheiiexpr 10000*\U+1113*\V\relax\par -\noindent\oodef\X{\xintBezout {123456789012345}{9876543210321}}\meaning\X\par -\xintAssign \X\to\U\V\D -U: \meaning\U, V: \meaning\V, D: \meaning\D\par -AU+BV: \xinttheiiexpr 123456789012345*\U+9876543210321*\V\relax -\end{everbatim*} +\def\macro #1{\the\numexpr 9-#1\relax} -\subsection{\csh{xintEuclideAlgorithm}}\label{xintEuclideAlgorithm} +\csa{xintNthElt\x}\marg{list}\etype{\numx f} gets (expandably) the |x|th +item of the \meta{list}. A braced item will lose one level of brace +pairs. The token list is first \fexpan ded. -|\xintEuclideAlgorithm|\n\m\etype{\Numf\Numf} applies the Euclide algorithm -and keeps a copy of all quotients and remainders. -\begin{everbatim*} -\edef\X{\xintEuclideAlgorithm {10000}{1113}}\meaning\X -\end{everbatim*} +Items are counted starting at one. -The first item is the number of steps, the second is |N|, the -third is the GCD, the fourth is |M| then the first quotient and -remainder, the second quotient and remainder, \dots until the -final quotient and last (zero) remainder. +\leftedline{|\xintNthElt {3}{{agh}\u{zzz}\v{Z}}| is + \texttt{\xintNthElt {3}{{agh}\u{zzz}\v{Z}}}} +% +\leftedline{|\xintNthElt {3}{{agh}\u{{zzz}}\v{Z}}| is + \texttt{\expandafter\expandafter\expandafter + \detokenize\expandafter\expandafter\expandafter {\xintNthElt + {3}{{agh}\u{{zzz}}\v{Z}}}}} +% +\leftedline{|\xintNthElt {2}{{agh}\u{{zzz}}\v{Z}}| is + \texttt{\expandafter\expandafter\expandafter + \detokenize\expandafter\expandafter\expandafter {\xintNthElt + {2}{{agh}\u{{zzz}}\v{Z}}}}} +% +\leftedline{|\xintNthElt {37}{\xintiiFac {100}}|\dtt{=\xintNthElt + {37}{\xintiiFac {100}}} is the thirty-seventh digit of $100!$.} +% +\leftedline{|\xintNthElt {10}{\xintFtoCv + {566827/208524}}|\dtt{=\xintNthElt {10}{\xintFtoCv + {566827/208524}}}} +\leftedline{is the tenth convergent of $566827/208524$ (uses \xintcfracname + package).} +% +\leftedline{|\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% + \dtt{=\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} +% +\leftedline{|\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% + \dtt{=\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} +% +\leftedline{|\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% + \dtt{=\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} -\subsection{\csh{xintBezoutAlgorithm}}\label{xintBezoutAlgorithm} +If |x=0|, +the macro returns the \emph{length} of the expanded list: this is not equivalent +to \csbxint{Length} which does no pre-expansion. And it is different from +\csbxint{Len} which is to be used only on integers or fractions. -|\xintBezoutAlgorithm|\n\m\etype{\Numf\Numf} applies the Euclide algorithm -and keeps a copy of all quotients and remainders. Furthermore it computes the -entries of the successive products of the 2 by 2 matrices -$\left(\vcenter{\halign {\,#&\,#\cr q & 1 \cr 1 & 0 \cr}}\right)$ formed from -the quotients arising in the algorithm. -\begin{everbatim*} -\edef\X{\xintBezoutAlgorithm {10000}{1113}}\printnumber{\meaning\X} -\end{everbatim*} +If |x<0|, the macro returns the \verb+|x|+th element from the end of the list. +Thus for example |x=-1| will fetch the last item of the list. +% +\leftedline {|\xintNthElt {-5}{{{agh}}\u{zzz}\v{Z}}| is + \texttt{\expandafter\expandafter\expandafter \detokenize + \expandafter\expandafter\expandafter{\xintNthElt {-5}{{{agh}}\u{zzz}\v{Z}}}}} -The first item is the number of steps, the second is |N|, then -|0|, |1|, the GCD, |M|, |1|, |0|, the first quotient, the first -remainder, the top left entry of the first matrix, the bottom left -entry, and then these four things at each step until the end. +The macro \csa{xintNthEltNoExpand}\etype{\numx n} does the same job but without +first expanding the list argument: |\xintNthEltNoExpand {-4}{\u\v\w T\x\y\z}| is +\xintNthEltNoExpand {-4}{\a\b\c\u\v\w T\x\y\z}. -\subsection{\csh{xintTypesetEuclideAlgorithm}}\label{xintTypesetEuclideAlgorithm} +If |x| is strictly larger (in absolute value) than the length of the list +then |\xintNthElt| produces empty contents. -This macro is just an example of how to organize the data returned by -\csa{xintEuclideAlgorithm}.\ntype{\Numf\Numf} Copy the source code to a new -macro and modify it to what is needed. +\subsection{\csh{xintNthOnePy}} +\label{xintNthOnePy} -\leftedline{|\xintTypesetEuclideAlgorithm {123456789012345}{9876543210321}|} -\xintTypesetEuclideAlgorithm {123456789012345}{9876543210321} +\csa{xintNthOnePy\x}\marg{list}\etype{\numx f} gets (expandably) the |x|th +item of the \meta{list}, adding a brace pair if there wasn't one.\NewWith{1.4} -\subsection{\csh{xintTypesetBezoutAlgorithm}}% -\label{xintTypesetBezoutAlgorithm} +Attention, items are counted starting at zero. For negative index, behaves +as \csbxint{NthElt}. -This macro is just an example of how to organize the data returned by -\csa{xintBezoutAlgorithm}.\ntype{\Numf\Numf} Copy the source code to a new -macro and modify it to what is needed. +If the index is out of range, the empty output is returned. If the input list +was empty (had no items) the empty output is returned. -\leftedline{|\xintTypesetBezoutAlgorithm {10000}{1113}|} -\xintTypesetBezoutAlgorithm {10000}{1113} +\subsection{\csh{xintKeep}}\label{xintKeep} -\clearpage -\let\xintgcdnameUp\undefined -\csname xintseriesnameUp\endcsname -\def\n{|{N}|} -\def\m{|{M}|} -\def\x{|{x}|} -\section{Macros of the \xintseriesname package} -\RaisedLabel{sec:series} +\csa{xintKeep\x}\marg{list}\etype{\numx f} expands the token list argument |L| +and produces a new list, depending on the value of |x|: +\begin{itemize}[nosep] +\item if |x>0|, the new list contains the first |x| items from |L| (counting + starts at one.) \emph{Each + such item will be output within a brace pair.} Use \csbxint{KeepUnbraced} if + this is not desired. This means that if the list item was braced to start + with, there is no modification, but if it was a token without braces, + then it acquires them. +\item if |x>=length(L)|, the new list is the old one with all its items now + braced. +\item if |x=0| the empty list is returned. +\item if |x<0| the last \verb+|x|+ elements compose the output in the same + order as in the initial list; as the macro proceeds by removing head items + the kept items end up in output as they were in input: no added braces. +\item if |x<=-length(L)| the output is identical with the input. +\end{itemize} -\localtableofcontents +\csa{xintKeepNoExpand} does the same without first \fexpan ding its list +argument. +% +\begin{everbatim*} +\fdef\test {\xintKeep {17}{\xintKeep {-69}{\xintSeq {1}{100}}}}\meaning\test\par +\noindent\fdef\test {\xintKeep {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintKeep {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintKeep {7}{123456789}}\meaning\test\par +\noindent\fdef\test {\xintKeep {-7}{123456789}}\meaning\test\par +\end{everbatim*} -This package was first released with version |1.03| (|2013/04/14|) of the -\xintname bundle. -The \Ff{} expansion type of various macro arguments is only a \Numf{} if only -\xintname but not \xintfracname is loaded. The macro \csbxint{iSeries} is -special and expects summing big integers obeying the strict format, even if -\xintfracname is loaded. +\subsection{\csh{xintKeepUnbraced}}\label{xintKeepUnbraced} -The arguments serving as indices are of the \numx{} expansion type. +Same as \csbxint{Keep} but no brace pairs are added around the kept items from +the head of the list in the case |x>0|: each such item will lose one level of +braces. Thus, to remove braces from all items of the list, one can use +\csbxint{KeepUnbraced} with its first argument larger than the length of the +list; the same is obtained from \csbxint{ListWithSep}|{}|\marg{list}. But the +new list will then have generally many more items than the original ones, +corresponding to the unbraced original items. -In some cases one or two of the macro arguments are only expanded at a later -stage not immediately. +For |x<0| the macro is no different from \csbxint{Keep}. Hence the name is a +bit misleading because brace removal will happen only if |x>0|. -\begin{framed} - Since |1.3|, \csbxint{Add} and \csbxint{Sub} use systematically the least - common multiple of the denominators. Some of the comments in this chapter - refer to the earlier situation where often the denominators were simply - multiplied together. \emph{They have yet to be updated to reflect the new - situation brought by the |1.3| release.} Some of these comments may now be - off-synced from the actual computation results and thus may be wrong. -\end{framed} -%% \clearpage +\csa{xintKeepUnbracedNoExpand} does the same without first \fexpan ding +its list argument. +% +\begin{everbatim*} +\fdef\test {\xintKeepUnbraced {10}{\xintSeq {1}{100}}}\meaning\test\par +\noindent\fdef\test {\xintKeepUnbraced {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintKeepUnbraced {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintKeepUnbraced {7}{123456789}}\meaning\test\par +\noindent\fdef\test {\xintKeepUnbraced {-7}{123456789}}\meaning\test\par +\end{everbatim*} -\subsection{\csh{xintSeries}}\label{xintSeries} +\subsection{\csh{xintTrim}}\label{xintTrim} -\csa{xintSeries}|{A}{B}{\coeff}|\etype{\numx\numx\Ff} computes -$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|. The initial and final indices -must obey the |\numexpr| constraint of expanding to numbers at most |2^31-1|. -The |\coeff| macro must be a one-parameter \fexpan dable macro, taking on -input an explicit number |n| and producing some number or fraction |\coeff{n}|; -it is expanded at the time it is -needed.% -% +\csa{xintTrim\x}\marg{list}\etype{\numx f} expands the list argument and +gobbles its first |x| elements. +\begin{itemize}[nosep] +\item if |x>0|, the first |x| items from |L| are gobbled. The remaining items + are not modified. +\item if |x>=length(L)|, the returned list is empty. +\item if |x=0| the original list is returned (with no added braces.) +\item if |x<0| the last \verb+|x|+ items of the list are removed. \emph{The + head items end up braced in the output.} Use \csbxint{TrimUnbraced} if + this is not desired. +\item if |x<=-length(L)| the output is empty. +\end{itemize} +\csa{xintTrimNoExpand} does the same without first \fexpan ding its list +argument. \begin{everbatim*} -\def\coeff #1{\xintiiMON{#1}/#1.5} % (-1)^n/(n+1/2) -\fdef\w {\xintSeries {0}{50}{\coeff}} % we want to re-use it -\fdef\z {\xintJrr {\w}[0]} % the [0] for a microsecond gain. -% \xintJrr preferred to \xintIrr: a big common factor is suspected. -% But numbers much bigger would be needed to show the greater efficiency. -\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} = \xintFrac\z \] +\fdef\test {\xintTrim {17}{\xintTrim {-69}{\xintSeq {1}{100}}}}\meaning\test\par +\noindent\fdef\test {\xintTrim {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintTrim {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintTrim {7}{123456789}}\meaning\test\par +\noindent\fdef\test {\xintTrim {-7}{123456789}}\meaning\test\par \end{everbatim*} -The definition of |\coeff| as |\xintiiMON{#1}/#1.5| is quite suboptimal. It -allows |#1| to be a big integer, but anyhow only small integers are accepted -as initial and final indices (they are of the \numx{} type). Second, when the -\xintfracname parser sees the |#1.5| it will remove the dot hence create a -denominator with one digit more. For example |1/3.5| turns internally into -|10/35| whereas it would be more efficient to have |2/7|. For info here is the -non-reduced |\w|: -\[\xintFrac\w\] -It would have been bigger still in releases earlier than |1.1|: now, the -\xintfracname \csbxint{Add} routine does not multiply blindly denominators -anymore, it checks if one is a multiple of the other. However it does not -practice systematic reduction to lowest terms. +\subsection{\csh{xintTrimUnbraced}}\label{xintTrimUnbraced} + +Same as \csbxint{Trim} but in case of a negative |x| (cutting items from +the tail), the kept items from the head are not enclosed in brace pairs. They +will lose one level of braces. The name is a bit misleading +because when |x>0| there is no brace-stripping done on the kept items, because +the macro works simply by gobbling the head ones. + +\csa{xintTrimUnbracedNoExpand} does the same without first \fexpan ding its list +argument. -A more efficient way to code |\coeff| is illustrated next. \begin{everbatim*} -\def\coeff #1{\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}% -% The [0] in \coeff is a tiny optimization: in its presence the \xintfracname parser -% sees something which is already in internal format. -\fdef\w {\xintSeries {0}{50}{\coeff}} -\[\sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12}=\xintFrac\w\] +\fdef\test {\xintTrimUnbraced {-90}{\xintSeq {1}{100}}}\meaning\test\par +\noindent\fdef\test {\xintTrimUnbraced {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintTrimUnbraced {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintTrimUnbraced {7}{123456789}}\meaning\test\par +\noindent\fdef\test {\xintTrimUnbraced {-7}{123456789}}\meaning\test\par \end{everbatim*} -The reduced form |\z| as displayed above only differs from this one by a -factor of \dtt{\xintNum {\xintDenominator\w/\xintDenominator\z}}. -\setlength{\columnsep}{0pt} -\everb|@ -\def\coeffleibnitz #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]} -\cnta 1 -\loop -% in this loop we recompute from scratch each partial sum! -% we can afford that, as \xintSeries is fast enough. -\noindent\hbox to 2em{\hfil\texttt{\the\cnta.} }% - \xintTrunc {12}{\xintSeries {1}{\cnta}{\coeffleibnitz}}\dots -\endgraf -\ifnum\cnta < 30 \advance\cnta 1 \repeat -| +\subsection{\csh{xintListWithSep}}\label{xintListWithSep} -\begin{multicols}{3} - \def\coeffleibnitz #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]} \cnta 1 - \loop - \noindent\hbox to 2em{\hfil\dtt{\the\cnta.} }% - \xintTrunc {12}{\xintSeries {1}{\cnta}{\coeffleibnitz}}\dots - \endgraf - \ifnum\cnta < 30 \advance\cnta 1 \repeat -\end{multicols} -\subsection{\csh{xintiSeries}}\label{xintiSeries} +\def\macro #1{\the\numexpr 9-#1\relax} -\def\coeff #1{\xintiTrunc {40} - {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% +\csa{xintListWithSep}\marg{sep}\marg{list}\etype{nf} inserts the separator +\meta{sep} in-between all items of the given list of braced items (or +individual tokens). The items are fetched as does \TeX\ with undelimited macro +arguments, thus they end up unbraced in output. If the \meta{list} is only one +(or multiple) space tokens, the output is empty. -\csa{xintiSeries}|{A}{B}{\coeff}|\etype{\numx\numx f} computes - $\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}| where |\coeff{n}| - must \fexpan d to a (possibly long) integer in the strict format. -\everb|@ -\def\coeff #1{\xintiTrunc {40}{\xintiiMON{#1}/#1.5}}% -% better: -\def\coeff #1{\xintiTrunc {40} - {\the\numexpr 2*\xintiiMON{#1}\relax/\the\numexpr 2*#1+1\relax [0]}}% -% better still: -\def\coeff #1{\xintiTrunc {40} - {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% -% (-1)^n/(n+1/2) times 10^40, truncated to an integer. -\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx - \xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\dots\] -| +The list argument \meta{list} gets \fexpan ded first (thus if it is a macro +whose contents are braced items, the first opening brace stops the expansion, +and it is as if the macro had been expanded once.) The separator \meta{sep} is +not pre-expanded, it ends up as is in the output (if the \meta{list} contained +at least two items.) -\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx \xintTrunc -{40}{\xintiSeries {0}{50}{\coeff}[-40]}\] +The variant \csa{xintListWithSepNoExpand}\etype{nn} does the same +job without the initial expansion of the \meta{list} argument. +\begin{everbatim*} +\edef\foo{\xintListWithSep{, }{123456789{10}{11}{12}}}\meaning\foo\newline +\edef\foo{\xintListWithSep{:}{\xintiiFac{20}}}\meaning\foo\newline +\oodef\FOO{\xintListWithSepNoExpand{\FOO}{\bat\baz\biz\buz}}\meaning\FOO\newline +% a braced item or a space stops the f-expansion: +\oodef\foo{\xintListWithSep{\FOO}{{\bat}\baz\biz\buz}}\meaning\foo\newline +\oodef\foo{\xintListWithSep{\FOO}{ \bat\baz\biz\buz}}\meaning\foo\par +\end{everbatim*} -We should have cut out at -least the last two digits: truncating errors originating with the first -coefficients of the sum will never go away, and each truncation -introduces an uncertainty in the last digit, so as we have 40 terms, we -should trash the last two digits, or at least round at 38 digits. It is -interesting to compare with the computation where rounding rather than -truncation is used, and with the decimal -expansion of the exactly computed partial sum of the series: -\everb|@ -\def\coeff #1{\xintiRound {40} % rounding at 40 - {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% -% (-1)^n/(n+1/2) times 10^40, rounded to an integer. -\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx - \xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\] -\def\exactcoeff #1% - {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}% -\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} - = \xintTrunc {50}{\xintSeries {0}{50}{\exactcoeff}}\dots\] -| +\subsection{\csh{xintApply}}\label{xintApply} -\def\coeff #1{\xintiRound {40} - {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% -% (-1)^n/(n+1/2) times 10^40, rounded to an integer. -\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx - \xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\] -\def\exactcoeff #1% - {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}% -\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} - = \xintTrunc {50}{\xintSeries {0}{50}{\exactcoeff}}\dots\] -This shows indeed that our sum of truncated terms -estimated wrongly the 39th and 40th digits of the exact result% + +\def\macro #1{\the\numexpr 9-#1\relax} + +\csa{xintApply}|{\macro}|\marg{list}\etype{ff} expandably applies the one +parameter macro |\macro| to each item in the \meta{list} given as second +argument and returns a new list with these outputs: each item is given one after +the other as parameter to |\macro| which is expanded at that time (as usual, +\emph{i.e.} fully for what comes first), the results are braced and output +together as a succession of braced items (if |\macro| is defined to start with a +space, the space will be gobbled and the |\macro| will not be expanded; it is +allowed to have its own arguments, the list items serve as last arguments to +|\macro|). Hence |\xintApply{\macro}{{1}{2}{3}}| returns +|{\macro{1}}{\macro{2}}{\macro{3}}| where all instances of |\macro| have been +already \fexpan ded. + +Being expandable, |\xintApply| is useful for example inside alignments where +implicit groups make standard loops constructs usually fail. In such situation +it is often not wished that the new list elements be braced, see +\csbxint{ApplyUnbraced}. The |\macro| does not have to be expandable: +|\xintApply| will try to expand it, the expansion may remain partial. + +The \meta{list} may +itself be some macro expanding (in the previously described way) to the list of +tokens to which the macro |\macro| will be applied. For example, if the +\meta{list} expands to some positive number, then each digit will be replaced by +the result of applying |\macro| on it. % % -\footnote{as the series is alternating, we can roughly expect an error - of $\sqrt{40}$ and the last two digits are off by 4 units, which is - not contradictory to our expectations.} +\leftedline{|\def\macro #1{\the\numexpr + 9-#1\relax}|} % % -and that the sum of rounded terms fared a bit better. +\leftedline{|\xintApply\macro{\xintiiFac + {20}}|\dtt{=\xintApply\macro{\xintiiFac {20}}}} -\subsection{\csh{xintRationalSeries}}\label{xintRationalSeries} +The macro \csa{xintApplyNoExpand}\etype{fn} does the same job without the first +initial expansion which gave the \meta{list} of braced tokens to which |\macro| +is applied. +\subsection{\csh{xintApplyUnbraced}}\label{xintApplyUnbraced} -\noindent \csa{xintRationalSeries}|{A}{B}{f}{\ratio}|\etype{\numx\numx\Ff\Ff} -evaluates $\sum_{\text{|n=A|}}^{\text{|n=B|}}$|F(n)|, where |F(n)| is specified -indirectly via the data of |f=F(A)| and the one-parameter macro |\ratio| which -must be such that |\macro{n}| expands to |F(n)/F(n-1)|. The name indicates that -\csa{xintRationalSeries} was designed to be useful in the cases where -|F(n)/F(n-1)| is a rational function of |n| but it may be anything expanding to -a fraction. The macro |\ratio| must be an expandable-only compatible macro and -expand to its value after iterated full expansion of its first item. |A| and -|B| are fed to a |\numexpr| hence may be count registers or arithmetic -expressions built with such; they must obey the \TeX{} bound. The initial term -|f| may be a macro |\f|, it will be expanded to its value representing |F(A)|. +\csa{xintApplyUnbraced}|{\macro}|\marg{list}\etype{ff} is like \csbxint{Apply}. +The difference is that after having expanded its list argument, and applied +|\macro| in turn to each item from the list, it reassembles the outputs without +enclosing them in braces. The net effect is the same as doing +% +\leftedline{|\xintListWithSep {}{\xintApply {\macro}|\marg{list}|}|} This is +useful for preparing a macro which will itself define some other macros or make +assignments, as the scope will not be limited by brace pairs. +% \begin{everbatim*} -\def\ratio #1{2/#1[0]}% 2/n, to compute exp(2) -\cnta 0 % previously declared count -\begin{quote} -\loop \fdef\z {\xintRationalSeries {0}{\cnta}{1}{\ratio }}% -\noindent$\sum_{n=0}^{\the\cnta} \frac{2^n}{n!}= - \xintTrunc{12}\z\dots= - \xintFrac\z=\xintFrac{\xintIrr\z}$\vtop to 5pt{}\par -\ifnum\cnta<20 \advance\cnta 1 \repeat -\end{quote} +\def\macro #1{\expandafter\def\csname myself#1\endcsname {#1}} +\xintApplyUnbraced\macro{{elta}{eltb}{eltc}} +\begin{enumerate}[nosep,label=(\arabic{*})] +\item \meaning\myselfelta +\item \meaning\myselfeltb +\item \meaning\myselfeltc +\end{enumerate} \end{everbatim*} -\begin{everbatim*} -\def\ratio #1{-1/#1[0]}% -1/n, comes from the series of exp(-1) -\cnta 0 % previously declared count -\begin{quote} -\loop -\fdef\z {\xintRationalSeries {0}{\cnta}{1}{\ratio }}% -\noindent$\sum_{n=0}^{\the\cnta} \frac{(-1)^n}{n!}= - \xintTrunc{20}\z\dots=\xintFrac{\z}=\xintFrac{\xintIrr\z}$% - \vtop to 5pt{}\par -\ifnum\cnta<20 \advance\cnta 1 \repeat -\end{quote} -\end{everbatim*} +% +The macro \csa{xintApplyUnbracedNoExpand}\etype{fn} does the same job without +the first initial expansion which gave the \meta{list} of braced tokens to which +|\macro| is applied. +\subsection{\csh{xintSeq}}\label{xintSeq} - \def\ratioexp #1#2{\xintDiv{#1}{#2}}% #1/#2 +\csa{xintSeq}|[d]{x}{y}|\etype{{{\upshape[\numx]}}\numx\numx} generates +expandably |{x}{x+d}...| up to and possibly including |{y}| if |d>0| or down +to and including |{y}| if |d<0|. Naturally |{y}| is omitted if |y-x| is not a +multiple of |d|. If |d=0| the macro returns |{x}|. If |y-x| and |d| have +opposite signs, the macro returns nothing. If the optional argument |d| is +omitted it is taken to be the sign of |y-x|. Hence |\xintSeq {1}{0}| is not +empty but |{1}{0}|. But |\xintSeq [1]{1}{0}| is empty. + + +The arguments |x| and |y| are expanded inside a |\numexpr| so they may be +count registers or a \LaTeX{} |\value{countername}|, or arithmetic with such +things. -\medskip We can incorporate an indeterminate if we define |\ratio| to be -a macro with two parameters: |\def\ratioexp - #1#2{\xintDiv{#1}{#2}}|\texttt{\%}| x/n: x=#1, n=#2|. -Then, if |\x| expands to some fraction |x|, the -macro % % -\leftedline{|\xintRationalSeries {0}{b}{1}{\ratioexp{\x}}|} -will compute $\sum_{n=0}^{n=b} x^n/n!$:\par \begin{everbatim*} -\cnta 0 -\def\ratioexp #1#2{\xintDiv{#1}{#2}}% #1/#2 -\loop -\noindent -$\sum_{n=0}^{\the\cnta} (.57)^n/n! = \xintTrunc {50} - {\xintRationalSeries {0}{\cnta}{1}{\ratioexp{.57}}}\dots$ - \vtop to 5pt {}\endgraf -\ifnum\cnta<50 \advance\cnta 10 \repeat +\xintListWithSep{,\hskip2pt plus 1pt minus 1pt }{\xintSeq {12}{-25}} \end{everbatim*} - -Observe that in this last example the |x| was directly inserted; if it -had been a more complicated explicit fraction it would have been -worthwile to use |\ratioexp\x| with |\x| defined to expand to its value. -In the further situation where this fraction |x| is not explicit but -itself defined via a complicated, and time-costly, formula, it should be -noted that \csa{xintRationalSeries} will do again the evaluation of |\x| -for each term of the partial sum. The easiest is thus when |x| can be -defined as an |\edef|. If however, you are in an expandable-only context -and cannot store in a macro like |\x| the value to be used, a variant of -\csa{xintRationalSeries} is needed which will first evaluate this |\x| and then -use this result without recomputing it. This is \csbxint{RationalSeriesX}, -documented next. - -Here is a slightly more complicated evaluation: +% \begin{everbatim*} -\cnta 1 -\begin{multicols}{2} -\loop \fdef\z {\xintRationalSeries - {\cnta} - {2*\cnta-1} - {\xintiiPow {\the\cnta}{\cnta}/\xintiiFac{\cnta}} - {\ratioexp{\the\cnta}}}% -\fdef\w {\xintRationalSeries {0}{2*\cnta-1}{1}{\ratioexp{\the\cnta}}}% -\noindent -$\sum_{n=\the\cnta}^{\the\numexpr 2*\cnta-1\relax} \frac{\the\cnta^n}{n!}/% - \sum_{n=0}^{\the\numexpr 2*\cnta-1\relax} \frac{\the\cnta^n}{n!} = - \xintTrunc{8}{\xintDiv\z\w}\dots$ \vtop to 5pt{}\endgraf -\ifnum\cnta<20 \advance\cnta 1 \repeat -\end{multicols} +\xintiiSum{\xintSeq [3]{1}{1000}} \end{everbatim*} +When the macro is used without the optional argument |d|, it can only generate +up to about $5000$ numbers\IMPORTANT, the precise value depends upon some +\TeX{} memory parameter (input save stack). -\subsection{\csh{xintRationalSeriesX}}\label{xintRationalSeriesX} +With the optional argument |d| the macro proceeds differently (but less +efficiently) and does not stress the input save stack. -\noindent\csa{xintRationalSeriesX}|{A}{B}{\first}{\ratio}{\g}|% -\etype{\numx\numx\Ff\Ff f} is a parametrized version of \csa{xintRationalSeries} -where |\first| is now a one-parameter macro such that |\first{\g}| gives the -initial term and |\ratio| is a two-parameter macro such that |\ratio{n}{\g}| -represents the ratio of one term to the previous one. The parameter |\g| is -evaluated only once at the beginning of the computation, and can thus itself be -the yet unevaluated result of a previous computation. -Let |\ratio| be such a two-parameter macro; note the subtle differences -between% -% -\leftedline{|\xintRationalSeries {A}{B}{\first}{\ratio{\g}}|} -% -\leftedline{and |\xintRationalSeriesX {A}{B}{\first}{\ratio}{\g}|.} First the -location of braces differ... then, in the former case |\first| is a -\emph{no-parameter} macro expanding to a fractional number, and in the latter, -it is a -\emph{one-parameter} macro which will use |\g|. Furthermore the |X| variant -will expand |\g| at the very beginning whereas the former non-|X| former variant -will evaluate it each time it needs it (which is bad if this -evaluation is time-costly, but good if |\g| is a big explicit fraction -encapsulated in a macro). +\subsection{\csh{xintloop}, \csh{xintbreakloop}, \csh{xintbreakloopanddo}, \csh{xintloopskiptonext}} +\label{xintloop} +\label{xintbreakloop} +\label{xintbreakloopanddo} +\label{xintloopskiptonext} -The example will use the macro \csbxint{PowerSeries} which computes -efficiently exact partial sums of power series, and is discussed in the -next section. -\begin{everbatim*} -\def\firstterm #1{1[0]}% first term of the exponential series -% although it is the constant 1, here it must be defined as a -% one-parameter macro. Next comes the ratio function for exp: -\def\ratioexp #1#2{\xintDiv {#1}{#2}}% x/n -% These are the (-1)^{n-1}/n of the log(1+h) series: -\def\coefflog #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]}% -% Let L(h) be the first 10 terms of the log(1+h) series and -% let E(t) be the first 10 terms of the exp(t) series. -% The following computes E(L(a/10)) for a=1,...,12. -\begin{multicols}{3}\raggedcolumns -\cnta 0 -\loop -\noindent\xintTrunc {18}{% - \xintRationalSeriesX {0}{9}{\firstterm}{\ratioexp} - {\xintPowerSeries{1}{10}{\coefflog}{\the\cnta[-1]}}}\dots -\endgraf -\ifnum\cnta < 12 \advance \cnta 1 \repeat -\end{multicols} -\end{everbatim*} +|\xintloop|\meta{stuff}|\if...\repeat|\retype{} is an expandable loop +compatible with nesting. However to break out of the loop one almost always need +some un-expandable step. The cousin \csbxint{iloop} is \csbxint{loop} with an +embedded expandable mechanism allowing to exit from the loop. The iterated +macros may contain |\par| tokens or empty lines. +If a sub-loop is to be used all the material from the start of the main loop and +up to the end of the entire subloop should be braced; these braces will be +removed and do not create a group. The simplest to allow the nesting of one or +more sub-loops is to brace everything between \csa{xintloop} and \csa{repeat}, +being careful not to leave a space between the closing brace and |\repeat|. -These completely exact operations rapidly create numbers with many digits. Let -us print in full the raw fractions created by the operation illustrated above: +As this loop and \csbxint{iloop} will primarily be of interest to experienced +\TeX{} macro programmers, my description will assume that the user is +knowledgeable enough. Some examples in this document will be perhaps more +illustrative than my attemps at explanation of use. -\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} -{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1[-1]}}} +One can abort the loop with \csbxint{breakloop}; this should not be used inside +the final test, and one should expand the |\fi| from the corresponding test +before. One has also \csbxint{breakloopanddo} whose first argument will be +inserted in the token stream after the loop; one may need a macro such as +|\xint_afterfi| to move the whole thing after the |\fi|, as a simple +|\expandafter| will not be enough. -|E(L(1[-1]))=|\dtt{\printnumber{\z}} (length of numerator: -\xintLen {\xintNumerator \z}) +One will usually employ some count registers to manage the exit test from the +loop; this breaks expandability, see \csbxint{iloop} for an expandable integer +indexed loop. Use in alignments will be complicated by the fact that cells +create groups, and also from the fact that any encountered unexpandable material +will cause the \TeX{} input scanner to insert |\endtemplate| on each encountered +|&| or |\cr|; thus |\xintbreakloop| may not work as expected, but the situation +can be resolved via |\xint_firstofone{&}| or use of |\TAB| with |\def\TAB{&}|. +It is thus simpler for alignments to use rather than \csbxint{loop} either the +expandable \csbxint{ApplyUnbraced} or the non-expandable but alignment +compatible \csbxint{ApplyInline}, \csbxint{For} or \csbxint{For*}. -\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} -{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{12[-2]}}} +As an example, let us suppose we have two macros |\A|\marg{i}\marg{j} and +|\B|\marg{i}\marg{j} behaving like (small) integer valued matrix entries, and we +want to define a macro |\C|\marg{i}\marg{j} giving the matrix product (|i| and +|j| may be count registers). We will assume that |\A[I]| expands to the number +of rows, |\A[J]| to the number of columns and want the produced |\C| to act in +the same manner. The code is very dispendious in use of |\count| registers, not +optimized in any way, not made very robust (the defined macro can not have the +same name as the first two matrices for example), we just wanted to quickly +illustrate use of the nesting capabilities of |\xintloop|.% +% +\footnote{for a more sophisticated implementation of matrix + multiplication, inclusive of determinants, inverses, and display + utilities, with entries big integers or decimal numbers or even + fractions see some code online posted + from + November 11, 2013.} +% -|E(L(12[-2]))=|\dtt{\printnumber{\z}} (length of numerator: -\xintLen {\xintNumerator \z}) -\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} -{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{123[-3]}}} +\begin{everbatim*} +\newcount\rowmax \newcount\colmax \newcount\summax +\newcount\rowindex \newcount\colindex \newcount\sumindex +\newcount\tmpcount +\makeatletter +\def\MatrixMultiplication #1#2#3{% + \rowmax #1[I]\relax + \colmax #2[J]\relax + \summax #1[J]\relax + \rowindex 1 + \xintloop % loop over row index i + {\colindex 1 + \xintloop % loop over col index k + {\tmpcount 0 + \sumindex 1 + \xintloop % loop over intermediate index j + \advance\tmpcount \numexpr #1\rowindex\sumindex*#2\sumindex\colindex\relax + \ifnum\sumindex<\summax + \advance\sumindex 1 + \repeat }% + \expandafter\edef\csname\string#3{\the\rowindex.\the\colindex}\endcsname + {\the\tmpcount}% + \ifnum\colindex<\colmax + \advance\colindex 1 + \repeat }% + \ifnum\rowindex<\rowmax + \advance\rowindex 1 + \repeat + \expandafter\edef\csname\string#3{I}\endcsname{\the\rowmax}% + \expandafter\edef\csname\string#3{J}\endcsname{\the\colmax}% + \def #3##1{\ifx[##1\expandafter\Matrix@helper@size + \else\expandafter\Matrix@helper@entry\fi #3{##1}}% +}% +\def\Matrix@helper@size #1#2#3]{\csname\string#1{#3}\endcsname }% +\def\Matrix@helper@entry #1#2#3% + {\csname\string#1{\the\numexpr#2.\the\numexpr#3}\endcsname }% +\def\A #1{\ifx[#1\expandafter\A@size + \else\expandafter\A@entry\fi {#1}}% +\def\A@size #1#2]{\ifx I#23\else4\fi}% 3rows, 4columns +\def\A@entry #1#2{\the\numexpr #1+#2-1\relax}% not pre-computed... +\def\B #1{\ifx[#1\expandafter\B@size + \else\expandafter\B@entry\fi {#1}}% +\def\B@size #1#2]{\ifx I#24\else3\fi}% 4rows, 3columns +\def\B@entry #1#2{\the\numexpr #1-#2\relax}% not pre-computed... +\makeatother +\MatrixMultiplication\A\B\C \MatrixMultiplication\C\C\D +\MatrixMultiplication\C\D\E \MatrixMultiplication\C\E\F +\begin{multicols}2 + \[\begin{pmatrix} + \A11&\A12&\A13&\A14\\ + \A21&\A22&\A23&\A24\\ + \A31&\A32&\A33&\A34 + \end{pmatrix} + \times + \begin{pmatrix} + \B11&\B12&\B13\\ + \B21&\B22&\B23\\ + \B31&\B32&\B33\\ + \B41&\B42&\B43 + \end{pmatrix} + = + \begin{pmatrix} + \C11&\C12&\C13\\ + \C21&\C22&\C23\\ + \C31&\C32&\C33 + \end{pmatrix}\] + \[\begin{pmatrix} + \C11&\C12&\C13\\ + \C21&\C22&\C23\\ + \C31&\C32&\C33 + \end{pmatrix}^2 = \begin{pmatrix} + \D11&\D12&\D13\\ + \D21&\D22&\D23\\ + \D31&\D32&\D33 + \end{pmatrix}\] + \[\begin{pmatrix} + \C11&\C12&\C13\\ + \C21&\C22&\C23\\ + \C31&\C32&\C33 + \end{pmatrix}^3 = \begin{pmatrix} + \E11&\E12&\E13\\ + \E21&\E22&\E23\\ + \E31&\E32&\E33 + \end{pmatrix}\] + \[\begin{pmatrix} + \C11&\C12&\C13\\ + \C21&\C22&\C23\\ + \C31&\C32&\C33 + \end{pmatrix}^4 = \begin{pmatrix} + \F11&\F12&\F13\\ + \F21&\F22&\F23\\ + \F31&\F32&\F33 + \end{pmatrix}\] +\end{multicols} +\end{everbatim*} -|E(L(123[-3]))=|\dtt{\printnumber{\z}} (length of numerator: -\xintLen {\xintNumerator \z}) -We see that the denominators here remain the same, as our input only had various -powers of ten as denominators, and \xintfracname efficiently assemble (some -only, as we can see) powers of ten. Notice that 1 more digit in an input -denominator seems to mean 90 more in the raw output. We can check that with some -other test cases: +\subsection{\csh{xintiloop}, \csh{xintiloopindex}, \csh{xintouteriloopindex}, + \csh{xintbreakiloop}, \csh{xintbreakiloopanddo}, \csh{xintiloopskiptonext}, +\csh{xintiloopskipandredo}} +\label{xintiloop} +\label{xintbreakiloop} +\label{xintbreakiloopanddo} +\label{xintiloopskiptonext} +\label{xintiloopskipandredo} +\label{xintiloopindex} +\label{xintouteriloopindex} + +\csa{xintiloop}|[start+delta]|\meta{stuff}|\if ... \repeat|\retype{} is a +completely expandable nestable loop. complete expandability depends naturally on +the actual iterated contents, and complete expansion will not be achievable +under a sole \fexpan sion, as is indicated by the hollow star in the margin; +thus the loop can be used inside an |\edef| but not inside arguments to the +package macros. It can be used inside an |\xintexpr..\relax|. The +|[start+delta]| is mandatory, not optional. -\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} -{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/7}}} +This loop benefits via \csbxint{iloopindex} to (a limited access to) the integer +index of the iteration. The starting value |start| (which may be a |\count|) and +increment |delta| (\emph{id.}) are mandatory arguments. A space after the +closing square bracket is not significant, it will be ignored. Spaces inside the +square brackets will also be ignored as the two arguments are first given to a +|\numexpr...\relax|. Empty lines and explicit |\par| tokens are accepted. -|E(L(1/7))=|\dtt{\printnumber{\z}} (length of numerator: -\xintLen {\xintNumerator \z}; length of denominator: -\xintLen {\xintDenominator \z}) +As with \csbxint{loop}, this tool will mostly be of interest to advanced users. +For nesting, one puts inside braces all the +material from the start (immediately after |[start+delta]|) and up to and +inclusive of the inner loop, these braces will be removed and do not create a +loop. In case of nesting, \csbxint{outeriloopindex} gives access to the index of +the outer loop. If needed one could write on its model a macro giving access to +the index of the outer outer loop (or even to the |nth| outer loop). -\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} -{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/71}}} +The \csa{xintiloopindex} and \csa{xintouteriloopindex} can not be used inside +braces, and generally speaking this means they should be expanded first when +given as argument to a macro, and that this macro receives them as delimited +arguments, not braced ones. Or, but naturally this will break expandability, one +can assign the value of \csa{xintiloopindex} to some |\count|. Both +\csa{xintiloopindex} and \csa{xintouteriloopindex} extend to the litteral +representation of the index, thus in |\ifnum| tests, if it comes last one has to +correctly end the macro with a |\space|, or encapsulate it in a +|\numexpr..\relax|. -|E(L(1/71))=|\dtt{\printnumber{\z}} (length of numerator: -\xintLen {\xintNumerator \z}; length of denominator: -\xintLen {\xintDenominator \z}) +When the repeat-test of the loop is, for example, |\ifnum\xintiloopindex<10 +\repeat|, this means that the last iteration will be with |\xintiloopindex=10| +(assuming |delta=1|). There is also |\ifnum\xintiloopindex=10 \else\repeat| to +get the last iteration to be the one with |\xintiloopindex=10|. -\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} -{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/712}}} +One has \csbxint{breakiloop} and \csbxint{breakiloopanddo} to abort the loop. +The syntax of |\xintbreakiloopanddo| is a bit surprising, the sequence of tokens +to be executed after breaking the loop is not within braces but is delimited by +a dot as in: +% +\leftedline{|\xintbreakiloopanddo .etc.. etc... \repeat|} +% +The reason is that one may wish to use the then current value of +|\xintiloopindex| in || but it can't be within braces at the time it +is evaluated. However, it is not that easy as |\xintiloopindex| must be expanded +before, so one ends up with code like this: +% +\leftedline +{|\expandafter\xintbreakiloopanddo\expandafter\macro\xintiloopindex.%|} +% +\leftedline{|etc.. etc.. \repeat|} +% +As moreover the |\fi| from the test leading to the decision of breaking out of +the loop must be cleared out of the way, the above should be +a branch of an expandable conditional test, else one needs something such +as: +% +\leftedline +{|\xint_afterfi{\expandafter\xintbreakiloopanddo\expandafter\macro\xintiloopindex.}%|} +% +\leftedline{|\fi etc..etc.. \repeat|} -|E(L(1/712))=|\dtt{\printnumber{\z}} (length of numerator: -\xintLen {\xintNumerator \z}; length of denominator: -\xintLen {\xintDenominator \z}) +There is \csbxint{iloopskiptonext} to abort the current iteration and skip to +the next, \hyperref[xintiloopskipandredo]{\ttfamily\hyphenchar\font45 \char92 + xintiloopskip\-and\-redo} to skip to the end of the current iteration and redo +it with the same value of the index (something else will have to change for this +not to become an eternal loop\dots ). +Inside alignments, if the looped-over text contains a |&| or a |\cr|, any +un-expandable material before a \csbxint{iloopindex} will make it fail because +of |\endtemplate|; in such cases one can always either replace |&| by a macro +expanding to it or replace it by a suitable |\firstofone{&}|, and similarly for +|\cr|. -Thus -decimal numbers such as |0.123| (equivalently -|123[-3]|) give less computing intensive tasks than fractions such as |1/712|: -in the case of decimal numbers the (raw) denominators originate in the -coefficients of the series themselves, powers of ten of the input within -brackets being treated separately. And even then the -numerators will grow with the size of the input in a sort of linear way, the -coefficient being given by the order of series: here 10 from the log and 9 from -the exp, so 90. One more digit in the input means 90 more digits in the -numerator of the output: obviously we can not go on composing such partial sums -of series and hope that \xintname will joyfully do all at the speed of light! +\phantomsection\label{edefprimes} +As an example, let us construct an |\edef\z{...}| which will define |\z| to be a +list of prime numbers: +\begin{everbatim*} +\begingroup +\edef\z +{\xintiloop [10001+2] + {\xintiloop [3+2] + \ifnum\xintouteriloopindex<\numexpr\xintiloopindex*\xintiloopindex\relax + \xintouteriloopindex, + \expandafter\xintbreakiloop + \fi + \ifnum\xintouteriloopindex=\numexpr + (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax + \else + \repeat + }% no space here + \ifnum \xintiloopindex < 10999 \repeat }% +\meaning\z\endgroup +\end{everbatim*}and we should have taken +some steps to not have a trailing comma, but +the point was to show that one can do that in an |\edef|\,! See also +\autoref{ssec:primesII} which extracts from this code its way of testing +primality. -Hence, truncating the output (or better, rounding) is the only way to go if one -needs a general calculus of special functions. This is why the package -\xintseriesname provides, besides \csbxint{Series}, \csbxint{RationalSeries}, or -\csbxint{PowerSeries} which compute \emph{exact} sums, -\csbxint{FxPtPowerSeries} for fixed-point computations and a (tentative naive) -\csbxint{FloatPowerSeries}. +Let us create an alignment where each row will contain all divisors of its +first entry. +Here is the output, thus obtained without any count register: +\begin{everbatim*} +\begin{multicols}2 +\tabskip1ex \normalcolor +\halign{&\hfil#\hfil\cr + \xintiloop [1+1] + {\expandafter\bfseries\xintiloopindex & + \xintiloop [1+1] + \ifnum\xintouteriloopindex=\numexpr + (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax + \xintiloopindex&\fi + \ifnum\xintiloopindex<\xintouteriloopindex\space % CRUCIAL \space HERE + \repeat \cr }% + \ifnum\xintiloopindex<30 + \repeat +} +\end{multicols} +\end{everbatim*} +We wanted this first entry in bold face, but |\bfseries| leads to +unexpandable tokens, so the |\expandafter| was necessary for |\xintiloopindex| +and |\xintouteriloopindex| not to be confronted with a hard to digest +|\endtemplate|. An alternative way of coding: +% +\begin{everbatim} +\tabskip1ex +\def\firstofone #1{#1}% +\halign{&\hfil#\hfil\cr + \xintiloop [1+1] + {\bfseries\xintiloopindex\firstofone{&}% + \xintiloop [1+1] \ifnum\xintouteriloopindex=\numexpr + (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax + \xintiloopindex\firstofone{&}\fi + \ifnum\xintiloopindex<\xintouteriloopindex\space % \space is CRUCIAL + \repeat \firstofone{\cr}}% + \ifnum\xintiloopindex<30 \repeat } +\end{everbatim} -\subsection{\csh{xintPowerSeries}}\label{xintPowerSeries} +\begin{framed} + The next utilities are not compatible with expansion-only context. +\end{framed} -\csa{xintPowerSeries}|{A}{B}{\coeff}{f}|\etype{\numx\numx\Ff\Ff} -evaluates the sum -$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot |f|^{\text{|n|}}$. The -initial and final indices are given to a |\numexpr| expression. The |\coeff| -macro (which, as argument to \csa{xintPowerSeries} is expanded only at the time -|\coeff{n}| is needed) should be defined as a one-parameter expandable macro, -its input will be an explicit number. +\subsection{\csh{xintApplyInline}}\label{xintApplyInline} -The |f| can be either a fraction directly input or a macro |\f| expanding to -such a fraction. It is actually more efficient to encapsulate an explicit -fraction |f| in such a macro, if it has big numerators and denominators (`big' -means hundreds of digits) as it will then take less space in the processing -until being (repeatedly) used. -This macro computes the \emph{exact} result (one can use it also for -polynomial evaluation), using a Horner scheme which helps avoiding a -denominator build-up (this problem however, even if using a naive additive -approach, is much less acute since release |1.1| and its new policy regarding -\csbxint{Add}). +\csa{xintApplyInline}|{\macro}|\marg{list}\ntype{o{\lowast f}} works non +expandably. It applies the one-parameter |\macro| to the first element of the +expanded list (|\macro| may have itself some arguments, the list item will be +appended as last argument), and is then re-inserted in the input stream after +the tokens resulting from this first expansion of |\macro|. The next item is +then handled. -\begin{everbatim*} -\def\geom #1{1[0]} % the geometric series -\def\f {5/17[0]} -\[ \sum_{n=0}^{n=20} \Bigl(\frac 5{17}\Bigr)^n - =\xintFrac{\xintIrr{\xintPowerSeries {0}{20}{\geom}{\f}}} - =\xintFrac{\xinttheexpr (17^21-5^21)/12/17^20\relax}\] -\end{everbatim*} +This is to be used in situations where one needs to do some repetitive +things. It is not expandable and can not be completely expanded inside a +macro definition, to prepare material for later execution, contrarily to what +\csbxint{Apply} or \csbxint{ApplyUnbraced} achieve. \begin{everbatim*} -\def\coefflog #1{1/#1[0]}% 1/n -\def\f {1/2[0]}% -\[ \log 2 \approx \sum_{n=1}^{20} \frac1{n\cdot 2^n} - = \xintFrac {\xintIrr {\xintPowerSeries {1}{20}{\coefflog}{\f}}}\] -\[ \log 2 \approx \sum_{n=1}^{50} \frac1{n\cdot 2^n} - = \xintFrac {\xintIrr {\xintPowerSeries {1}{50}{\coefflog}{\f}}}\] +\def\Macro #1{\advance\cnta #1 , \the\cnta} +\cnta 0 +0\xintApplyInline\Macro {3141592653}. \end{everbatim*} +The first argument |\macro| does not have to be an expandable macro. +\csa{xintApplyInline} submits its second, token list parameter to an +\hyperref[ssec:expansions]{\fexpan +sion}. Then, each \emph{unbraced} item will also be \fexpan ded. This provides +an easy way to insert one list inside another. \emph{Braced} items are not +expanded. Spaces in-between items are gobbled (as well as those at the start +or the end of the list), but not the spaces \emph{inside} the braced items. +\csa{xintApplyInline}, despite being non-expandable, does survive to +contexts where the executed |\macro| closes groups, as happens inside +alignments with the tabulation character |&|. +This tabular provides an example:\par \begin{everbatim*} -\setlength{\columnsep}{0pt} -\begin{multicols}{3} -\cnta 1 % previously declared count -\loop % in this loop we recompute from scratch each partial sum! -% we can afford that, as \xintPowerSeries is fast enough. -\noindent\hbox to 2em{\hfil\texttt{\the\cnta.} }% - \xintTrunc {12} - {\xintPowerSeries {1}{\cnta}{\coefflog}{\f}}\dots -\endgraf -\ifnum \cnta < 30 \advance\cnta 1 \repeat -\end{multicols} +\centerline{\normalcolor\begin{tabular}{ccc} + $N$ & $N^2$ & $N^3$ \\ \hline + \def\Row #1{ #1 & \xintiiSqr {#1} & \xintiiPow {#1}{3} \\ \hline }% + \xintApplyInline \Row {\xintCSVtoList{17,28,39,50,61}} +\end{tabular}}\medskip \end{everbatim*} +We see that despite the fact that the first encountered tabulation character in +the first row close a group and thus erases |\Row| from \TeX's memory, +|\xintApplyInline| knows how to deal with this. + +Using \csbxint{ApplyUnbraced} is an alternative: the difference is that +this would have prepared all rows first and only put them back into the +token stream once they are all assembled, whereas with |\xintApplyInline| +each row is constructed and immediately fed back into the token stream: when +one does things with numbers having hundreds of digits, one learns that +keeping on hold and shuffling around hundreds of tokens has an impact on +\TeX{}'s speed (make this ``thousands of tokens'' for the impact to be +noticeable). +One may nest various |\xintApplyInline|'s. For example (see the +\hyperref[float]{table} \vpageref{float}):\par \begin{everbatim*} -\def\coeffarctg #1{1/\the\numexpr\ifodd #1 -2*#1-1\else2*#1+1\fi\relax }% -% the above gives (-1)^n/(2n+1). The sign being in the denominator, -% **** no [0] should be added ****, -% else nothing is guaranteed to work (even if it could by sheer luck) -% Notice in passing this aspect of \numexpr: -% **** \numexpr -(1)\relax is ilegal !!! **** -\def\f {1/25[0]}% 1/5^2 -\[\mathrm{Arctg}(\frac15)\approx \frac15\sum_{n=0}^{15} \frac{(-1)^n}{(2n+1)25^n} -= \xintFrac{\xintIrr {\xintDiv {\xintPowerSeries {0}{15}{\coeffarctg}{\f}}{5}}}\] +\begin{figure*}[ht!] + \centering\phantomsection\label{float} + \def\Row #1{#1:\xintApplyInline {\Item {#1}}{0123456789}\\ }% + \def\Item #1#2{&\xintiiPow {#1}{#2}}% + \centeredline {\begin{tabular}{ccccccccccc} &0&1&2&3&4&5&6&7&8&9\\ \hline + \xintApplyInline \Row {0123456789} + \end{tabular}} +\end{figure*} \end{everbatim*} +One could not move the definition of |\Item| inside the tabular, +as it would get lost after the first |&|. But this +works: +\everb|@ +\begin{tabular}{ccccccccccc} + &0&1&2&3&4&5&6&7&8&9\\ \hline + \def\Row #1{#1:\xintApplyInline {&\xintiiPow {#1}}{0123456789}\\ }% + \xintApplyInline \Row {0123456789} +\end{tabular} +| -\subsection{\csh{xintPowerSeriesX}}\label{xintPowerSeriesX} +A limitation is that, contrarily to what one may have expected, the +|\macro| for an |\xintApplyInline| can not be used to define +the |\macro| for a nested sub-|\xintApplyInline|. For example, +this does not work:\par +\everb|@ + \def\Row #1{#1:\def\Item ##1{&\xintiiPow {#1}{##1}}% + \xintApplyInline \Item {0123456789}\\ }% + \xintApplyInline \Row {0123456789} % does not work +| +\noindent But see \csbxint{For}. -%{\small\hspace*{\parindent}New with release |1.04|.\par} +\subsection{\csh{xintFor}, \csh{xintFor*}}\label{xintFor}\label{xintFor*} -\noindent This is the same as \csbxint{PowerSeries}\ntype{\numx\numx\Ff\Ff} -apart -from the fact that the last parameter |f| is expanded once and for all before -being then used repeatedly. If the |f| parameter is to be an explicit big -fraction with many (dozens) digits, rather than using it directly it is slightly -better to have some macro |\g| defined to expand to the explicit fraction and -then use \csbxint{PowerSeries} with |\g|; but if |f| has not yet been evaluated -and will be the output of a complicated expansion of some |\f|, and if, due to -an expanding only context, doing |\edef\g{\f}| is no option, then -\csa{xintPowerSeriesX} should be used with |\f| as last parameter. +\csbxint{For}\ntype{on} is a new kind of for loop.\footnote{first introduced + with \xintname |1.09c| of |2013/10/09|.} Rather than using macros +for encapsulating list items, its behaviour is like a macro with parameters: +|#1|, |#2|, \dots, |#9| are used to represent the items for up to nine levels of +nested loops. Here is an example: % -\begin{everbatim*} -\def\ratioexp #1#2{\xintDiv {#1}{#2}}% x/n -% These are the (-1)^{n-1}/n of the log(1+h) series: -\def\coefflog #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]}% -% Let L(h) be the first 10 terms of the log(1+h) series and -% let E(t) be the first 10 terms of the exp(t) series. -% The following computes L(E(a/10)-1) for a=1,..., 12. -\begin{multicols}{3}\raggedcolumns -\cnta 1 -\loop -\noindent\xintTrunc {18}{% - \xintPowerSeriesX {1}{10}{\coefflog} - {\xintSub - {\xintRationalSeries {0}{9}{1[0]}{\ratioexp{\the\cnta[-1]}}} - {1}}}\dots -\endgraf -\ifnum\cnta < 12 \advance \cnta 1 \repeat -\end{multicols} -\end{everbatim*} +\everb|@ +\xintFor #9 in {1,2,3} \do {% + \xintFor #1 in {4,5,6} \do {% + \xintFor #3 in {7,8,9} \do {% + \xintFor #2 in {10,11,12} \do {% + $$#9\times#1\times#3\times#2=\xintiiPrd{{#1}{#2}{#3}{#9}}$$}}}} +| +\noindent This example illustrates that one does not have to use |#1| as the +first one: +the order is arbitrary. But each level of nesting should have its specific macro +parameter. Nine levels of nesting is presumably overkill, but I did not know +where it was reasonable to stop. |\par| tokens are accepted in both the comma +separated list and the replacement text. +\begin{framed} + \TeX nical notes: -\subsection{\csh{xintFxPtPowerSeries}}\label{xintFxPtPowerSeries} +\begin{itemize} + \item The |#1| is replaced in the iterated-over text exactly as in general + \TeX\ macros or \LaTeX\ commands. This spares the user quite a few + |\expandafter|'s or other tricks needed with loops which have the + values encapsulated in macros, like \LaTeX's |\@for| and |\@tfor|. -\csa{xintFxPtPowerSeries}|{A}{B}{\coeff}{f}{D}|\etype{\numx\numx} -computes -$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot |f|^{\,\text{|n|}}$ with each - term of the series truncated to |D| digits\etype{\Ff\Ff\numx} - after the decimal point. As - usual, |A| and |B| are completely expanded through their inclusion in a - |\numexpr| expression. Regarding |D| it will be similarly be expanded each - time it is used inside an \csa{xintTrunc}. The one-parameter macro |\coeff| - is similarly expanded at the time it is used inside the - computations. Idem for |f|. If |f| itself is some complicated macro it is - thus better to use the variant \csbxint{FxPtPowerSeriesX} which expands it - first and then uses the result of that expansion. + \item \csa{xintFor} (and \csa{xintFor*}) isn't purely expandable: one can + not use it inside an |\edef|. But it may be used, as will be shown in + examples, in some contexts such as \LaTeX's |tabular| which are usually + hostile to non-expandable loops. + + \item \csa{xintFor} (and \csa{xintFor*}) does some assignments prior to + executing each iteration of the replacement text, but it acts purely + expandably after the last iteration, hence if for example the replacement + text ends with a |\\|, the loop can be used insided a tabular and be + followed by a |\hline| without creating the dreaded ``|Misplaced + \noalign|'' error. -The current (|1.04|) implementation is: the first power |f^A| is -computed exactly, then \emph{truncated}. Then each successive power is -obtained from the previous one by multiplication by the exact value of -|f|, and truncated. And |\coeff{n}|\raisebox{.5ex}{|.|}|f^n| is obtained -from that by multiplying by |\coeff{n}| (untruncated) and then -truncating. Finally the sum is computed exactly. Apart from that -\csa{xintFxPtPowerSeries} (where |FxPt| means `fixed-point') is like -\csa{xintPowerSeries}. + \item As stated in previous item the first iteration follows some + non-expandable internal dealings. This means for example that in \LaTeX{}, + one can not inject a |\multicolumn| in the first iteration. Sometimes one + way work around this by injecting father |&\multicolumn| or |\\ + \multicolumn|. -There should be a variant for things of the type $\sum c_n \frac {f^n}{n!}$ to -avoid having to compute the factorial from scratch at each coefficient, the same -way \csa{xintFxPtPowerSeries} does not compute |f^n| from scratch at each |n|. -Perhaps in the next package release. + \item It does not create groups. -\def\coeffexp #1{1/\xintiiFac {#1}[0]}% [0] for faster parsing -\def\f {-1/2[0]}% -\newcount\cnta + \item It makes no global assignments. -\setlength{\multicolsep}{0pt} + \item The iterated replacement text may close a group which was opened even + before the start of the loop (typical example being with |&| in + alignments). +\begin{everbatim*} +\begin{tabular}{rccccc} + \hline + \xintFor #1 in {A, B, C} \do {% + #1:\xintFor #2 in {a, b, c, d, e} \do {&($ #2 \to #1 $)}\\ }% + \hline +\end{tabular} +\end{everbatim*} + + \item There is no facility provided which would give access to a count of + the number of iterations as it is technically not easy to do so it in a + way working with nested loops while maintaining the ``expandable after + done'' property; something in the spirit of \csbxint{iloopindex} is + possible but this approach would bring its own limitations and + complications. Hence the user is invited to update her own count or + \LaTeX{} counter or macro at each iteration, if needed. -\begin{multicols}{3}[% -\centeredline{$e^{-\frac12}\approx{}$}]% -\cnta 0 -\noindent\loop -$\xintFxPtPowerSeries {0}{\cnta}{\coeffexp}{\f}{20}$\\ -\ifnum\cnta<19 -\advance\cnta 1 -\repeat\par -\end{multicols} -\everb|@ -\def\coeffexp #1{1/\xintiiFac {#1}[0]}% 1/n! -\def\f {-1/2[0]}% [0] for faster input parsing -\cnta 0 % previously declared \count register -\noindent\loop -$\xintFxPtPowerSeries {0}{\cnta}{\coeffexp}{\f}{20}$\\ -\ifnum\cnta<19 \advance\cnta 1 \repeat\par -| + \item A |\macro| whose definition uses internally an \csbxint{For} loop + may be used inside another \csbxint{For} loop even if the two loops both + use the same macro parameter. The loop definition inside |\macro| + must use |##| as is the general rule for definitions done inside macros. + + \item \csbxint{For} is for comma separated values and \csbxint{For*} for + lists of braced items; their respective expansion policies differ. They + are described later. +\end{itemize} +\unskip +\end{framed} +\noindent Regarding \csbxint{For}: +\begin{itemize}[nosep, listparindent=\leftmarginiii] +\item the spaces between the various declarative elements are all optional, +\item in the list of comma separated values, spaces around the commas or at + the start and end are ignored, +\item if an item must contain itself its own commas, then it should + be braced, and the braces will be removed before feeding the iterated-over + text, +\item the list may be a macro, it is expanded only once, +\item items are not pre-expanded. The first item should be braced or start + with a space if the list is explicit and the item should not be + pre-expanded, +\item empty items give empty |#1|'s in the replacement text, they are not + skipped, +\item an empty list executes once the replacement text with an empty parameter + value, +\item the list, if not a macro, \fbox{must be braced.} +\end{itemize} -% -\leftedline{|\xintFxPtPowerSeries {0}{19}{\coeffexp}{\f}{25}=| -\dtt{\xintFxPtPowerSeries {0}{19}{\coeffexp}{\f}{25}}} -\fdef\z{\xintIrr {\xintPowerSeries {0}{19}{\coeffexp}{\f}}} -% +\noindent Regarding \csbxint{For*}:\ntype{{\lowast f}n} +\begin{itemize}[nosep, listparindent=\leftmarginiii] +\item it handles lists of braced items (or naked tokens), +\item it \hyperref[ssec:expansions]{\fexpan ds} the list, +\item and more generally it \hyperref[ssec:expansions]{\fexpan ds} each naked + token encountered + before assigning the |#1| values (gobbling spaces in the process); + this + makes it easy to simulate concatenation of multiple lists|\x|, |\y|: + if |\x| expands to |{1}{2}{3}| and |\y| expands to |{4}{5}{6}| then |{\x\y}| + as argument to |\xintFor*| has the same effect as |{{1}{2}{3}{4}{5}{6}}|. -\texttt{\hyphenchar\font45 }% -It is no difficulty for \xintfracname to compute exactly, with the help -of \csa{xintPowerSeries}, the nineteenth partial sum, and to then give -(the start of) its exact decimal expansion: -% -\leftedline{|\xintPowerSeries {0}{19}{\coeffexp}{\f}| ${}= - \displaystyle\xintFrac{\z}$% - \vphantom{\vrule height 20pt depth 12pt}}% -% -\leftedline{${}=\xintTrunc {30}{\z}\dots$} Thus, one should always -estimate a priori how many ending digits are not reliable: if there are -|N| terms and |N| has |k| digits, then digits up to but excluding the -last |k| may usually be trusted. If we are optimistic and the series is -alternating we may even replace |N| with $\sqrt{|N|}$ to get the number |k| -of digits possibly of dubious significance. + For a further illustration see the use of |\xintFor*| at the end of + \autoref{ssec:fibonacci}. +\item spaces at the start, end, or in-between items are gobbled (but naturally + not the spaces inside \emph{braced} items), +\item except if the list argument is a macro (with no parameters), \fbox{it + must be braced.}, +\item an empty list leads to an empty result. +\end{itemize} + +The macro \csbxint{Seq} which generates arithmetic sequences is to be used +with \csbxint{For*} as its output consists of successive braced numbers (given +as digit tokens). +\begin{everbatim*} +\xintFor* #1 in {\xintSeq [+2]{-7}{+2}}\do {stuff + with #1\xintifForLast{\par}{\newline}} +\end{everbatim*} -\subsection{\csh{xintFxPtPowerSeriesX}}\label{xintFxPtPowerSeriesX} +When nesting \csa{xintFor*} loops, using \csa{xintSeq} in the inner loops is +inefficient, as the arithmetic sequence will be re-created each time. A more +efficient style is: +% +\begin{everbatim} + \edef\innersequence {\xintSeq[+2]{-50}{50}}% + \xintFor* #1 in {\xintSeq {13}{27}} \do + {\xintFor* #2 in \innersequence \do {stuff with #1 and #2}% + .. some other macros .. } +\end{everbatim} -\noindent\csa{xintFxPtPowerSeriesX}|{A}{B}{\coeff}{\f}{D}|% -\ntype{\numx\numx} -computes, exactly as -\csa{xintFxPtPowerSeries}, the sum of -|\coeff{n}|\raisebox{.5ex}{|.|}|\f^n|\etype{\Ff\Ff\numx} from |n=A| to |n=B| with each term -of the series being \emph{truncated} to |D| digits after the decimal -point. The sole difference is that |\f| is first expanded and it -is the result of this which is used in the computations. +This is a general remark applying for any nesting of loops, one should avoid +recreating the inner lists of arguments at each iteration of the outer loop. -Let us illustrate this on the numerical exploration of the identity +When the loop is defined inside a macro for later execution the |#| characters +must be doubled.% % -\leftedline{|log(1+x) = -log(1/(1+x))|} +\footnote{sometimes what seems to be a macro argument isn't really; in + \csa{raisebox\{1cm\}\{}\csa{xintFor \#1 in \{a,b,c\} }\csa{do + \{\#1\}\}} no doubling should be done.} +% +For example: % -Let |L(h)=log(1+h)|, and |D(h)=L(h)+L(-h/(1+h))|. Theoretically thus, -|D(h)=0| but we shall evaluate |L(h)| and |-h/(1+h)| keeping only 10 -terms of their respective series. We will assume $|h|<0.5$. With only -ten terms kept in the power series we do not have quite 3 digits -precision as $2^{10}=1024$. So it wouldn't make sense to evaluate things -more precisely than, say circa 5 digits after the decimal points. \begin{everbatim*} -\cnta 0 -\def\coefflog #1{\the\numexpr\ifodd#1 1\else-1\fi\relax/#1[0]}% (-1)^{n-1}/n -\def\coeffalt #1{\the\numexpr\ifodd#1 -1\else1\fi\relax [0]}% (-1)^n -\begin{multicols}2 -\loop -\noindent \hbox to 2.5cm {\hss\texttt{D(\the\cnta/100): }}% -\xintAdd {\xintFxPtPowerSeriesX {1}{10}{\coefflog}{\the\cnta [-2]}{5}} - {\xintFxPtPowerSeriesX {1}{10}{\coefflog} - {\xintFxPtPowerSeriesX {1}{10}{\coeffalt}{\the\cnta [-2]}{5}} - {5}}\endgraf -\ifnum\cnta < 49 \advance\cnta 7 \repeat -\end{multicols} +\def\T{\def\z {}% + \xintFor* ##1 in {{u}{v}{w}} \do {% + \xintFor ##2 in {x,y,z} \do {% + \expandafter\def\expandafter\z\expandafter {\z\sep (##1,##2)} }% + }% +}% +\T\def\sep {\def\sep{, }}\z \end{everbatim*} +Similarly when the replacement text +of |\xintFor| defines a macro with parameters, the macro character |#| must be +doubled. -Let's say we evaluate functions on |[-1/2,+1/2]| with values more or less also -in |[-1/2,+1/2]| and we want to keep 4 digits of precision. So, roughly we need -at least 14 terms in series like the geometric or log series. Let's make this -15. Then it doesn't make sense to compute intermediate summands with more than 6 -digits precision. So we compute with 6 digits -precision but return only 4 digits (rounded) after the decimal point. -This result with 4 post-decimal points precision is then used as input -to the next evaluation. -\begin{everbatim*} -\begin{multicols}2 -\loop -\noindent \hbox to 2.5cm {\hss\texttt{D(\the\cnta/100): }}% -\dtt{\xintRound{4} - {\xintAdd {\xintFxPtPowerSeriesX {1}{15}{\coefflog}{\the\cnta [-2]}{6}} - {\xintFxPtPowerSeriesX {1}{15}{\coefflog} - {\xintRound {4}{\xintFxPtPowerSeriesX {1}{15}{\coeffalt} - {\the\cnta [-2]}{6}}} - {6}}% - }}\endgraf -\ifnum\cnta < 49 \advance\cnta 7 \repeat -\end{multicols} -\end{everbatim*} -Not bad... I have cheated a bit: the `four-digits precise' numeric -evaluations were left unrounded in the final addition. However the inner -rounding to four digits worked fine and made the next step faster than -it would have been with longer inputs. The morale is that one should not -use the raw results of \csa{xintFxPtPowerSeriesX} with the |D| digits -with which it was computed, as the last are to be considered garbage. -Rather, one should keep from the output only some smaller number of -digits. This will make further computations faster and not less precise. -I guess there should be some macro to do this final truncating, or -better, rounding, at a given number |D'\relax|, +and the litteral representation as a string of digits can thus be obtained as +\fbox{\csa{the\#1}} or |\number#1|. Such a |#1| can be used in an |\ifnum| test +with no need to be postfixed with a space or a |\relax| and one should +\emph{not} add them. -% 693147180559945309417232121458176568075500134360255254120680009493 +If the list argument is \csbxint{dimensions} or more generally +\csbxint{dimensions}|[||start|\allowbreak|+|\allowbreak|delta||]| (\emph{within + braces}!), then +\csbxint{For} does an infinite iteration where |#1| (or |#2|, \dots, |#9|) will +run through the arithmetic sequence of dimensions with initial value +|start| and increment |delta|. Default values: |start=0pt|, |delta=1pt|; if +the optional argument is present it must contain both of them, and they may +be explicit specifications, or macros, or dimen registers, or length macros +in \LaTeX{} (the stretch and shrink components will be discarded). The |#1| +will be |\dimexpr sp\relax|, from which one can get the +litteral (approximate) representation in points via |\the#1|. So |#1| can be +used anywhere \TeX{} expects a dimension (and there is no need in conditionals +to insert a |\relax|, and one should \emph{not} do it), and to print its value +one uses \fbox{\csa{the\#1}}. The chosen representation guarantees exact +incrementation with no rounding errors accumulating from converting into +points at each step. -\begin{everbatim*} -\def\coefflog #1{1/#1[0]}% 1/n -\def\xa {13/256[0]}% we will compute log(1-13/256) -\def\xb {1/9[0]}% we will compute log(1-1/9) -\def\LogTwo #1% -% get log(2)=-2log(1-13/256)- 5log(1-1/9) -{% we want to use \printnumber, hence need something expanding in two steps - % only, so we use here the \romannumeral0 method - \romannumeral0\expandafter\LogTwoDoIt \expandafter - % Nb Terms for 1/9: - {\the\numexpr #1*150/143\expandafter}\expandafter - % Nb Terms for 13/256: - {\the\numexpr #1*100/129\expandafter}\expandafter - % We print #1 digits, but we know the ending ones are garbage - {\the\numexpr #1\relax}% allows #1 to be a count register -}% -\def\LogTwoDoIt #1#2#3% -% #1=nb of terms for 1/9, #2=nb of terms for 13/256, -{% #3=nb of digits for computations, also used for printing - \xinttrunc {#3} % lowercase form to stop the \romannumeral0 expansion! - {\xintAdd - {\xintMul {2}{\xintFxPtPowerSeries {1}{#2}{\coefflog}{\xa}{#3}}} - {\xintMul {5}{\xintFxPtPowerSeries {1}{#1}{\coefflog}{\xb}{#3}}}% - }% -}% -\noindent $\log 2 \approx \LogTwo {60}\dots$\endgraf -\noindent\phantom{$\log 2$}${}\approx{}$\printnumber{\LogTwo {65}}\dots\endgraf -\noindent\phantom{$\log 2$}${}\approx{}$\printnumber{\LogTwo {70}}\dots\endgraf -\end{everbatim*} -Here is the code doing an exact evaluation of the partial sums. We have -added a |+1| to the number of digits for estimating the number of terms -to keep from the log series: we experimented that this gets exactly the -first |D| digits, for all values from |D=0| to |D=100|, except in one -case (|D=40|) where the last digit is wrong. For values of |D| -higher than |100| it is more efficient to use the code using -\csa{xintFxPtPowerSeries}. -\everb|@ -\def\LogTwo #1% get log(2)=-2log(1-13/256)- 5log(1-1/9) -{% - \romannumeral0\expandafter\LogTwoDoIt \expandafter - {\the\numexpr (#1+1)*150/143\expandafter}\expandafter - {\the\numexpr (#1+1)*100/129\expandafter}\expandafter - {\the\numexpr #1\relax}% -}% -\def\LogTwoDoIt #1#2#3% -{% #3=nb of digits for truncating an EXACT partial sum - \xinttrunc {#3} - {\xintAdd - {\xintMul {2}{\xintPowerSeries {1}{#2}{\coefflog}{\xa}}} - {\xintMul {5}{\xintPowerSeries {1}{#1}{\coefflog}{\xb}}}% - }% -}% -| -Let us turn now to Pi, computed with the Machin formula (but see also the -approach via the \hyperlink{BrentSalamin}{Brent-Salamin algorithm} with -\csa{xintfloatexpr}) Again the numbers of terms to keep in the two |arctg| -series were roughly estimated, and some experimentations showed that removing -the last three digits was enough (at least for |D=0-100| range). And the -algorithm does print the correct digits when used with |D=1000| (to be -convinced of that one needs to run it for |D=1000| and again, say for -|D=1010|.) A theoretical analysis could help confirm that this algorithm -always gets better than |10^{-D}| precision, but again, strings of zeroes or -nines encountered in the decimal expansion may falsify the ending digits, -nines may be zeroes (and the last non-nine one should be increased) and zeroes -may be nine (and the last non-zero one should be decreased). -\hypertarget{MachinCode}{} -\begin{everbatim*} -\def\coeffarctg #1{\the\numexpr\ifodd#1 -1\else1\fi\relax/% - \the\numexpr 2*#1+1\relax [0]}% -%\def\coeffarctg #1{\romannumeral0\xintmon{#1}/\the\numexpr 2*#1+1\relax }% -\def\xa {1/25[0]}% 1/5^2, the [0] for faster parsing -\def\xb {1/57121[0]}% 1/239^2, the [0] for faster parsing -\def\Machin #1{% #1 may be a count register, \Machin {\mycount} is allowed - \romannumeral0\expandafter\MachinA \expandafter - % number of terms for arctg(1/5): - {\the\numexpr (#1+3)*5/7\expandafter}\expandafter - % number of terms for arctg(1/239): - {\the\numexpr (#1+3)*10/45\expandafter}\expandafter - % do the computations with 3 additional digits: - {\the\numexpr #1+3\expandafter}\expandafter - % allow #1 to be a count register: - {\the\numexpr #1\relax }}% -\def\MachinA #1#2#3#4% -{\xinttrunc {#4} - {\xintSub - {\xintMul {16/5}{\xintFxPtPowerSeries {0}{#1}{\coeffarctg}{\xa}{#3}}} - {\xintMul{4/239}{\xintFxPtPowerSeries {0}{#2}{\coeffarctg}{\xb}{#3}}}% - }}% -\begin{framed} - \[ \pi = \Machin {60}\dots \] -\end{framed} -\end{everbatim*} -Here is a variant|\MachinBis|, -which evaluates the partial sums \emph{exactly} using -\csa{xintPowerSeries}, before their final truncation. No need for a -``|+3|'' then. -\begin{everbatim*} -\def\MachinBis #1{% #1 may be a count register, -% the final result will be truncated to #1 digits post decimal point - \romannumeral0\expandafter\MachinBisA \expandafter - % number of terms for arctg(1/5): - {\the\numexpr #1*5/7\expandafter}\expandafter - % number of terms for arctg(1/239): - {\the\numexpr #1*10/45\expandafter}\expandafter - % allow #1 to be a count register: - {\the\numexpr #1\relax }}% -\def\MachinBisA #1#2#3% -{\xinttrunc {#3} % - {\xintSub - {\xintMul {16/5}{\xintPowerSeries {0}{#1}{\coeffarctg}{\xa}}} - {\xintMul{4/239}{\xintPowerSeries {0}{#2}{\coeffarctg}{\xb}}}% -}}% -\end{everbatim*} -Let us use this variant for a loop showing the build-up of digits: +If the list argument to \csbxint{For} (or \csbxint{For*}) is \csbxint{rationals} +or more generally +\csbxint{rationals}|[||start|\allowbreak|+|\allowbreak|delta||]| (\emph{within + braces}!), then \csbxint{For} does an infinite iteration where |#1| (or |#2|, +\dots, |#9|) will run through the arithmetic sequence of \xintfracname fractions +with initial value |start| and increment |delta| (default values: |start=1/1|, +|delta=1/1|). This loop works \emph{only with \xintfracname loaded}. if the +optional argument is present it must contain both of them, and they may be given +in any of the formats recognized by \xintfracname (fractions, decimal +numbers, numbers in scientific notations, numerators and denominators in +scientific notation, etc...) , or as macros or count registers (if they are +short integers). The |#1| (or |#2|, \dots, |#9|) will be an |a/b| fraction +(without a |[n]| part), where +the denominator |b| is the product of the denominators of +|start| and |delta| (for reasons of speed |#1| is not reduced to irreducible +form, and for another reason explained later |start| and |delta| are not put +either into irreducible form; the input may use explicitely \csa{xintIrr} to +achieve that). \begin{everbatim*} -\begin{multicols}{2} - \cnta 0 % previously declared \count register - \loop \noindent - \centeredline{\dtt{\MachinBis{\cnta}}}% - \ifnum\cnta < 30 - \advance\cnta 1 \repeat -\end{multicols} +\begingroup\small +\noindent\parbox{\dimexpr\linewidth-3em}{\color[named]{OrangeRed}% +\xintFor #1 in {\xintrationals [10/21+1/21]} \do +{#1=\xintifInt {#1} + {\textcolor{blue}{\xintTrunc{10}{#1}}} + {\xintTrunc{10}{#1}}% display in blue if an integer + \xintifGt {#1}{1.123}{\xintBreakFor}{, }% + }} +\endgroup\smallskip \end{everbatim*} -\hypertarget{Machin1000}{} -% -You want more digits and have some time? compile this copy of the -\hyperlink{MachinCode}{|\Machin|} with |etex| (or |pdftex|): -% -\everb|@ -% Compile with e-TeX extensions enabled (etex, pdftex, ...) -\input xintfrac.sty -\input xintseries.sty -% pi = 16 Arctg(1/5) - 4 Arctg(1/239) (John Machin's formula) -\def\coeffarctg #1{\the\numexpr\ifodd#1 -1\else1\fi\relax/% - \the\numexpr 2*#1+1\relax [0]}% -\def\xa {1/25[0]}% -\def\xb {1/57121[0]}% -\def\Machin #1{% - \romannumeral0\expandafter\MachinA \expandafter - {\the\numexpr (#1+3)*5/7\expandafter}\expandafter - {\the\numexpr (#1+3)*10/45\expandafter}\expandafter - {\the\numexpr #1+3\expandafter}\expandafter - {\the\numexpr #1\relax }}% -\def\MachinA #1#2#3#4% -{\xinttrunc {#4} - {\xintSub - {\xintMul {16/5}{\xintFxPtPowerSeries {0}{#1}{\coeffarctg}{\xa}{#3}}} - {\xintMul {4/239}{\xintFxPtPowerSeries {0}{#2}{\coeffarctg}{\xb}{#3}}}% -}}% -\pdfresettimer -\fdef\Z {\Machin {1000}} -\odef\W {\the\pdfelapsedtime} -\message{\Z} -\message{computed in \xintRound {2}{\W/65536} seconds.} -\bye -| - -This will log the first 1000 digits of $\pi$ after the decimal point. On my -laptop (a 2012 model) this took about $5.05$ seconds last time I tried.% -% -\footnote{With \texttt{1.09i} and earlier \xintname, this used to be \dtt{42} - seconds; starting with \texttt{1.09j}, and prior to \texttt{1.2}, it was - \dtt{16} seconds (this was probably due to a more efficient division with - denominators at most $9999$). The |1.2| \xintcorename achieves a further - gain at \dtt{5.6} seconds.} -% -\footnote{With |\xintDigits:=1001\relax|, the non-optimized implementation with the - |iter| of \xintexprname fame using the - \hyperlink{BrentSalamin}{Brent-Salamin algorithm}, took, last time I tried - (1.2i), about \dtt{7} seconds on my laptop (the last two digits were wrong, - which is ok as they serve as guard digits), and for obtaining about - \dtt{500} digits, it was about \dtt{1.7}s. This is not bad, taking into - account that the syntax is almost free rolling speech, contrarily to the - code above for the Machin formula computation; we would like to use the - quadratically convergent Brent-Salamin algorithm for more digits, but with - such computations with numbers of one thousand digits we are beyond the - border of the reasonable range for \xintname. Innocent people not knowing - what it means to compute with \TeX, and with the extra constraint of - expandability will wonder why this is at least thousands of times slower - than with any other language (with a little Python program using the - |Decimal| library, I timed the Brent-Salamin algorithm to \dtt{4.4ms} for - about |1000| digits and \dtt{1.14ms} for |500| digits.) I will just say that - for example digits are represented and manipulated via their ascii-code ! - all computations must convert from ascii-code to cpu words; furthermore - nothing can be stored away. And there is no memory storage with |O(1)| time - access... if expandability is to be verified.} -% - - -As mentioned in the -introduction, the file \href{https://ctan.org/pkg/pi}{pi.tex} by \textsc{D. - Roegel} shows that orders of magnitude faster computations are possible within -\TeX{}, but recall our constraints of complete expandability and be merciful, -please. - -\textbf{Why truncating rather than rounding?} One of our main competitors -on the market of scientific computing, a canadian product (not -encumbered with expandability constraints, and having barely ever heard -of \TeX{} ;-), prints numbers rounded in the last digit. Why didn't we -follow suit in the macros \csa{xintFxPtPowerSeries} and -\csa{xintFxPtPowerSeriesX}? To round at |D| digits, and excluding a -rewrite or cloning of the division algorithm which anyhow would add to -it some overhead in its final steps, \xintfracname needs to truncate at -|D+1|, then round. And rounding loses information! So, with more time -spent, we obtain a worst result than the one truncated at |D+1| (one -could imagine that additions and so on, done with only |D| digits, cost -less; true, but this is a negligeable effect per summand compared to the -additional cost for this term of having been truncated at |D+1| then -rounded). Rounding is the way to go when setting up algorithms to -evaluate functions destined to be composed one after the other: exact -algebraic operations with many summands and an |f| variable which is a -fraction are costly and create an even bigger fraction; replacing |f| -with a reasonable rounding, and rounding the result, is necessary to -allow arbitrary chaining. - -But, for the -computation of a single constant, we are really interested in the exact -decimal expansion, so we truncate and compute more terms until the -earlier result gets validated. Finally if we do want the rounding we can -always do it on a value computed with |D+1| truncation. +\smallskip The example above confirms that computations are done exactly, and +illustrates that the two initial (reduced) denominators are not multiplied when +they are found to be equal. It is thus recommended to input |start| and |delta| +with a common smallest possible denominator, or as fixed point numbers with the +same numbers of digits after the decimal mark; and this is also the reason why +|start| and |delta| are not by default made irreducible. As internally the +computations are done with numerators and denominators completely expanded, one +should be careful not to input numbers in scientific notation with exponents in +the hundreds, as they will get converted into as many zeroes. -\clearpage -\let\xintseriesnameUp\undefined -\csname xintcfracnameUp\endcsname -\def\n{|{N}|} -\def\m{|{M}|} -\def\x{|{x}|} -\section{Macros of the \xintcfracname package} -\RaisedLabel{sec:cfrac} +\begin{everbatim*} +\noindent\parbox{\dimexpr.7\linewidth}{\raggedright +\xintFor #1 in {\xintrationals [0.000+0.125]} \do +{\edef\tmp{\xintTrunc{3}{#1}}% + \xintifInt {#1} + {\textcolor{blue}{\tmp}} + {\tmp}% + \xintifGt {#1}{2}{\xintBreakFor}{, }% + }}\smallskip +\end{everbatim*} -\localtableofcontents +We see here that \csbxint{Trunc} outputs (deliberately) zero as $0$, not (here) +$0.000$, the idea being not to lose the information that the truncated thing was +truly zero. Perhaps this behaviour should be changed? or made optional? Anyhow +printing of fixed points numbers should be dealt with via dedicated packages +such as |numprint| or |siunitx|.\par -First version of this package was included in release |1.04| (|2013/04/25|) of the -\xintname bundle. It was kept almost unchanged until |1.09m| of |2014/02/26| -which brought some new macros: \csbxint{FtoC}, \csbxint{CtoF}, \csbxint{CtoCv}, -dealing with sequences of braced partial quotients rather than comma separated -ones, \csbxint{FGtoC} which is to produce ``guaranteed'' coefficients of some -real number known approximately, and \csbxint{GGCFrac} for displaying arbitrary -material as a continued fraction; also, some changes to existing macros: -\csbxint{FtoCs} and \csbxint{CntoCs} insert spaces after the commas, -\csbxint{CstoF} and \csbxint{CstoCv} authorize spaces in the input also before -the commas. -Note: \csbxint{CstoF} and \csbxint{CstoCv} create a partial dependency on -\xinttoolsname (its \csbxint{CSVtoList}.) +\subsection{\csh{xintForpair}, \csh{xintForthree}, \csh{xintForfour}}\label{xintForpair}\label{xintForthree}\label{xintForfour} -This section contains: -\begin{enumerate} -\item an \hyperref[ssec:cfracoverview]{overview} of the package functionalities, -\item a description of each one of the package macros, -\item further illustration of their use via the study of the - \hyperref[ssec:e-convergents]{convergents of $e$}. -\end{enumerate} +The syntax\ntype{on} is illustrated in this +example. The notation is the usual one for |n|-uples, with parentheses and +commas. Spaces around commas and parentheses are ignored. +% +\begin{everbatim*} +{\centering\begin{tabular}{cccc} + \xintForpair #1#2 in { ( A , a ) , ( B , b ) , ( C , c ) } \do {% + \xintForpair #3#4 in { ( X , x ) , ( Y , y ) , ( Z , z ) } \do {% + $\Biggl($\begin{tabular}{cc} + -#1- & -#3-\\ + -#4- & -#2-\\ + \end{tabular}$\Biggr)$&}\\\noalign{\vskip1\jot}}% +\end{tabular}\\} +\end{everbatim*} -\subsection{Package overview}\label{ssec:cfracoverview} +\csbxint{Forpair} must be followed by either |#1#2|, |#2#3|, |#3#4|, \dots, or +|#8#9| with |#1| usable as an alias for |#1#2|, |#2| as alias for |#2#3|, +etc \dots\ and similarly for \csbxint{Forthree} (using |#1#2#3| or simply +|#1|, |#2#3#4| or simply |#2|, \dots) and \csbxint{Forfour} (with |#1#2#3#4| +etc\dots). -The package computes partial quotients and convergents of a fraction, or -conversely start from coefficients and obtain the corresponding fraction; three -macros \csbxint {CFrac}, \csbxint {GCFrac} and \csbxint {GGCFrac} are -for typesetting (the first two assume that the coefficients are numeric -quantities acceptable by the \xintfracname \csbxint{Frac} macro, the -last one will display arbitrary material), the others -can be nested (if applicable) or see their outputs further processed by other -macros from the \xintname bundle, particularly the macros of \xinttoolsname -dealing with sequences of braced items or comma separated lists. +Nesting works as long as the macro parameters are distinct among |#1|, |#2|, +..., |#9|. A macro which expands to an \csa{xintFor} or a +\csa{xintFor(pair,three,four)} can be used in another one with no constraint +about using distinct macro parameters. -A \emph{simple} continued fraction has coefficients -|[c0,c1,...,cN]| (usually called partial quotients, but I -dislike this entrenched terminology), where |c0| is a positive or -negative integer and the others are positive integers. +|\par| tokens are accepted in both the comma separated list and the +replacement text. -Typesetting is usually done via the |amsmath| macro |\cfrac|: -\begin{everbatim*} -\[ c_0 + \cfrac{1}{c_1+\cfrac1{c_2+\cfrac1{c_3+\cfrac1{\ddots}}}}\] -\end{everbatim*} -Here is a concrete example: -\begin{everbatim*} -\[ \xintFrac {208341/66317}=\xintCFrac {208341/66317}\]% -\end{everbatim*} -But it is the macro \csbxint{CFrac} which did all the work of \emph{computing} -the continued fraction \emph{and} using |\cfrac| from |amsmath| to typeset -it. +\subsection{\csh{xintAssign}}\label{xintAssign} -A \emph{generalized} continued fraction has the same structure but the -numerators are not restricted to be $1$, and numbers used in the continued -fraction may be arbitrary, also fractions, irrationals, complex, -indeterminates.% -% -\footnote{\xintcfracname may be used with indeterminates, - for basic conversions from one inline format to another, but not for - actual computations. See \csbxint{GGCFrac}.} +\csa{xintAssign}\meta{braced things}\csa{to}% +\meta{as many cs as they are things} %\ntype{{(f$\to$\lowast [x)}{\lowast N}} % -The \emph{centered} continued fraction is an -example: -\begin{everbatim*} -\[ \xintFrac {915286/188421}=\xintGCFrac {5+-1/7+1/39+-1/53+-1/13} - =\xintCFrac {915286/188421}\] -\end{everbatim*} +defines (without checking if something gets overwritten) the control sequences +on the right of \csa{to} to expand to the successive tokens or braced items +located to the left of \csa{to}. \csa{xintAssign} is not an expandable macro. -The macro \csbxint{GCFrac}, contrarily to -\csbxint{CFrac}, does not compute anything, it just typesets starting from a -generalized continued fraction in inline format, which in this example -was input literally. We also used \csa{xintCFrac} -for comparison of the two types of continued fractions. +\fexpan sion is first applied to the material in front of \csa{xintAssign} +which is fetched as one argument if it is braced. Then the expansion of this +argument is examined and successive items are assigned to the macros following +|\to|. There must be exactly as many macros as items. No check is done. The +macro assignments are done with removal of one level of brace pairs from each +item. -To let \TeX{} compute the centered continued fraction of |f| there is -\csbxint{FtoCC}: -\begin{everbatim*} -\[\xintFrac {915286/188421}\to\xintFtoCC {915286/188421}\] -\end{everbatim*} -The package macros are expandable and may be nested (naturally \csa{xintCFrac} -and \csa{xintGCFrac} must be at the top level, as they deal with typesetting). -\begin{everbatim*} -\[\xintGCFrac {\xintFtoCC{915286/188421}}\] -\end{everbatim*} +After the initial \fexpan sion, each assigned (brace-stripped) item will be +expanded according to the setting of the optional parameter. -The `inline' format expected on input by \csbxint{GCFrac} is -% -\leftedline{$a_0+b_0/a_1+b_1/a_2+b_2/a_3+\cdots+b_{n-2}/a_{n-1}+b_{n-1}/a_n$} -% -Fractions among the coefficients are allowed but they must be enclosed -within braces. Signed integers may be left without braces (but the |+| -signs are mandatory). No spaces are allowed around the plus and fraction -symbols. The coefficients may themselves be macros, as long as these -macros are \fexpan dable. -\begin{everbatim*} -\[ \xintFrac{\xintGCtoF {1+-1/57+\xintPow {-3}{7}/\xintiiQuo {132}{25}}} - = \xintGCFrac {1+-1/57+\xintPow {-3}{7}/\xintiiQuo {132}{25}}\] -\end{everbatim*} -To compute the actual fraction one has \csbxint{GCtoF}: -\begin{everbatim*} -\[\xintFrac{\xintGCtoF {1+-1/57+\xintPow {-3}{7}/\xintiiQuo {132}{25}}}\] -\end{everbatim*} -For non-numeric input there is \csbxint{GGCFrac}. -\begin{everbatim*} -\[\xintGGCFrac {a_0+b_0/a_1+b_1/a_2+b_2/\ddots+\ddots/a_{n-1}+b_{n-1}/a_n}\] -\end{everbatim*} -For regular continued fractions, there is a simpler comma separated format: -\begin{everbatim*} -\[-7,6,19,1,33\to\xintFrac{\xintCstoF{-7,6,19,1,33}}=\xintCFrac{\xintCstoF{-7,6,19,1,33}}\] -\end{everbatim*} -The macro \csbxint{FtoCs} produces from a fraction |f| the comma separated -list of its coefficients. -\begin{everbatim*} -\[\xintFrac{1084483/398959}=[\xintFtoCs{1084483/398959}]\] -\end{everbatim*} -If one prefers other separators, one can use the two arguments macros -\csbxint{FtoCx} whose first argument is the separator (which may consist of more -than one token) which is to be used. +For example |\xintAssign [e]...| means that all assignments are done using +|\edef|. With |[f]| the assignments will be made using +\hyperref[fdef]{\ttfamily\char92fdef}. The default is simply to make the +definitions with |\def|, corresponding to an empty optional paramter |[]|. +Possibilities for the optional parameter are: |[], [g], [e], [x], [o], [go], +[oo], [goo], [f], [gf]|. For example |[oo]| means a double expansion. \begin{everbatim*} -\[\xintFrac{2721/1001}=\xintFtoCx {+1/(}{2721/1001})\cdots)\] +\xintAssign \xintiiDivision{1000000000000}{133333333}\to\Q\R +\meaning\Q\newline +\meaning\R\newline +\xintAssign {{\xintiiDivision{1000000000000}{133333333}}}\to\X +\meaning\X\newline +\xintAssign [oo]{{\xintiiDivision{1000000000000}{133333333}}}\to\X +\meaning\X\newline +\xintAssign \xintiiPow{7}{13}\to\SevenToThePowerThirteen +\meaning\SevenToThePowerThirteen\par \end{everbatim*} -This allows under Plain \TeX{} with |amstex| to obtain the same effect -as with \LaTeX{}+|\amsmath|+\csbxint{CFrac}: -% -\leftedline{|$$\xintFwOver{2721/1001}=\xintFtoCx {+\cfrac1\\ }{2721/1001}\endcfrac$$|} -As a shortcut to \csa{xintFtoCx} with separator |1+/|, there is -\csbxint{FtoGC}: -\begin{everbatim*} -2721/1001=\xintFtoGC {2721/1001} -\end{everbatim*} -Let us compare in that case with the output of \csbxint{FtoCC}: +Two special cases: +\begin{itemize}[nosep] +\item if after this initial expansion no brace is found immediately after + \csa{xintAssign}, it is assumed that there is only one control sequence + following |\to|, and this control sequence is then defined via |\def| (or + what is set-up by the optional parameter) to expand to the material between + \csa{xintAssign} and \csa{to}. +\item if the material between \csa{xintAssign} and |\to| is enclosed in two + brace pairs, the first brace pair is removed, then the \fexpan sion is + immediately stopped by the inner brace pair, hence \csa{xintAssign} now + finds a unique item and thus defines only a single macro to be this item, + which is now stripped of the second pair of braces. +\end{itemize} + + +\emph{Note:} prior to release |1.09j|, |\xintAssign| did an |\edef| by default +for each item assignment but it now does |\def| corresponding to no or empty +optional parameter. + +It is allowed for the successive braced items to be separated by spaces. They +are removed during the assignments. But if a single macro is defined (which +happens if the argument after \fexpan sion does not start with a brace), +naturally the scooped up material has all intervening spaces, as it is +considered a +single item. But an upfront initial space will have been absorbed by \fexpan +sion. \begin{everbatim*} -2721/1001=\xintFtoCC {2721/1001} +\def\X{ {a} {b} {c} {d} }\def\Y { u {a} {b} {c} {d} } +\xintAssign\X\to\A\B\C\D +\xintAssign\Y\to\Z +\meaning\A, \meaning\B, \meaning\C, \meaning\D+++\newline +\meaning\Z+++\par \end{everbatim*} -To obtain the coefficients as a sequence of braced numbers, there is -\csbxint{FtoC} (this is a shortcut for |\xintFtoCx {}|). This list -(sequence) may then be manipulated using the various macros of \xinttoolsname -such as the non-expandable macro \csbxint{AssignArray} or the expandable -\csbxint{Apply} and \csbxint{ListWithSep}. +As usual successive space characters in input make for a single \TeX\ space token. -Conversely to go from such a sequence of braced coefficients to the -corresponding fraction there is \csbxint{CtoF}. -The `|\printnumber|' (\autoref{ssec:printnumber}) macro which we use in this -document to print long numbers can also be useful on long continued fractions. +\subsection{\csh{xintAssignArray}}\label{xintAssignArray} + +\xintAssignArray \xintBezout {1000}{113}\to\Bez + +\csa{xintAssignArray}\meta{braced things}\csa{to}\csa{myArray} % -\begin{everbatim*} -\printnumber{\xintFtoCC {35037018906350720204351049/244241737886197404558180}} -\end{everbatim*} +%\ntype{{(f$\to$\lowast x)}N} % -If we apply \csbxint{GCtoF} to this generalized continued fraction, we -discover that the original fraction was reducible: +first expands fully what comes immediately after |\xintAssignArray| and +expects to find a list of braced things |{A}{B}...| (or tokens). It then +defines \csa{myArray} as a macro with one parameter, such that \csa{myArray\x} +expands to give the |x|th braced thing of this original +list (the argument \texttt{\x} itself is fed to a |\numexpr| by |\myArray|, +and |\myArray| expands in two steps to its output). With |0| as parameter, +\csa{myArray}|{0}| returns the number |M| of elements of the array so that the +successive elements are \csa{myArray}|{1}|, \dots, \csa{myArray}|{M}|. % -\leftedline{|\xintGCtoF - {143+1/2+...+-1/9}|\dtt{=\xintGCtoF{143+1/2+1/5+-1/4+-1/4+-1/4+-1/3+1/2+1/2+1/6+-1/22+1/2+1/10+-1/5+-1/11+-1/3+1/4+-1/2+1/2+1/4+-1/2+1/23+1/3+1/8+-1/6+-1/9}}} +\leftedline{|\xintAssignArray \xintBezout {1000}{113}\to\Bez|} will set +|\Bez{0}| to \dtt{\Bez0}, |\Bez{1}| to \dtt{\Bez1}, |\Bez{2}| to +\dtt{\Bez2}, and |\Bez{3}| to \dtt{\Bez3}: +\dtt{$\Bez1\times1000+\Bez2\times113=\Bez3$.} +This macro is incompatible with expansion-only contexts. -\def\mymacro #1{$\xintFrac{#1}=[\xintFtoCs{#1}]$\vtop to 6pt{}} +\csa{xintAssignArray} admits an optional parameter, for example +|\xintAssignArray [e]| means that the definitions of the macros will be made +with |\edef|. The empty optional parameter (default) means that definitions +are done with |\def|. Other possibilities: |[], [o], [oo], [f]|. Contrarily to +\csbxint{Assign} one can not use the |g| here to make the definitions global. +For this, one should rather do |\xintAssignArray| within a group starting with +|\globaldefs 1|. -\begingroup -\catcode`^\active -\def^#1^{\hbox{#1}}% -When a generalized continued fraction is built with integers, and -numerators are only |1|'s or |-1|'s, the produced fraction is -irreducible. And if we compute it again with the last sub-fraction -omitted we get another irreducible fraction related to the bigger one by -a Bézout identity. Doing this here we get: -% -\leftedline{|\xintGCtoF {143+1/2+...+-1/6}|\dtt{=\xintGCtoF{143+1/2+1/5+-1/4+-1/4+-1/4+-1/3+1/2+1/2+1/6+-1/22+1/2+1/10+-1/5+-1/11+-1/3+1/4+-1/2+1/2+1/4+-1/2+1/23+1/3+1/8+-1/6}}} -and indeed: -\[\begin{vmatrix} - ^2897319801297630107^ & ^328124887710626729^\\ - ^20197107104701740^ & ^2287346221788023^ - \end{vmatrix} = \mbox{\dtt{\xintiiSub {\xintiiMul {2897319801297630107}{2287346221788023}}{\xintiiMul{20197107104701740}{328124887710626729}}}}\] +\subsection{\csh{xintDigitsOf}}\label{xintDigitsOf} +This is a synonym for \csbxint{AssignArray},\ntype{fN} to be used to define +an array giving all the digits of a given (positive, else the minus sign will +be treated as first item) number. +\begingroup\xintDigitsOf\xintiiPow {7}{500}\to\digits +% +\leftedline{|\xintDigitsOf\xintiiPow {7}{500}\to\digits|} +\noindent $7^{500}$ has |\digits{0}=|\digits{0} digits, and the 123rd among them +(starting from the most significant) is +|\digits{123}=|\digits{123}. \endgroup -The various fractions obtained from the truncation of a continued fraction to -its initial terms are called the convergents. The macros of \xintcfracname -such as \csbxint{FtoCv}, \csbxint{FtoCCv}, and others which compute such -convergents, return them as a list of braced items, with no separator (as does -\csbxint {FtoC} for the partial quotients). Here is an example: +\subsection{\csh{xintRelaxArray}}\label{xintRelaxArray} -\begin{everbatim*} -\[\xintFrac{915286/188421}\to - \xintListWithSep{,}{\xintApply\xintFrac{\xintFtoCv{915286/188421}}}\] -\end{everbatim*} -\begin{everbatim*} -\[\xintFrac{915286/188421}\to - \xintListWithSep{,}{\xintApply\xintFrac{\xintFtoCCv{915286/188421}}}\] -\end{everbatim*} +\csa{xintRelaxArray}\csa{myArray} %\ntype{N} % -We thus see that the `centered convergents' obtained with \csbxint{FtoCCv} are -among the fuller list of convergents as returned by \csbxint{FtoCv}. +(globally) sets to \csa{relax} all macros which were defined by the previous +\csa{xintAssignArray} with \csa{myArray} as array macro. -Here is a more complicated use of \csa{xintApply} -and \csa{xintListWithSep}. We first define a macro which will be applied to each -convergent:% -% -\leftedline{|\newcommand{\mymacro}[1]{$\xintFrac{#1}=[\xintFtoCs{#1}]$\vtop to 6pt{}}|} -% -Next, we use the following code: -% -\leftedline{|$\xintFrac{49171/18089}\to{}$|} -% -\leftedline{|\xintListWithSep {, - }{\xintApply{\mymacro}{\xintFtoCv{49171/18089}}}|} -It produces:\par -\noindent$ \xintFrac{49171/18089}\to {}$\xintListWithSep {, - }{\xintApply{\mymacro}{\xintFtoCv{49171/18089}}}. +\clearpage +\let\xinttoolsnameUp\undefined +\def\n{|{N}|} +\def\m{|{M}|} +\def\x{|{x}|} -The macro \csbxint{CntoF} allows to specify the coefficients as a function given -by a one-parameter macro. The produced values do not have to be integers. -\begin{everbatim*} -\def\cn #1{\xintiiPow {2}{#1}}% 2^n - \[\xintFrac{\xintCntoF {6}{\cn}}=\xintCFrac [l]{\xintCntoF {6}{\cn}}\] -\end{everbatim*} +\csname xintexprnameUp\endcsname +\section{Macros of the \xintexprname package}% +\RaisedLabel{sec:oldxintexpr} -Notice the use of the optional argument |[l]| to \csa{xintCFrac}. Other -possibilities are |[r]| and (default) |[c]|. -\begin{everbatim*} -\def\cn #1{\xintPow {2}{-#1}}% - \[\xintFrac{\xintCntoF {6}{\cn}}=\xintGCFrac [r]{\xintCntoGC {6}{\cn}}= - [\xintFtoCs {\xintCntoF {6}{\cn}}]\] -\end{everbatim*} -We used \csbxint{CntoGC} as we wanted to display also the continued fraction and -not only the fraction returned by \csa{xintCntoF}. +\localtableofcontents -There are also \csbxint{GCntoF} and \csbxint{GCntoGC} which allow the same for -generalized fractions. An initial portion of a generalized continued -fraction for $\pi$ is obtained like this -\begin{everbatim*} -\def\an #1{\the\numexpr 2*#1+1\relax }% -\def\bn #1{\the\numexpr (#1+1)*(#1+1)\relax }% -\[\xintFrac{\xintDiv {4}{\xintGCntoF {5}{\an}{\bn}}} = - \cfrac{4}{\xintGCFrac{\xintGCntoGC {5}{\an}{\bn}}} = - \xintTrunc {10}{\xintDiv {4}{\xintGCntoF {5}{\an}{\bn}}}\dots\] -\end{everbatim*} +The \xintexprname package was first released with version |1.07| +(|2013/05/25|) of the \xintname bundle. It was substantially enhanced with +release |1.1| from |2014/10/28|. -We see that the quality of approximation is not fantastic compared to the simple -continued fraction of $\pi$ with about as many terms: -\begin{everbatim*} -\[\xintFrac{\xintCstoF{3,7,15,1,292,1,1}}= - \xintGCFrac{3+1/7+1/15+1/1+1/292+1/1+1/1}= - \xintTrunc{10}{\xintCstoF{3,7,15,1,292,1,1}}\dots\] -\end{everbatim*} +The |1.4| release from |2020/01/31| maintains the same general architecture +but needed adapting all the code base for the switch from |\csname| to +|\expanded| techniques. On this occasion the mechanism for defining functions +was substantially strengthened. The parser core mechanisms were improved too. -When studying the continued fraction of some real number, there is always -some doubt about how many terms are valid, when computed starting from some -approximation. If $f\leqslant x\leqslant g$ and $f, g$ both have the -same first $K$ partial quotients, then $x$ also has the same first $K$ quotients -and convergents. The macro \csbxint{FGtoC} outputs as a sequence of braced items -the common partial quotients of its two arguments. We can thus use it to produce -a sure list of valid convergents of $\pi$ for example, starting from some proven -lower and upper bound: -\begin{everbatim*} -$$\pi\to [\xintListWithSep{,} - {\xintFGtoC {3.14159265358979323}{3.14159265358979324}}, \dots]$$ -\noindent$\pi\to\xintListWithSep{,\allowbreak\;} - {\xintApply{\xintFrac} - {\xintCtoCv{\xintFGtoC {3.14159265358979323}{3.14159265358979324}}}}, \dots$ -\end{everbatim*} +The package loads automatically \xintfracname and \xinttoolsname. +This section should be trimmed to contain only information not +already covered in \autoref{sec:expr}. -\subsection{\csh{xintCFrac}}\label{xintCFrac} +\subsection{The \csh{xintexpr} expressions} +\label{xintexpr} +\label{xinttheexpr} +\label{thexintexpr} +\label{xintthe} -\csa{xintCFrac}|{f}|\ntype{\Ff} is a math-mode only, \LaTeX{} with |amsmath| -only, macro which first computes then displays with the help of |\cfrac| the -simple continued fraction corresponding to the given fraction. It admits an -optional argument which may be |[l]|, |[r]| or (the default) |[c]| to specify -the location of the one's in the numerators of the sub-fractions. Each -coefficient is typeset using the \csbxint{Frac} macro from the \xintfracname -package. This macro is \fexpan dable in the sense that it prepares expandably -the whole expression with the multiple |\cfrac|'s, but it is not completely -expandable naturally as |\cfrac| isn't. +An \xintexprname{}ession is a construct +\csbxint{expr}\meta{expandable\_expression}|\relax|\etype{x} where the +expandable expression is read and completely expanded from left to right. -\subsection{\csh{xintGCFrac}}\label{xintGCFrac} +An |\xintexpr...\relax| \emph{must} end in a |\relax| (which will be absorbed). +Contrarily to a |\numexpr| expression, it is printable\CHANGED{1.4} as is without a prefix +|\the| or |\number| (don't use them with |\xintexpr| this will raise an +error). -\csa{xintGCFrac}|{a+b/c+d/e+f/g+h/...+x/y}|\ntype{f} uses similarly |\cfrac| -to prepare the typesetting with the |amsmath| |\cfrac| (\LaTeX{}) of a -generalized continued fraction given in inline format (or as macro which -will \fexpan d to it). It admits the -same optional argument as \csa{xintCFrac}. Plain \TeX{} with |amstex| -users, see \csbxint{GCtoGCx}. -\begin{everbatim*} -\[\xintGCFrac {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}\] -\end{everbatim*} -This is mostly a typesetting macro, although it does provoke the -expansion of the coefficients. See \csbxint{GCtoF} if you are impatient -to see this specific fraction computed. +But one can use |\xintthe| prefix if one does need the explicit digits and +other characters as in the final typesetted result. -It admits an optional argument within square brackets which may be -either |[l]|, |[c]| or |[r]|. Default is |[c]| (numerators are centered). +As an alternative and equivalent syntax to +\begin{everbatim} +\xintexpr round(, D)\relax +\end{everbatim} +there is +\begin{everbatim} +\xintiexpr [D] \relax +\end{everbatim} +The parameter |D| must be zero or positive.\footnote{|D=0| + corresponds to using |round()| not |round(,0)| which + would leave a trailing dot. Same for |trunc|. There is also function |float| + for floating point rounding to \csbxint{theDigits} or the given number of + significant digits as second argument.} Perhaps some future version will +give a meaning to using a negative |D|.\footnote{Thanks to KT for this + suggestion. Sorry for the delay in implementing it... matter of formatting + the output and corresponding choice of user interface are still in need of + some additional thinking.} -Numerators and denominators are made arguments to the \csbxint{Frac} -macro. This allows them to be themselves fractions or anything \fexpan -dable giving numbers or fractions, but also means however that they can -not be arbitrary material, they can not contain color changing macros -for example. One of the reasons is that \csa{xintGCFrac} tries to -determine the signs of the numerators and chooses accordingly to use -$+$ or $-$. +\begin{itemize} +\item the expression may contain arbitrarily many levels of nested parenthesized + sub-expressions, +\item the expression may contain explicitely or from a macro expansion a + sub-expression |\xintexpr...\relax|, which itself may contain a + sub-expressions etc\dots +\item to let sub-contents evaluate as a sub-unit it should thus be either + \begin{enumerate} + \item parenthesized, + \item or a sub-expression |\xintexpr...\relax|. + \end{enumerate} + \item to use an expression as argument to macros from \xintfracname, + or more generally to macros which expand their arguments, one must use the + |\xinttheexpr...\relax| or |\xintthe\xintexpr...\relax| forms. + \item one should not use |\xintthe\xintexpr...\relax| as a sub-constituent of + another expression but only the + |\xintexpr...\relax| form which is more efficient in this context. + \item each \xintexprname{}ession, whether prefixed or not with |\xintthe|, is + completely expandable and obtains its result in two expansion steps. +\end{itemize} + +The information now following is possibly in need of updates. + +\begin{itemize}[parsep=0pt, labelwidth=\leftmarginii, + itemindent=0pt, listparindent=\leftmarginiii, leftmargin=\leftmarginii] +\item An expression is built the standard way with opening and closing + parentheses, infix operators, and (big) numbers, with possibly a fractional + part, and/or scientific notation (except for \csbxint{iiexpr} which only + admits big integers). All variants work with comma separated expressions. On + output each comma will be followed by a space. A decimal number must have + digits either before or after the decimal mark. + +\item As everything gets expanded, the characters |.|, |+|, |-|, |*|, |/|, |^|, + |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, |=|, |(|, |)|, |"|, |]|, |[|, |@| + and the comma |,| should not (if used in the expression) be active. For + example, the French language in |Babel| system, for pdf\LaTeX, activates |!|, + |?|, |;| and |:|. Turn off the activity before expressions using such characters. + + Alternatively the macro \csbxint{exprSafeCatcodes} resets all + characters potentially needed by \csbxint{expr} to their standard catcodes + and \csbxint{exprRestoreCatcodes} restores the former status. + +\item Count registers and |\numexpr|-essions are accepted (LaTeX{}'s counters + can be inserted using |\value|) natively without |\the| or |\number| as + prefix. Also dimen registers and control sequences, skip registers and + control sequences (\LaTeX{}'s lengths), |\dimexpr|-essions, + |\glueexpr|-essions are automatically unpacked using |\number|, discarding + the stretch and shrink components and giving the dimension value in |sp| + units ($1/65536$th of a \TeX{} point). Furthermore, tacit multiplication is + implied, when the (count or dimen or glue) register or variable, or the + (|\numexpr| or |\dimexpr| or |\glueexpr|) expression is immediately prefixed + by a (decimal) number. See \autoref{ssec:tacit multiplication} for the complete rules + of tacit multiplication.\IMPORTANT + +\item With a macro |\x| defined like this: + % + \leftedline{|\def\x {\xintexpr \a + \b \relax}| or |\edef\x {\xintexpr + \a+\b\relax}|} + % + one may then do |\xintthe\x|, either for printing the result on the page or + to use it in some other macros expanding their arguments. The |\edef| does + the computation immediately but keeps it in a protected form. + Naturally, the |\edef| is only possible if |\a| and |\b| are already + defined. With both approaches the |\x| can be inserted in other expressions, + as for example (assuming naturally as we use an |\edef| that in the + `yet-to-be computed' case the |\a| and |\b| now have some suitable meaning): + % + \leftedline {|\edef\y {\xintexpr \x^3\relax}|} -\subsection{\csh{xintGGCFrac}}\label{xintGGCFrac} +\item There is also \csbxint{boolexpr}| ... \relax| and + \csbxint{theboolexpr}| ... \relax|. -\csa{xintGGCFrac}|{a+b/c+d/e+f/g+h/...+x/y}|\ntype{f} is a clone of -\csbxint{GCFrac}, hence again \LaTeX{} specific with package -|amsmath|. -It does not assume the coefficients to be numbers as understood by -\xintfracname. The macro can be used for displaying arbitrary content as -a continued fraction with |\cfrac|, using only plus signs though. Note -though that it will first \fexpan d its argument, which may be thus be -one of the \xintcfracname macros producing a (general) continued -fraction in inline format, see \csbxint{FtoCx} for an example. If this -expansion is not wished, it is enough to start the argument with a -space. +\item See also + \csbxint{ifboolexpr} (\autoref{xintifboolexpr}) and the + \func{bool} and \func{togl} functions + in \autoref{sec:expr}. Here is an example. Well in fact the + example ended up using only \csbxint{boolexpr} so it + was modified to use \csbxint{ifboolexpr}. +\catcode`| 12 % \begin{everbatim*} -\[\xintGGCFrac {1+q/1+q^2/1+q^3/1+q^4/1+q^5/\ddots}\] -\end{everbatim*} - -\subsection{\csh{xintGCtoGCx}}\label{xintGCtoGCx} -%{\small New with release |1.05|.\par} - -\csa{xintGCtoGCx}|{sepa}{sepb}{a+b/c+d/e+f/...+x/y}|\etype{nnf} returns the list -of the coefficients of the generalized continued fraction of |f|, each one -within a pair of braces, and separated with the help of |sepa| and |sepb|. Thus -% -\leftedline{|\xintGCtoGCx :;{1+2/3+4/5+6/7}| gives \xintGCtoGCx - :;{1+2/3+4/5+6/7}} -% -The following can be used byt Plain \TeX{}+|amstex| users to obtain an -output similar as the ones produced by \csbxint{GCFrac} and -\csbxint{GGCFrac}:\par -\everb|@ -$$\xintGCtoGCx {+\cfrac}{\\}{a+b/...}\endcfrac$$ -$$\xintGCtoGCx {+\cfrac\xintFwOver}{\\\xintFwOver}{a+b/...}\endcfrac$$ -| +\xintdeffunc A(p,q,r) = p && (q || r) ; +\xintdeffunc B(p,q,r) = p || (q && r) ; +\xintdeffunc C(p,q,r) = xor(p, q, r) ; -\subsection{\csh{xintFtoC}}\label{xintFtoC} +\centeredline{\normalcolor +\begin{tabular}{ccrclcl} + \xintFor* #1 in {{False}{True}} \do {% + \xintFor* #2 in {{False}{True}} \do {% + \xintFor* #3 in {{False}{True}} \do {% + #1 &AND &(#2 &OR )&is&\textcolor[named]{OrangeRed} + {\xintifboolexpr{A(#1,#2,#3)}{true}{false}}\\ + #1 &OR &(#2 &AND )&is&\textcolor[named]{OrangeRed} + {\xintifboolexpr{B(#1,#2,#3)}{yes}{no}}\\ + #1 &XOR & #2 &XOR  &is&\textcolor[named]{OrangeRed} + {\xintifboolexpr{C(#1,#2,#3)}{oui}{non}}\\ +}}} +\end{tabular}% +} +\end{everbatim*}\catcode`| 13 -\csa{xintFtoC}|{f}|\etype{\Ff} computes the -coefficients of the simple continued fraction of |f| and returns them as a list -(sequence) of braced items. +\item See also \csbxint{ifsgnexpr}. +\item There is \csbxint{floatexpr}| ... \relax| where the algebra is done + in floating point approximation (also for each intermediate result). Use the + syntax |\xintDigits:=N\relax| to set the precision. Default: $16$ digits. + % + \leftedline{|\xintthefloatexpr 2^100000\relax:| \dtt{\xintthefloatexpr + 2^100000\relax }} + % + The square-root operation can be used in |\xintexpr|, it is computed + as a float with the precision set by |\xintDigits| or by the optional + second argument: + % \begin{everbatim*} -\fdef\test{\xintFtoC{-5262046/89233}}\texttt{\meaning\test} +\xinttheexpr sqrt(2,60)\relax\newline +Here the [60] is to avoid truncation to |\xinttheDigits| of precision on output.\newline +\printnumber{\xintthefloatexpr [60] sqrt(2,60)\relax} \end{everbatim*} -\subsection{\csh{xintFtoCs}}\label{xintFtoCs} - -\csa{xintFtoCs}|{f}|\etype{\Ff} returns the comma separated list of the -coefficients of the simple continued fraction of |f|. Notice that starting with -|1.09m| a space follows each comma (mainly for usage in text mode, as in math -mode spaces are produced in the typeset output by \TeX{} itself). + Floats are quickly indispensable when using the power function, as exact + results will easily have hundreds, even thousands of digits. + % \begin{everbatim*} -\[ \xintSignedFrac{-5262046/89233} \to [\xintFtoCs{-5262046/89233}]\] +\xintDigits:=48\relax \xintthefloatexpr 2^100000\relax \end{everbatim*} -\subsection{\csh{xintFtoCx}}\label{xintFtoCx} + Only integer and (in |\xintfloatexpr...\relax|) half-integer exponents are + allowed. -\csa{xintFtoCx}|{sep}{f}|\etype{n\Ff} returns the list of the -coefficients of the simple continued fraction of |f| separated with the -help of |sep|, which may be anything (and is kept unexpanded). For -example, with Plain \TeX{} and |amstex|, -% -\leftedline{|$$\xintFtoCx {+\cfrac1\\ }{-5262046/89233}\endcfrac$$|} -% -will display the continued fraction using -|\cfrac|. Each coefficient is inside a brace pair \hbox{|{ }|}, allowing -a macro to end the separator and fetch it as argument, -for example, again with Plain \TeX{} and |amstex|: -\everb|@ - \def\highlight #1{\ifnum #1>200 \textcolor{red}{#1}\else #1\fi} - $$\xintFtoCx {+\cfrac1\\ \highlight}{104348/33215}\endcfrac$$ -| +\item if one uses \emph{macros} within |\xintexpr..\relax| one should + obviously take into account that the parser will \emph{not} see the macro + arguments, hence one cannot use the syntax there, except if the arguments + are themselves wrapped as |\xinttheexpr...\relax| and assuming the macro + \fexpan ds these arguments. +\end{itemize} +\subsection{\texorpdfstring{\texttt{\protect\string\numexpr}}{\textbackslash + numexpr} or \texorpdfstring{\texttt{\protect\string\dimexpr}}{\textbackslash + dimexpr} expressions, count and dimension registers and variables} +\label{ssec:countinexpr} -Due to the different and extremely cumbersome syntax of |\cfrac| under -\LaTeX{} it proves a bit tortuous to obtain there the same effect. -Actually, it is partly for this purpose that |1.09m| added \csbxint -{GGCFrac}. We thus use \csa{xintFtoCx} with a suitable separator, and\; -then the whole thing as argument to \csbxint{GGCFrac}: -\begin{everbatim*} -\def\highlight #1{\ifnum #1>200 \fcolorbox{blue}{white}{\boldmath\color{red}$#1$}% - \else #1\fi} -\[\xintGGCFrac {\xintFtoCx {+1/\highlight}{208341/66317}}\] -\end{everbatim*} +Count registers, count control sequences, dimen registers, dimen control +sequences (like |\parindent|), skips and skip control sequences, |\numexpr|, +|\dimexpr|, |\glueexpr|, |\fontdimen| can be inserted directly, they will be +unpacked using |\number| which gives the internal value in terms of scaled +points for the dimensional variables: $1$\,|pt|${}=65536$\,|sp| (stretch and +shrink components are thus discarded). -\subsection{\csh{xintFtoGC}}\label{xintFtoGC} +Tacit multiplication (see \autoref{ssec:tacit multiplication}) is implied, +when a number or decimal number prefixes such a register or control sequence. +\LaTeX{} lengths are skip control sequences and \LaTeX{} counters should be +inserted using |\value|. -\csa{xintFtoGC}|{f}|\etype{\Ff} does the same as \csa{xintFtoCx}|{+1/}{f}|. Its -output may thus be used in the package macros expecting such an `inline -format'. -% This continued fraction is a \emph{simple} one, not a -% \emph{generalized} one, but as it is produced in the format used for -% user input of generalized continued fractions, the macro was called -% \csa{xintFtoGC} rather than \csa{xintFtoC} for example. -% +Release |1.2| of the |\xintexpr| parser also recognizes and prefixes with +|\number| the |\ht|, |\dp|, and |\wd| \TeX{} primitives as well as the +|\fontcharht|, |\fontcharwd|, |\fontchardp| and |\fontcharic| \eTeX{} +primitives. + +In the case of numbered registers like |\count255| or |\dimen0| (or |\ht0|), +the resulting digits will be re-parsed, so for example |\count255 0| is like +|100| if |\the\count255| would give |10|. The same happens with inputs such +as |\fontdimen6\font|. And |\numexpr 35+52\relax| will be exactly as if |87| +as been encountered by the parser, thus more digits may follow: |\numexpr +35+52\relax 000| is like |87000|. If a new |\numexpr| follows, it is treated +as what would happen when |\xintexpr| scans a number and finds a non-digit: it +does a tacit multiplication. \begin{everbatim*} -566827/208524=\xintFtoGC {566827/208524} +\xinttheexpr \numexpr 351+877\relax\numexpr 1000-125\relax\relax{} is the same +as \xinttheexpr 1228*875\relax. \end{everbatim*} -\subsection{\csh{xintFGtoC}}\label{xintFGtoC} +Control sequences however (such as |\parindent|) are picked up as a whole by +|\xintexpr|, and the numbers they define cannot be extended extra digits, a +syntax error is raised if the parser finds digits rather than a legal +operation after such a control sequence. -\csa{xintFGtoC}|{f}{g}|\etype{\Ff\Ff} computes the common initial coefficients -to -two given fractions |f| and |g|. Notice that any real number |fx>g| -will then necessarily share with |f| and |g| these common initial coefficients -for its regular continued fraction. The coefficients are output as a sequence of -braced numbers. This list can then be manipulated via macros from -\xinttoolsname, or other macros of \xintcfracname. +A token list variable must be prefixed by |\the|, it will not be unpacked +automatically (the parser will actually try |\number|, and thus fail). Do not +use |\the| but only |\number| with a dimen or skip, as the |\xintexpr| parser +doesn't understand |pt| and its presence is a syntax error. To use a dimension +expressed in terms of points or other \TeX{} recognized units, incorporate it in +|\dimexpr...\relax|. -\begin{everbatim*} -\fdef\test{\xintFGtoC{-5262046/89233}{-5314647/90125}}\texttt{\meaning\test} -\end{everbatim*} -\begin{everbatim*} -\fdef\test{\xintFGtoC{3.141592653}{3.141592654}}\texttt{\meaning\test} -\end{everbatim*} -\begin{everbatim*} -\fdef\test{\xintFGtoC{3.1415926535897932384}{3.1415926535897932385}}\meaning\test -\end{everbatim*} -\begin{everbatim*} -\xintRound {30}{\xintCstoF{\xintListWithSep{,}{\test}}} -\end{everbatim*} -\begin{everbatim*} -\xintRound {30}{\xintCtoF{\test}} -\end{everbatim*} -\begin{everbatim*} -\fdef\test{\xintFGtoC{1.41421356237309}{1.4142135623731}}\meaning\test -\end{everbatim*} +Regarding how dimensional expressions are converted by \TeX{} into scaled points +see also \autoref{sec:Dimensions}. -\subsection{\csh{xintFtoCC}}\label{xintFtoCC} +\subsection{Catcodes and spaces} -\csa{xintFtoCC}|{f}|\etype{\Ff} returns the `centered' continued fraction of -|f|, in `inline format'. % -\begin{everbatim*} -566827/208524=\xintFtoCC {566827/208524} -\end{everbatim*} -\begin{everbatim*} -\[\xintFrac{566827/208524} = \xintGCFrac{\xintFtoCC{566827/208524}}\] -\end{everbatim*} +The main problems are caused by active characters, because \csbxint{expr} et +al.\@ expand forward whatever comes from token stream; they apply |\string| +only in a second step. For example the catcode of |&| from |&&| Boolean +disjunction is not really important as long as it is not active, or comment, +or escape... or brace... or ignored... in brief, as long as it is reasonable, +and in particular whether |@| is of catcode letter or other does not matter. -\subsection{\csh{xintCstoF}}\label{xintCstoF} +It is always possible to insert manually the |\string| in the expression +before a problematic (but reasonable) character catcode, or even to use +|\detokenize| for a big chunk. -\csa{xintCstoF}|{a,b,c,d,...,z}|\etype{f} computes the fraction corresponding to -the coefficients, which may be fractions or even macros expanding to such -fractions. The final fraction may then be highly reducible. +\subsubsection{\csh{xintexprSafeCatcodes}} +\label{xintexprSafeCatcodes} -\emph{Usage of this macro requires the user to load} \xinttoolsname.\IMPORTANT +For an even more radical way, there is \csbxint{exprSafeCatcodes} which sets +the catcodes of many characters to safe values. This is a non-expandable step +as it changes catcodes. +% This is used +% internally by \csbxint{NewExpr} (restoring the catcodes on exit), hence it +% does not have to be protected against active characters when used at +% top-level. -Starting with -release |1.09m| spaces before commas are allowed and trimmed automatically -(spaces after commas were already silently handled in earlier releases). -\begin{everbatim*} -\[\xintGCFrac {-1+1/3+1/-5+1/7+1/-9+1/11+1/-13}= - \xintSignedFrac{\xintCstoF {-1,3,-5,7,-9,11,-13}}=\xintSignedFrac{\xintGCtoF - {-1+1/3+1/-5+1/7+1/-9+1/11+1/-13}}\] -\end{everbatim*} -\begin{everbatim*} -\[\xintGCFrac{{1/2}+1/{1/3}+1/{1/4}+1/{1/5}}=\xintFrac{\xintCstoF {1/2,1/3,1/4,1/5}}\] -\end{everbatim*} -% -A generalized continued fraction may produce a reducible fraction -(\csa{xintCstoF} tries its best not to accumulate in a silly way superfluous -factors but will not do simplifications which would be obvious to a human, like -simplification by 3 in the result above). +\csbxint{defvar}, \csbxint{deffunc}, et al., execute it before fetching their +semi-colon delimited arguments, so they can be used (also in the document +body) for example with Babel+French (which makes the semi-colon active in the +(\LaTeX) document body). This applies also to \csbxint{NewExpr}. + +% As \csbxint{NewExpr} and \csbxint{deffunc} and variants use internally some +% |\scantokens|, they will (reasonably) succeed in sanitizing catcodes in the +% expressions, even if all is from the replacement text of some macro whose +% definition was done under some special catcode regime. + +But, if used in the body of macro definitions problems may arise from the +catcode regime at that location. This applies in particular to the +semi-colon as used by \csbxint{deffunc}, \csbxint{defvar} and variants as +delimiter. Thus make sure the semi-colon has its normal catcode when issueing +\csbxint{deffunc} inside some macro definition. + +\csbxint{deffunc} is more lenient than \csbxint{defvar} regarding catcodes of +characters in expression bodies as it does some |\scantokens| which will reset +compatible catcodes. And also, characters inside the +expression may usually be prefixed with |\string|; but some aspects of the parsing +use delimited macros which need the comma, equality sign and closing +parenthesis to have standard catcodes. + +Even if used in a context where catcodes are already set, \csbxint{deffunc}, +\csbxint{defvar} and variants ignore completely the colon in |:=| so it can +have any (reasonable) catcode. Moreover it is optional. + +The semi-colon in the syntax of \csbxint{Digits} is no real problem either +(cf. \csbxint{Digits} documentation). -\subsection{\csh{xintCtoF}}\label{xintCtoF} +\begin{framed} + It is important to ALWAYS shortly let \csbxint{exprSafeCatcodes} be followed + by \csbxint{exprRestoreCatcodes}.\IMPORTANTf{} If one uses twice + \csbxint{exprSafeCatcodes} then the next \csbxint{exprRestoreCatcodes} will + restore the ancient catcode regime at time of the first one. +\end{framed} -\csa{xintCtoF}|{{a}{b}{c}...{z}}|\etype{f} computes the fraction corresponding -to the coefficients, which may be fractions or even macros. -\begin{everbatim*} -\xintCtoF {\xintApply {\xintiiPow 3}{\xintSeq {1}{5}}} -\end{everbatim*} -\begin{everbatim*} -\[ \xintFrac{14946960/4805083}=\xintCFrac {14946960/4805083}\] -\end{everbatim*} -In the example above the power of $3$ was already pre-computed via the expansion -done by |\xintApply|, but if we try with |\xintApply { \xintiiPow 3}| where the -space will stop this expansion, we can check that |\xintCtoF| will itself -provoke the needed coefficient expansion.% ok +\subsubsection{\csh{xintexprRestoreCatcodes}} +\label{xintexprRestoreCatcodes} -\subsection{\csh{xintGCtoF}}\label{xintGCtoF} +Restores the catcodes to the earlier state. More precisely, +\csbxint{exprSafeCatcodes} sets a toggle (with local scope). If the toggle is +set already it does not restore the current catcodes. The next +\csa{xintexprRestoreCatcodes} unsets the toggle. +So, in case of nesting, the +catcodes are restored to what they were when the \emph{first} un-paired +\csbxint{exprSafeCatcodes} got executed. -\csa{xintGCtoF}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} computes the fraction -defined by the inline generalized continued fraction. Coefficients may be -fractions but must then be put within braces. They can be macros. The plus signs -are mandatory. -\begin{everbatim*} -\[\xintGCFrac {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}} = -\xintFrac{\xintGCtoF {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}} = -\xintFrac{\xintIrr{\xintGCtoF - {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}}}\] -\end{everbatim*} +\bigskip -\begin{everbatim*} -\[ \xintGCFrac{{1/2}+{2/3}/{4/5}+{1/2}/{1/5}+{3/2}/{5/3}} = - \xintFrac{\xintGCtoF {{1/2}+{2/3}/{4/5}+{1/2}/{1/5}+{3/2}/{5/3}}} \] -\end{everbatim*} +Spaces inside an |\xinttheexpr...\relax| should mostly be +innocuous (except inside macro arguments). -The macro tries its best not to accumulate superfluous factor in the -denominators, but doesn't reduce the fraction to irreducible form before -returning it and does not do simplifications which would be obvious to a human. +|\xintexpr| and |\xinttheexpr| are for the most part agnostic regarding +catcodes: (unbraced) digits, binary operators, minus and plus signs as +prefixes, dot as decimal mark, parentheses, may be indifferently of catcode +letter or other or subscript or superscript, ..., it doesn't matter.% +% +\footnote{Furthermore, although \csbxint{expr} uses \csa{string}, it is + escape-char agnostic. It should work with any \csa{escapechar} setting + including -1.} -\subsection{\csh{xintCstoCv}}\label{xintCstoCv} +The characters |+|, |-|, |*|, |/|, |^|, |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, +|=|, |(|, |)|, |"|, |[|, |]|, |;|, the dot and the comma should not be active if +in the expression, as everything is expanded along the way. If one of them is +active, it should be prefixed with |\string|. -\csa{xintCstoCv}|{a,b,c,d,...,z}|\etype{f} returns the sequence of the -corresponding convergents, each one within braces. +The exclamation mark |!| should have its standard catcode: with catcode letter +it is used internally and hence will confuse the parsers if it comes from the +expression. -\emph{Usage of this macro requires the user to load} \xinttoolsname.\IMPORTANT +Digits, slash, square brackets, minus sign, in the output from an +|\xinttheexpr| are all of catcode 12. For |\xintthefloatexpr| the `e' in the +output has its standard catcode ``letter''. -It is allowed to use fractions as coefficients (the computed -convergents have then no reason to be the real convergents of the final -fraction). When the coefficients are integers, the convergents are irreducible -fractions, but otherwise it is not necessarily the case. -\begin{everbatim*} -\xintListWithSep:{\xintCstoCv{1,2,3,4,5,6}} -\end{everbatim*} -\begin{everbatim*} -\xintListWithSep:{\xintCstoCv{1,1/2,1/3,1/4,1/5,1/6}} -\end{everbatim*} -\begin{everbatim*} -\[\xintListWithSep{\to}{\xintApply\xintFrac{\xintCstoCv {\xintPow - {-.3}{-5},7.3/4.57,\xintCstoF{3/4,9,-1/3}}}}\] -\end{everbatim*} +A macro with arguments will expand and grab its arguments before the +parser may get a chance to see them, so the situation with catcodes and spaces +is not the same within such macro arguments. -\subsection{\csh{xintCtoCv}}\label{xintCtoCv} -\csa{xintCtoCv}|{{a}{b}{c}...{z}}|\etype{f} returns the sequence of the -corresponding convergents, each one within braces. -\begin{everbatim*} -\fdef\test{\xintCtoCv {11111111111}}\texttt{\meaning\test} -\end{everbatim*} -\subsection{\csh{xintGCtoCv}}\label{xintGCtoCv} +\subsection{Expandability, \csh{xintexpro}} -\csa{xintGCtoCv}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} returns the list of -the corresponding convergents. The coefficients may be fractions, but must then -be inside braces. Or they may be macros, too. +As is the case with all other package macros |\xintexpr| \fexpan ds (in two +steps) to its final (somewhat protected) result; and |\xinttheexpr| \fexpan ds +(in two steps) to the chain of digits (and possibly minus sign |-|, decimal +mark |.|, fraction slash |/|, scientific |e|, square brackets |[|, |]|) +representing the result. -The convergents will in the general case be reducible. To put them into -irreducible form, one needs one more step, for example it can be done -with |\xintApply\xintIrr|. -\begin{everbatim*} -\[\xintListWithSep{,}{\xintApply\xintFrac - {\xintGCtoCv{3+{-2}/{7/2}+{3/4}/12+{-56}/3}}}\] -\[\xintListWithSep{,}{\xintApply\xintFrac{\xintApply\xintIrr - {\xintGCtoCv{3+{-2}/{7/2}+{3/4}/12+{-56}/3}}}}\] -\end{everbatim*} +The once expanded |\xintexpr| is |\romannumeral0\xintexpro|. is similarly +|\xintiexpro| |\xintiiexpro| and |\xintfloatexpro|. For an example see +\autoref{ssec:fibonacci}. +An expression can only be legally finished by a |\relax| token, which +will be absorbed. -\subsection{\csh{xintFtoCv}}\label{xintFtoCv} +It is quite possible to nest expressions among themselves; for example, if one +needs inside an |\xintiiexpr...\relax| to do some computations with fractions, +rounding the final result to an integer, one just has to insert +|\xintiexpr...\relax|. The functioning of the infix operators will not be in +the least affected from the fact that the outer ``environment'' is the +|\xintiiexpr| one. -\csa{xintFtoCv}|{f}|\etype{\Ff} returns the list of the (braced) convergents of -|f|, with no separator. To be treated with \csbxint{AssignArray} or -\csbxint{ListWithSep}. -\begin{everbatim*} -\[\xintListWithSep{\to}{\xintApply\xintFrac{\xintFtoCv{5211/3748}}}\] -\end{everbatim*} -\subsection{\csh{xintFtoCCv}}\label{xintFtoCCv} +\subsection{\csh{xintDigits*}, \csh{xintSetDigits*}} +\label{xintDigits*} +\label{xintSetDigits*} -\csa{xintFtoCCv}|{f}|\etype{\Ff} returns the list of the (braced) centered -convergents of |f|, with no separator. To be treated with \csbxint{AssignArray} -or \csbxint{ListWithSep}. -\begin{everbatim*} -\[\xintListWithSep{\to}{\xintApply\xintFrac{\xintFtoCCv{5211/3748}}}\] -\end{everbatim*} +These starred variants of \csbxint{Digits} and \csbxint{SetDigits} execute +\csbxint{reloadxinttrig}. -\subsection{\csh{xintCntoF}}\label{xintCntoF} +\subsection{\csh{xintiexpr}, \csh{xinttheiexpr}} +\label{xintiexpr}\label{xinttheiexpr}\label{thexintiexpr} +Equivalent\etype{x} to doing |\xintexpr round(...)\relax| (more precisely, +|round| is applied to each leaf item of the |ople| independently of its +depth). -\csa{xintCntoF}|{N}{\macro}|\etype{\numx f} computes the fraction |f| having -coefficients |c(j)=\macro{j}| for |j=0,1,...,N|. The |N| parameter is given to a -|\numexpr|. The values of the coefficients, as returned by |\macro| do not have -to be positive, nor integers, and it is thus not necessarily the case that the -original |c(j)| are the true coefficients of the final |f|. -\begin{everbatim*} -\def\macro #1{\the\numexpr 1+#1*#1\relax} \xintCntoF {5}{\macro} -\end{everbatim*} +Intermediate calculations are exact, only the final output gets +rounded. Half integers are rounded towards $+\infty$ for positive +numbers and towards $-\infty$ for negative ones. -This example shows that the fraction is output with a trailing number in square -brackets (representing a power of ten), this is for consistency with what do -most macros of \xintfracname, and does not have to be always this annoying |[0]| -as the coefficients may for example be numbers in scientific notation. To avoid -these trailing square brackets, for example if the coefficients are known to be integers, there is always the possibility to filter the output via -\csbxint{PRaw}, or \csbxint{Irr} (the latter is overkill in the case of integer -coefficients, as the fraction is guaranteed to be irreducible then). +An optional parameter |D| within brackets, immediately after |\xintiexpr| is +allowed: it instructs (for |D>0|) the expression to do its final rounding to +the nearest value with that many digits after the decimal mark, \emph{i.e.}, +|\xintiexpr [D] \relax| is equivalent (in case of a single +expression) to |\xintexpr round(, D)\relax|. -\subsection{\csh{xintGCntoF}}\label{xintGCntoF} +|\xintiexpr [0] ...| is the same as |\xintiexpr ...| and rounds to an integer. -\csa{xintGCntoF}|{N}{\macroA}{\macroB}|\etype{\numx ff} returns the fraction |f| -corresponding to the inline generalized continued fraction -|a0+b0/a1+b1/a2+....+b(N-1)/aN|, with |a(j)=\macroA{j}| and |b(j)=\macroB{j}|. -The |N| parameter is given to a |\numexpr|. -\begin{everbatim*} -\def\coeffA #1{\the\numexpr #1+4-3*((#1+2)/3)\relax }% -\def\coeffB #1{\the\numexpr \ifodd #1 -\fi 1\relax }% (-1)^n -\[\xintGCFrac{\xintGCntoGC {6}{\coeffA}{\coeffB}} = - \xintFrac{\xintGCntoF {6}{\coeffA}{\coeffB}}\] -\end{everbatim*} -There is also \csbxint{GCntoGC} to get the `inline format' continued -fraction. +The case of negative |D| gives quantization to an integer multiple of +\dtt{1e-D}.\NewWith{1.4a} -\subsection{\csh{xintCntoCs}}\label{xintCntoCs} +If truncation rather than rounding is needed on can use |\xintexpr +trunc(...)\relax| for truncation to an integer or |\xintexpr +trunc(...,D)\relax| for quantization to an integer multiple or \dtt{1eD}. But +this works only for a single scalar value. -\csa{xintCntoCs}|{N}{\macro}|\etype{\numx f} produces the comma separated list -of the corresponding coefficients, from |n=0| to |n=N|. The |N| is given to a -|\numexpr|. % -\begin{everbatim*} -\xintCntoCs {5}{\macro} -\end{everbatim*} -\begin{everbatim*} -\[ \xintFrac{\xintCntoF{5}{\macro}}=\xintCFrac{\xintCntoF {5}{\macro}}\] -\end{everbatim*} +Already on October 20, 2015, it was suggested by \textsc{Kpym} to give some +meaning to negative |D|. The suggestion was to let it act like |-D| but +remove trailing zeroes of the output. Finally, I opted rather for +quantization. -\subsection{\csh{xintCntoGC}}\label{xintCntoGC} +\subsection{\csh{xintiiexpr}, \csh{xinttheiiexpr}} +\label{xintiiexpr}\label{xinttheiiexpr}\label{thexintiiexpr} -% -\csa{xintCntoGC}|{N}{\macro}|\etype{\numx f} evaluates the |c(j)=\macro{j}| from -|j=0| to |j=N| and returns a continued fraction written in inline format: -|{c(0)}+1/{c(1)}+1/...+1/{c(N)}|. The parameter |N| is given to a |\numexpr|. -The coefficients, after expansion, are, as shown, being enclosed in an added -pair of braces, they may thus be fractions. -\begin{everbatim*} -\def\macro #1{\the\numexpr\ifodd#1 -1-#1\else1+#1\fi\relax/\the\numexpr 1+#1*#1\relax} -\fdef\x{\xintCntoGC {5}{\macro}}\meaning\x -\[\xintGCFrac{\xintCntoGC {5}{\macro}}\] -\end{everbatim*} +This variant\etype{x} does not know fractions. It deals almost only with long +integers. Comma separated lists of expressions are allowed. -\subsection{\csh{xintGCntoGC}}\label{xintGCntoGC} +\begin{framed} + It maps |/| to the \emph{rounded} quotient. The operator + |//| is, like in |\xintexpr...\relax|, mapped to \emph{truncated} division. + The Euclidean quotient (which for positive operands is like the truncated + quotient) was, prior to release |1.1|, associated to |/|. The function + |quo(a,b)| can still be employed. +\end{framed} -\csa{xintGCntoGC}|{N}{\macroA}{\macroB}|\etype{\numx ff} evaluates the -coefficients and then returns the corresponding -|{a0}+{b0}/{a1}+{b1}/{a2}+...+{b(N-1)}/{aN}| inline generalized fraction. |N| is -givent to a |\numexpr|. The coefficients are enclosed into pairs -of braces, and may thus be fractions, the fraction slash will not be -confused in further processing by the continued fraction slashes. -% -\begin{everbatim*} -\def\an #1{\the\numexpr #1*#1*#1+1\relax}% -\def\bn #1{\the\numexpr \ifodd#1 -\fi 1*(#1+1)\relax}% -$\xintGCntoGC {5}{\an}{\bn}=\xintGCFrac {\xintGCntoGC {5}{\an}{\bn}} = -\displaystyle\xintFrac {\xintGCntoF {5}{\an}{\bn}}$\par -\end{everbatim*} +The \csbxint{iiexpr}-essions use the `ii' macros for addition, subtraction, +multiplication, power, square, sums, products, Euclidean quotient and +remainder. + +The |round|, |trunc|, |floor|, |ceil| functions are still available, and are +about the only places where fractions can be used, but |/| within, if not +somehow hidden will be executed as integer rounded division. To avoid this one +can wrap the input in \dtt{qfrac}: this means however that none of the normal +expression parsing will be executed on the argument. + +To understand the illustrative examples, recall that |round| and |trunc| have +a second (non negative) optional argument. In a normal \csbxint{expr}-essions, +|round| and |trunc| are mapped to \csbxint{Round} and \csbxint{Trunc}, in +\csbxint{iiexpr}-essions, they are mapped to \csbxint{iRound} and +\csbxint{iTrunc}. -\subsection{\csh{xintCstoGC}}\label{xintCstoGC} -\csa{xintCstoGC}|{a,b,..,z}|\etype{f} transforms a comma separated list (or -something expanding to such a list) into an `inline format' continued fraction -|{a}+1/{b}+1/...+1/{z}|. The coefficients are just copied and put within braces, -without expansion. The output can then be used in \csbxint{GCFrac} for example. \begin{everbatim*} -\[\xintGCFrac {\xintCstoGC {-1,1/2,-1/3,1/4,-1/5}}=\xintSignedFrac{\xintCstoF {-1,1/2,-1/3,1/4,-1/5}}\] +\xinttheiiexpr 5/3, round(5/3,3), trunc(5/3,3), trunc(\xintDiv {5}{3},3), +trunc(\xintRaw {5/3},3)\relax{} are problematic, but +% +\xinttheiiexpr 5/3, round(qfrac(5/3),3), trunc(qfrac(5/3),3), floor(qfrac(5/3)), +ceil(qfrac(5/3))\relax{} work! \end{everbatim*} -\subsection{\csh{xintiCstoF}, \csh{xintiGCtoF}, \csh{xintiCstoCv}, \csh{xintiGCtoCv}}\label{xintiCstoF} -\label{xintiGCtoF} -\label{xintiCstoCv} -\label{xintiGCtoCv} - -Essentially\etype{f} the same as the corresponding macros without the -`i', but for integer-only input. Infinitesimally faster, mainly for -internal use by the package. -\subsection{\csh{xintGCtoGC}}\label{xintGCtoGC} +On the other hand decimal numbers and scientific numbers can be used directly +as arguments to the |num|, |round|, or any function producing an integer. + +\begin{framed} + Scientific numbers will be + represented with as many zeroes as necessary, thus one does not want to + insert \dtt{num(1e100000)} for example in an \csa{xintiiexpr}ession! +\end{framed} -\csa{xintGCtoGC}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} expands (with the -usual meaning) each one of the coefficients and returns an inline continued -fraction of the same type, each expanded coefficient being enclosed within -braces. % \begin{everbatim*} -\fdef\x {\xintGCtoGC {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/% - \xintiiFac {6}+\xintCstoF {2,-7,-5}/16}} \meaning\x +\xinttheiiexpr num(13.4567e3)+num(10000123e-3)\relax % should (num truncates) compute 13456+10000 \end{everbatim*} +% -To be honest I have forgotten for which purpose I wrote this macro in the first -place. - -\subsection{Euler's number \texorpdfstring{$e$}{e}}\label{ssec:e-convergents} +The |reduce| function is not available and will raise an error. The |frac| +function also. The |sqrt| function is mapped to \csbxint{iiSqrt} which gives +a truncated square root. The |sqrtr| function is mapped to \csbxint{iiSqrtR} +which gives a rounded square root. -Let us explore -the convergents of Euler's number $e$. -\smallskip The volume of computation is kept minimal by the following steps: -\begin{itemize} -\item a comma separated list of the first 36 coefficients is produced by - \csbxint{CntoCs}, -\item this is then given to \csbxint{iCstoCv} which produces the list of the - convergents (there is also \csbxint{CstoCv}, but our - coefficients being integers we used the infinitesimally - faster \csbxint{iCstoCv}), -\item then the whole list was converted into a sequence of one-line paragraphs, - each convergent becomes the argument to a macro printing it - together with its decimal expansion with 30 digits after the decimal point. -\item A count register |\cnta| was used to give a line count serving as a visual - aid: we could also have done that in an expandable way, but well, let's relax - from time to time\dots -\end{itemize} +One can use the Float macros if one is careful to use |num|, or |round| +etc\dots on their output. \begin{everbatim*} -\def\cn #1{\the\numexpr\ifcase \numexpr #1+3-3*((#1+2)/3)\relax - 1\or1\or2*(#1/3)\fi\relax } -% produces the pattern 1,1,2,1,1,4,1,1,6,1,1,8,... which are the -% coefficients of the simple continued fraction of e-1. -\cnta 0 -\def\mymacro #1{\advance\cnta by 1 - \noindent - \hbox to 3em {\hfil\small\dtt{\the\cnta.} }% - $\xintTrunc {30}{\xintAdd {1[0]}{#1}}\dots= - \xintFrac{\xintAdd {1[0]}{#1}}$}% -\xintListWithSep{\vtop to 6pt{}\vbox to 12pt{}\par} - {\xintApply\mymacro{\xintiCstoCv{\xintCntoCs {35}{\cn}}}} +\xinttheiiexpr \xintFloatSqrt [20]{2}, \xintFloatSqrt [20]{3}\relax % no operations + +\noindent The next example requires the |round|, and one could not put the |+| inside it: + +\xinttheiiexpr round(\xintFloatSqrt [20]{2},19)+round(\xintFloatSqrt [20]{3},19)\relax + +(the second argument of |round| and |trunc| tells how many digits from after the +decimal mark one should keep.) \end{everbatim*} +The whole point of \csbxint{iiexpr} is to gain some speed in +\emph{integer-only} algorithms, and the above explanations related to how to +nevertheless use fractions therein are a bit peripheral. We observed +(2013/12/18) of the order of $30$\% speed gain when dealing with numbers with +circa one hundred digits (1.2: this info may be obsolete). -\smallskip -% The actual computation of the list of all 36 convergents accounts for -% only 8\% of the total time (total time equal to about 5 hundredths of a second -% in my testing, on my laptop): another 80\% is occupied with the computation of -% the truncated decimal expansions (and the addition of 1 to everything as the -% formula gives the continued fraction of $e-1$). +\subsection{\csh{xintboolexpr}, \csh{xinttheboolexpr}} +\label{xintboolexpr}\label{xinttheboolexpr}\label{thexintboolexpr} -One can with no problem compute -much bigger convergents. Let's get the 200th convergent. It turns out to -have the same first 268 digits after the decimal point as $e-1$. Higher -convergents get more and more digits in proportion to their index: the 500th -convergent already gets 799 digits correct! To allow speedy compilation of the -source of this document when the need arises, I limit here to the 200th -convergent. -% (getting the 500th took about 1.2s on my laptop last time I tried, -% and the 200th convergent is obtained ten times faster). -\begin{everbatim*} -\fdef\z {\xintCntoF {199}{\cn}}% -\begingroup\parindent 0pt \leftskip 2.5cm -\indent\llap {Numerator = }\printnumber{\xintNumerator\z}\par -\indent\llap {Denominator = }\printnumber{\xintDenominator\z}\par -\indent\llap {Expansion = }\printnumber{\xintTrunc{268}\z}\dots\par\endgroup -\end{everbatim*} +Equivalent\etype{x} to doing |\xintexpr ...\relax| and returning $True$ if the +result does not vanish, and $False$ if the result is zero. As |\xintexpr|, this +can be used on comma separated lists of expressions, and even bracketed lists. +\CHANGED{1.4} +It can be customized, one only needs to modify the following: +\begin{everbatim} +\def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{True}{False}}% +\end{everbatim} +Not only are |True| and |False| usable in input, also |true| and |false| are +pre-declared variables. -One can also use a centered continued fraction: we get more digits but there are -also more computations as the numerators may be either -$1$ or $-1$. +Maybe obsolete: -\clearpage -\let\xintcfracnameUp\undefined -\csname xinttoolsnameUp\endcsname -\def\n{|{N}|} -\def\m{|{M}|} -\def\x{|{x}|} -\section{Macros of the \xinttoolsname package} +There is slight quirk in case it is used as a sub-expression: the boolean +expression needs at least one logic operation else the value is not +standardized to |1| or |0|, for example we get from +\begin{everbatim*} +\xinttheexpr \xintboolexpr 1.23\relax\relax\newline +\end{everbatim*}which is to be compared with +\begin{everbatim*} +\xinttheboolexpr 1.23\relax +\end{everbatim*} -\RaisedLabel{sec:tools} +% A related issue existed with +% |\xinttheexpr \xintiexpr 1.23\relax\relax|, which was fixed with |1.1| +% release, and I decided back then not to add the needed overhead also to the +% |\xintboolexpr| context, as one only needs to use |?(1.23)| for example or +% involve the |1.23| in any logic operation like |1.23 'and' 3.45|, or involve +% the |\xintboolexpr ..\relax | itself with any logical operation, contrarily to +% the sub-|\xintiexpr| case where |\xinttheexpr 1+\xintiexpr 1.23\relax\relax| +% did behave contrarily to expectations until |1.1|. -\localtableofcontents -These utilities used to be provided within the \xintname package; since |1.09g| -(|2013/11/22|) they have been moved to an independently usable package -\xinttoolsname, which has none of the \xintname facilities regarding big -numbers. Whenever relevant release |1.09h| has made the macros |\long| so they -accept |\par| tokens on input. +\subsection{\csh{xintfloatexpr}, + \csh{xintthefloatexpr}} +\label{xintfloatexpr}\label{xintthefloatexpr}\label{thexintfloatexpr} -The completely expandable utilities (up to \csbxint{iloop}) are documented -first, then the non expandable utilities. +\csbxint{floatexpr}|...\relax|\etype{x} is exactly like |\xintexpr...\relax| +but with the four binary operations and the power function are mapped to +\csa{xintFloatAdd}, \csa{xintFloatSub}, \csa{xintFloatMul}, \csa{xintFloatDiv} +and \csa{xintFloatPower}, respectively.\footnote{Since |1.2f| the \string^ + handles half-integer exponents, contrarily to \csa{xintFloatPower}.} -\autoref{sec:examples} -gives additional (also dated) examples of use of macros of this package. +The target precision for the computation is from the +current setting of |\xintDigits|. Comma separated lists of expressions are +allowed. -\subsection{\csh{xintRevWithBraces}}\label{xintRevWithBraces} +An optional parameter within brackets is allowed: +\begin{itemize} +\item if positive it instructs the macro to round the result to that many + digits of precision. It thus makes sense to employ it only if this parameter is + less than the \csbxint{theDigits} precision. +\item if negative it means to trim off that many digits (of course, in the + sense of rounding + the values to shorter mantissas). Don't use it to trim all digits (or more than all)! +\end{itemize} -%{\small New in release |1.06|.\par} +Since |1.2f| all float operations first round their arguments; a parsed number +is not rounded prior to its use as operand to such a float operation. -\edef\X{\xintRevWithBraces{12345}} -\edef\y{\xintRevWithBraces\X} -\expandafter\def\expandafter\w\expandafter - {\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}} +|\thexintfloatexpr| is synonym to |\xintthefloatexpr|. +|\xintDigits:=36\relax|\xintDigits:=36\relax % -\csa{xintRevWithBraces}\marg{list}\etype{f} first does the \fexpan sion of its -argument then it reverses the order of the tokens, or braced material, it -encounters, maintaining existing braces and adding a brace pair around each -naked token encountered. Space tokens (in-between top level braces or naked -tokens) are gobbled. This macro is mainly thought out for use on a \meta{list} -of such braced material; with such a list as argument the \fexpan sion will only -hit against the first opening brace, hence do nothing, and the braced stuff may -thus be macros one does not want to expand. -% -\leftedline{|\edef\x{\xintRevWithBraces{12345}}|} -% -\leftedline{|\meaning\x:|\dtt{\meaning\X}} -% -\leftedline{|\edef\y{\xintRevWithBraces\x}|} -% -\leftedline{|\meaning\y:|\dtt{\meaning\y}} -% -The examples above could be defined with |\edef|'s because the braced material -did not contain macros. Alternatively: -% -\leftedline{|\expandafter\def\expandafter\w\expandafter|} +\leftedline{|\xintthefloatexpr + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax|} % -\leftedline{|{\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}}|} +\leftedline{\dtt{\xintthefloatexpr + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax}} +% 0.00564487459334466559166166079096852897 % -\leftedline{|\meaning\w:|\dtt{\meaning\w}} +\leftedline{|\xintthefloatexpr\xintexpr + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax\relax|} % -The macro \csa{xintReverseWithBracesNoExpand}\etype{n} does the same job -without the initial expansion of its argument. - - -\subsection{\csh{xintZapFirstSpaces}, \csh{xintZapLastSpaces}, \csh{xintZapSpaces}, \csh{xintZapSpacesB}} -\label{xintZapFirstSpaces} -\label{xintZapLastSpaces} -\label{xintZapSpaces} -\label{xintZapSpacesB} -%{\small New with release |1.09f|.\par} - -\csa{xintZapFirstSpaces}\marg{stuff}\etype{n} does not do \emph{any} expansion -of its argument, nor brace removal of any sort, nor does it alter \meta{stuff} -in anyway apart from stripping away all \emph{leading} spaces. - -This macro will be mostly of interest to programmers who will know what I will -now be talking about. \emph{The essential points, naturally, are the complete - expandability and the fact that no brace removal nor any other alteration is - done to the input.} +\leftedline{\dtt{\xintthefloatexpr\xintexpr + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax\relax}} -\TeX's input scanner already converts consecutive blanks into single space -tokens, but |\xintZapFirstSpaces| handles successfully also inputs with -consecutive multiple space tokens. -However, it is assumed that \meta{stuff} does not contain (except inside braced -sub-material) space tokens of character code distinct from $32$. +\xintDigits := 16; -It expands in two steps, and if the goal is to apply it to the -expansion text of |\x| to define |\y|, then one can do: -|\odef\y{\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}| -(one can also define a wrapper macro to |\xintZapFirstSpaces| in order to -expand once the argument first, but \xinttoolsname not being a programming -layer, it provides no «Generate Variants» facilities). +The latter is the rounding of the exact result. The former one has +its last three digits wrong due to the cumulative effect of rounding errors +in the intermediate computations, as compared to exact evaluations. -Other use case: inside a macro which received a parameter |#1|, one can do -|\oodef\x{\xintZapFirstSpaces {#1}}|, or, if |#1|, after leading spaces have -been stripped can accept |\edef| expansion, one can do -|\edef\x{\xintZapFirstSpaces{#1}}|. -\begingroup -\def\x { \a { \X } { \b \Y } } -% -\leftedline{|\xintZapFirstSpaces { \a { \X } { \b \Y } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}}+++} -\endgroup -\medskip -\noindent\csbxint{ZapLastSpaces}\marg{stuff}\etype{n} does not do \emph{any} expansion of -its argument, nor brace removal of any sort, nor does it alter \meta{stuff} in -anyway apart from stripping away all \emph{ending} spaces. The same remarks as -for \csbxint{ZapFirstSpaces} apply. +I recall here from \autoref{ssec:floatingpoint} that with release |1.2f| the +float macros for addition, subtraction, multiplication and division round +their arguments first to |P| significant places with |P| the asked-for +precision of the output; and similarly the power macros and the +square root macro. This does not modify anything for computations with +arguments having at most |P| significant places already. -\begingroup -\def\x { \a { \X } { \b \Y } } -% -\leftedline{|\xintZapLastSpaces { \a { \X } { \b \Y } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzaplastspaces\expandafter{\x}}}+++} -\endgroup +\subsection{\csh{xinteval}, \csh{xintieval}, \csh{xintiieval}, + \csh{xintfloateval}} +\label{xinteval}\label{xintieval}\label{xintiieval}\label{xintfloateval} -\medskip +\csbxint{eval}\etype{x} is an \fexpan dable macro which is basically defined +like this (DON'T BELIEVE THIS; it has been entirely revamped at |1.4|): +\begin{everbatim} +\def\xinteval#1{\romannumeral-`0\xinttheexpr#1\relax}% OLD DEFINITION < 1.4 +\end{everbatim} +thus expands in two steps (its exact definition differs from the one given +above in order to achieve a slight optimization). +\begin{everbatim*} +\xinteval{add(x^2, x = 100..110), add(x^3, x = 100..110)} +\end{everbatim*} -\noindent\csbxint{ZapSpaces}\marg{stuff}\etype{n} does not do \emph{any} -expansion of its -argument, nor brace removal of any sort, nor does it alter \meta{stuff} in -anyway apart from stripping away all \emph{leading} and all \emph{ending} -spaces. The same remarks as for \csbxint{ZapFirstSpaces} apply. +\csbxint{ieval}\etype{x} is similarly related to \csbxint{theiexpr}. Its optional +argument must be located inside the braces: +\begin{everbatim*} +\xintieval{[7] 355/113} +\end{everbatim*} -\begingroup -\def\x { \a { \X } { \b \Y } } -% -\leftedline{|\xintZapSpaces { \a { \X } { \b \Y } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapspaces\expandafter{\x}}}+++} -\endgroup +\csbxint{iieval}\etype{x} is similarly related to \csbxint{theiiexpr}. +\begin{everbatim*} +\xintiieval{add(x^2, x = 100..110), add(x^3, x = 100..110)} +\end{everbatim*} -\medskip +\csbxint{floateval}\etype{x} is similarly related to \csbxint{thefloatexpr}. Its optional +argument must be located inside the braces: +\begin{everbatim*} +\xintfloateval{[7] 355/113} +\end{everbatim*} -\noindent\csbxint{ZapSpacesB}\marg{stuff}\etype{n} does not do \emph{any} -expansion of -its argument, nor does it alter \meta{stuff} in anyway apart from stripping away -all leading and all ending spaces and possibly removing one level of braces if -\meta{stuff} had the shape |{braced}|. The same remarks as for -\csbxint{ZapFirstSpaces} apply. +When negative it tells how many digits to remove from the prevailing precision +(\csbxint{theDigits}): +\begin{everbatim*} +\xintfloateval{[-2] 355/113} has \xinttheDigits\ minus 2 digits. +\end{everbatim*} -\begingroup -\def\x { \a { \X } { \b \Y } } -% -\leftedline{|\xintZapSpacesB { \a { \X } { \b \Y } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++} -\def\x { { \a { \X } { \b \Y } } } -% -\leftedline{|\xintZapSpacesB { { \a { \X } { \b \Y } } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++} -\endgroup - The spaces here at the start and end of the output come from the braced - material, and are not removed (one would need a second application for that; - recall though that the \xintname zapping macros do not expand their argument). +These macros are useful when one uses some extra wrapper doing some parsing of +its input, like the |\num| macro of +\href{http://ctan.org/pkg/siunitx}{siunitx}, which would choke on some of the +syntax elements allowed inside \csb{xintexpr}|...\relax| (for example +brackets). +As shown in the above examples, these macros, like the underlying parsers +accept arbitrarily many comma separated expressions. -\subsection{\csh{xintCSVtoList}} -\label{xintCSVtoList} -\label{xintCSVtoListNoExpand} +\subsection{Using an expression parser within another one} -\csa{xintCSVtoList}|{a,b,c...,z}|\etype{f} returns |{a}{b}{c}...{z}|. A -\emph{list} is by -convention in this manual simply a succession of tokens, where each braced thing -will count as one item (``items'' are defined according to the rules of \TeX{} -for fetching undelimited parameters of a macro, which are exactly the same rules -as for \LaTeX{} and macro arguments [they are the same things]). The word -`list' in `comma separated list of items' has its usual linguistic meaning, -and then an ``item'' is what is delimited by commas. +This was already illustrated before. In the following: +\begin{everbatim*} +\xintfloatexpr \xintexpr add(1/i, i=1234..1243)\relax ^100\relax +\end{everbatim*}, +the inner sum is computed exactly. Then it will be rounded to |\xinttheDigits| +significant digits, and then its power will be evaluated as a float operation. +One should avoid the "|\xintthe|" parsers in inner positions as this induces +digit by digit parsing of the inner computation result by the outer parser. +Here is the same computation done with floats all the way: +\begin{everbatim*} +\xintfloatexpr add(1/i, i=1234..1243)^100\relax +\end{everbatim*} -So \csa{xintCSVtoList} takes on input a `comma separated list of items' and -converts it into a `\TeX{} list of braced items'. The argument to -|\xintCSVtoList| may be a macro: it will first be -\hyperref[ssec:expansions]{\fexpan ded}. Hence the item before the first comma, -if it is itself a macro, will be expanded which may or may not be a good thing. -A space inserted at the start of the first item serves to stop that expansion -(and disappears). The macro \csbxint{CSVtoListNoExpand}\etype{n} does the same -job without -the initial expansion of the list argument. +Not surprisingly this differs from the previous one which was exact until +raising to the |100|th power. -Apart from that no expansion of the items is done and the list items may thus be -completely arbitrary (and even contain perilous stuff such as unmatched |\if| -and |\fi| tokens). +The fact that the inner expression occurs inside a bigger one has nil +influence on its behaviour. There is the limitation though that the outputs +from \csbxint{expr} and \csbxint{floatexpr} can not be used directly in +\csbxint{theiiexpr} integer-only parser. But one can do: +\begin{everbatim*} +\xintiiexpr round(\xintfloatexpr 3.14^10\relax)\relax % or trunc +\end{everbatim*} -Contiguous spaces and tab characters, are collapsed by \TeX{} -into single spaces. All such spaces around commas% -% -\footnote{and multiple space tokens are not a problem; but those at the - top level (not hidden inside braces) \emph{must} be of character code - |32|.} -% -\fbox{are removed}, as well as -the spaces at the start and the spaces at the end of the list.% -% -\footnote{let us recall that this is all done completely expandably... - There is absolutely no alteration of any sort of the item apart from - the stripping of initial and final space tokens (of character code - |32|) and brace removal if and only if the item apart from intial and - final spaces (or more generally multiple |char 32| space tokens) is - braced.} -% -The items may contain explicit |\par|'s or -empty lines (converted by the \TeX{} input parsing into |\par| tokens). -\begingroup +\subsection{The \csh{xintthecoords} macro} +\label{xintthecoords} -\edef\X{\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , { {x , - y} } }} +It converts (in two expansion steps) the expansion result of +\csbxint{floatexpr} (or \csbxint{expr} or \csbxint{iiexpr}) into the |(a, b) +(c, d) ...| format for list of coordinates as expected by the |TikZ| +|coordinates| syntax.% +\begin{everbatim*} +\begin{figure}[htbp] +\centering\begin{tikzpicture}[scale=10]\xintDigits:=8\relax + \clip (-1.1,-.25) rectangle (.3,.25); + \draw [blue] (-1.1,0)--(1,0); + \draw [blue] (0,-1)--(0,+1); + \draw [red] plot[smooth] coordinates {% +%%% (\xintthecoords converts output of next expression into (x1, y1) (x2, y2)... format) + \xintthecoords\xintfloatexpr +%%% This syntax -1+[0..4]/2 is currenty dropped at xint 1.4 +%%% seq((x^2-1,mul(x-t,t=-1+[0..4]/2)),x=-1.2..[0.1]..+1.2)\relax +%%% Use this: + seq((x^2-1,mul(x-t,t=seq(-1+u/2, u=0..4))),x=-1.2..[0.1]..+1.2) + \relax + }; +\end{tikzpicture} +\caption{Coordinates with \cs{xintthecoords}.} +\end{figure} +\end{everbatim*} -% -\leftedline{|\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , - { {x , y} } }|} -% -\leftedline{|->|% -{\makeatletter\dtt{\expandafter\strip@prefix\meaning\X}}} +% Notice: if x goes not take exactly value 1 or -1, the origin appears slightly +% off the curve, not MY fault!!! +It is currently undecided how \csa{xintthecoords} should handle +bracketed data.\UNSTABLE{} -One sees on this example how braces protect commas from -sub-lists to be perceived as delimiters of the top list. Braces around an entire -item are removed, even when surrounded by spaces before and/or after. Braces for -sub-parts of an item are not removed. +\subsection{The \csh{xintthespaceseparated} macro} +\label{xintthespaceseparated} -We observe also that there is a slight difference regarding the brace stripping -of an item: if the braces were not surrounded by spaces, also the initial and -final (but no other) spaces of the \emph{enclosed} material are removed. This is -the only situation where spaces protected by braces are nevertheless removed. +It converts (in two expansion steps)\NewWith{1.4a} the expansion result of +\csbxint{floatexpr} (or \csbxint{expr} or \csbxint{iiexpr}) into the space +separated format suitable for usage with |PS-Tricks| |\listplot| macro. +\begin{everbatim*} +\oodef\foo{\xintthespaceseparated\xintfloatexpr [4] 1..10\relax} +\meaning\foo +\end{everbatim*} -From the rules above: for an empty argument (only spaces, no braces, no comma) -the output is -\dtt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist { }}} -(a list with one empty item), -for ``|{}|'' the output is -\dtt{\expandafter\detokenize\expandafter - {\romannumeral0\xintcsvtolist { {} }}} -(again a list with one empty item, the braces were removed), -for ``|{ }|'' the output is -\dtt{\expandafter\detokenize\expandafter - {\romannumeral0\xintcsvtolist {{ }}}} -(again a list with one empty item, the braces were removed and then -the inner space was removed), -for ``| { }|'' the output is -\dtt{\expandafter\detokenize\expandafter -{\romannumeral0\xintcsvtolist { { }}}} (again a list with one empty item, the initial space served only to stop the expansion, so this was like ``|{ }|'' as input, the braces were removed and the inner space was stripped), -for ``\texttt{\ \{\ \ \}\ }'' the output is -\dtt{\expandafter\detokenize\expandafter -{\romannumeral0\xintcsvtolist { { } }}} (this time the ending space of the first -item meant that after brace removal the inner spaces were kept; recall though -that \TeX{} collapses on input consecutive blanks into one space token), -for ``|,|'' the output consists of two consecutive -empty items -\dtt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist - {,}}}. Recall that on output everything is braced, a |{}| is an ``empty'' -item. -% -Most of the above is mainly irrelevant for every day use, apart perhaps from the -fact to be noted that an empty input does not give an empty output but a -one-empty-item list (it is as if an ending comma was always added at the end of -the input). +It is currently undecided how \csa{xintthespaceseparated} should handle +bracketed data.\UNSTABLE{} -\def\y { \a,\b,\c,\d,\e} -\expandafter\def\expandafter\Y\expandafter{\romannumeral0\xintcsvtolist{\y}} -\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode} -\expandafter\def\expandafter\T\expandafter{\romannumeral0\xintcsvtolist{\t}} +\subsection{\csh{xintifboolexpr}, \csh{xintifboolfloatexpr}, \csh{xintifbooliiexpr}} +\label{xintifboolexpr} +\label{xintifboolfloatexpr} +\label{xintifbooliiexpr} -% -\leftedline{|\def\y{ \a,\b,\c,\d,\e} \xintCSVtoList\y->|% - {\makeatletter\dtt{\expandafter\strip@prefix\meaning\Y}}} -% -\leftedline{|\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} -% -\leftedline -{|\xintCSVtoList\t->|\makeatletter\dtt{\expandafter\strip@prefix\meaning\T}} -% -The results above were automatically displayed using \TeX's primitive -\csa{meaning}, which adds a space after each control sequence name. These spaces -are not in the actual braced items of the produced lists. The first items |\a| -and |\if| were either preceded by a space or braced to prevent expansion. The -macro \csa{xintCSVtoListNoExpand} would have done the same job without the -initial expansion of the list argument, hence no need for such protection but if -|\y| is defined as |\def\y{\a,\b,\c,\d,\e}| we then must do: -% -\leftedline{|\expandafter\xintCSVtoListNoExpand\expandafter {\y}|} Else, we -may have direct use: % -% -\leftedline{|\xintCSVtoListNoExpand - {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} -% -\leftedline{|->|\dtt{\expandafter\detokenize\expandafter - {\romannumeral0\xintcsvtolistnoexpand - {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}}}} -% -Again these spaces are an artefact from the use in the source of the document of -\csa{meaning} (or rather here, \csa{detokenize}) to display the result of using -\csa{xintCSVtoListNoExpand} (which is done for real in this document -source). +\csh{xintifboolexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does +\csbxint{theexpr}|\relax| and then executes the \meta{YES} or the +\meta{NO} branch depending on whether the outcome was non-zero or zero. Thus +one can read \emph{if bool expr} as meaning \emph{if not zero}: +\centeredline{if \meta{expr}-ession does not vanish do \meta{YES} else do + \meta{NO}} -For the similar conversion from comma separated list to braced items list, but -without removal of spaces around the commas, there is -\csa{xintCSVtoListNonStripped}\etype{f} and -\csa{xintCSVtoListNonStrippedNoExpand}\etype{n}. +The expression is not limited to using only comparison operators and Boolean +logic (|<|, |>|, |==|, |!=|, |&&|, \verb+||+, \func{all}, \func{any}, +\func{xor}, \func{bool}, \func{togl}, ...), it can be the most general +computation. -\endgroup +\csh{xintifboolfloatexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does +\csbxint{thefloatexpr}\meta{expr}|\relax| and then executes the \meta{YES} or the +\meta{NO} branch depending on whether the outcome was non zero or zero. -\subsection{\csh{xintNthElt}}\label{xintNthElt} +\csh{xintifbooliiexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does +\csbxint{theiiexpr}\meta{expr}|\relax| and then executes the \meta{YES} or the +\meta{NO} branch depending on whether the outcome was non zero or zero. +The expression argument must be a single one, comma separated sub-expressions +will cause low-level errors. -\def\macro #1{\the\numexpr 9-#1\relax} +\subsection{\csh{xintifsgnexpr}, \csh{xintifsgnfloatexpr}, \csh{xintifsgniiexpr}} +\label{xintifsgnexpr} +\label{xintifsgnfloatexpr} +\label{xintifsgniiexpr} -\csa{xintNthElt\x}\marg{list}\etype{\numx f} gets (expandably) the |x|th -item of the \meta{list}. A braced item will lose one level of brace -pairs. The token list is first \fexpan ded. +\csh{xintifsgnexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates +the \csbxint{expr}ession and chooses the branch corresponding to its sign. -Items are counted starting at one. +\csh{xintifsgnfloatexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates +the \csbxint{floatexpr}ession and chooses the branch corresponding to its sign. -\leftedline{|\xintNthElt {3}{{agh}\u{zzz}\v{Z}}| is - \texttt{\xintNthElt {3}{{agh}\u{zzz}\v{Z}}}} -% -\leftedline{|\xintNthElt {3}{{agh}\u{{zzz}}\v{Z}}| is - \texttt{\expandafter\expandafter\expandafter - \detokenize\expandafter\expandafter\expandafter {\xintNthElt - {3}{{agh}\u{{zzz}}\v{Z}}}}} -% -\leftedline{|\xintNthElt {2}{{agh}\u{{zzz}}\v{Z}}| is - \texttt{\expandafter\expandafter\expandafter - \detokenize\expandafter\expandafter\expandafter {\xintNthElt - {2}{{agh}\u{{zzz}}\v{Z}}}}} -% -\leftedline{|\xintNthElt {37}{\xintiiFac {100}}|\dtt{=\xintNthElt - {37}{\xintiiFac {100}}} is the thirty-seventh digit of $100!$.} -% -\leftedline{|\xintNthElt {10}{\xintFtoCv - {566827/208524}}|\dtt{=\xintNthElt {10}{\xintFtoCv - {566827/208524}}}} -\leftedline{is the tenth convergent of $566827/208524$ (uses \xintcfracname - package).} +\csh{xintifsgniiexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates +the \csbxint{iiexpr}ession and chooses the branch corresponding to its sign. + +The expression argument must be a single one, comma separated sub-expressions +will cause low-level errors. + +\subsection{The \csh{xintNewExpr}, \csh{xintNewIIExpr}, + \csh{xintNewFloatExpr}, \csh{xintNewIExpr}, and \csh{xintNewBoolExpr} + macros} +\label{xintNewExpr} +\label{xintNewIIExpr} +\label{xintNewFloatExpr} +\label{xintNewIExpr} +\label{xintNewBoolExpr} + +\csbxint{NewExpr} macro is used as: % -\leftedline{|\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% - \dtt{=\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} +\leftedline{|\xintNewExpr{\myformula}[n]|\marg{stuff}, where} +\begin{itemize} +\item \meta{stuff} will be inserted inside |\xinttheexpr . . . \relax|, +\item |n| is an integer between zero and nine, inclusive, which is the number + of parameters of |\myformula|, +\item the placeholders |#1|, |#2|, ..., |#n| are used inside \meta{stuff} in + their usual r\^ole,% % -\leftedline{|\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% - \dtt{=\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} +\catcode`# 12 +\footnote{if \csa{xintNewExpr} is used inside a macro, + the |#|'s must be doubled as usual.} + \footnote{the |#|'s will in pratice have their usual + catcode, but category code other |#|'s are accepted too.} +\catcode`# 6 % -\leftedline{|\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% - \dtt{=\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} +\item the |[n]| is \emph{mandatory}, even for |n=0|.% +\footnote{there is some use for \csa{xintNewExpr}|[0]| compared to an + \csa{edef} as \csa{xintNewExpr} has some built-in catcode protection.} +\item the macro |\myformula| is defined without checking if it already exists, + \LaTeX{} users might prefer to do first |\newcommand*\myformula {}| to get a + reasonable error message in case |\myformula| already exists, +\item the protection against active characters is done automatically (as long + as the whole thing has not already been fetched as a macro argument and + the catcodes correspondingly already frozen). +\end{itemize} -If |x=0|, -the macro returns the \emph{length} of the expanded list: this is not equivalent -to \csbxint{Length} which does no pre-expansion. And it is different from -\csbxint{Len} which is to be used only on integers or fractions. +It (if it succeeds) will be a completely expandable macro entirely built-up using |\xintAdd|, +|\xintSub|, |\xintMul|, |\xintDiv|, |\xintPow|, etc\dots as corresponds to the +expression written with the infix operators. +Macros created by |\xintNewExpr| can thus be nested. -If |x<0|, the macro returns the \verb+|x|+th element from the end of the list. -Thus for example |x=-1| will fetch the last item of the list. -% -\leftedline {|\xintNthElt {-5}{{{agh}}\u{zzz}\v{Z}}| is - \texttt{\expandafter\expandafter\expandafter \detokenize - \expandafter\expandafter\expandafter{\xintNthElt {-5}{{{agh}}\u{zzz}\v{Z}}}}} +\begin{everbatim*} + \xintNewFloatExpr \FA [2]{(#1+#2)^10} + \xintNewFloatExpr \FB [2]{sqrt(#1*#2)} +\begin{enumerate}[nosep] + \item \FA {5}{5} + \item \FB {30}{10} + \item \FA {\FB {30}{10}}{\FB {40}{20}} +\end{enumerate} +\end{everbatim*} -The macro \csa{xintNthEltNoExpand}\etype{\numx n} does the same job but without -first expanding the list argument: |\xintNthEltNoExpand {-4}{\u\v\w T\x\y\z}| is -\xintNthEltNoExpand {-4}{\a\b\c\u\v\w T\x\y\z}. +The documentation is much shortened here because \csbxint{NewExpr} and \csbxint{deffunc} +are very much related one with the other. -If |x| is strictly larger (in absolute value) than the length of the list -then |\xintNthElt| produces empty contents. +\begin{framed} + ATTENTION! -\subsection{\csh{xintNthOnePy}} -\label{xintNthOnePy} + The original spirit of \csbxint{NewExpr} was to define a (possibly very big) + macro using only \xintfracname, and this means in particular that it must be + used only with arguments compatible with the \xintfracname input + format.\IMPORTANTf -\csa{xintNthOnePy\x}\marg{list}\etype{\numx f} gets (expandably) the |x|th -item of the \meta{list}, adding a brace pair if there wasn't one.\NewWith{1.4} + Thus an |\xintexpr| declared variable has no chance to work, it must be + wrapped explicitly in |\xinteval{...}| to be fetched as argument to a macro + constructed by \csbxint{NewExpr}. +\end{framed} -Attention, items are counted starting at zero. For negative index, behaves -as \csbxint{NthElt}. +They share essentially the same limitations. -If the index is out of range, the empty output is returned. If the input list -was empty (had no items) the empty output is returned. +Notice though that \csbxint{NewFloatExpr} accepts and recognizes the optional +argument |[Q]| of \csbxint{floatexpr}, contrarily to \csbxint{deffloatfunc}. +Use an |\empty| in case the contents are not known in advance. -\subsection{\csh{xintKeep}}\label{xintKeep} -\csa{xintKeep\x}\marg{list}\etype{\numx f} expands the token list argument |L| -and produces a new list, depending on the value of |x|: -\begin{itemize}[nosep] -\item if |x>0|, the new list contains the first |x| items from |L| (counting - starts at one.) \emph{Each - such item will be output within a brace pair.} Use \csbxint{KeepUnbraced} if - this is not desired. This means that if the list item was braced to start - with, there is no modification, but if it was a token without braces, - then it acquires them. -\item if |x>=length(L)|, the new list is the old one with all its items now - braced. -\item if |x=0| the empty list is returned. -\item if |x<0| the last \verb+|x|+ elements compose the output in the same - order as in the initial list; as the macro proceeds by removing head items - the kept items end up in output as they were in input: no added braces. -\item if |x<=-length(L)| the output is identical with the input. -\end{itemize} +Historical note: prior to |1.4|, \xintexprname used a |\csname..\endcsname| +encapsulation technique which impacted the string pool memory. The +\csbxint{NewExpr} was designed as a method to pre-parse the expression and +produce one single, gigantic, nested usage of the relevant \xintfracname +macros. This way, only those macros were expanded which had nil impact on the +\TeX{} string pool. -\csa{xintKeepNoExpand} does the same without first \fexpan ding its list -argument. +Later on it was found that this mechanism could be employed to define +functions. Basically underneath |98%| of \csbxint{NewExpr} and +\csbxint{deffunc} are using the same shared code. + +\xintDigits:= 16\relax + +\subsection{Analogies and differences of \csh{xintiiexpr} with \csh{numexpr}} + +\csbxint{iiexpr}|..\relax| is a parser of expressions knowing only (big) +integers. There are, besides the enlarged range of allowable inputs, some +important differences of syntax between |\numexpr| and |\xintiiexpr| and +variants: +\begin{itemize} +\item Contrarily to |\numexpr|, the |\xintiiexpr| parser will stop expanding + only after having encountered (and swallowed) a \emph{mandatory} |\relax| + token. +\item In particular, spaces between digits (and not only around infix + operators or parentheses) do not stop |\xintiiexpr|, contrarily to the + situation with |numexpr|: |\the\numexpr 7 + 3 5\relax| expands (in one + step)% % -\begin{everbatim*} -\fdef\test {\xintKeep {17}{\xintKeep {-69}{\xintSeq {1}{100}}}}\meaning\test\par -\noindent\fdef\test {\xintKeep {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintKeep {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintKeep {7}{123456789}}\meaning\test\par -\noindent\fdef\test {\xintKeep {-7}{123456789}}\meaning\test\par -\end{everbatim*} +\footnote {The |\numexpr| triggers continued expansion after the space + following the |3| to check if some operator like |+| is upstream. But + after having found the |5| it treats it as and end-marker.} +% + to \dtt{\detokenize\expandafter{\the\numexpr 7 + 3 5\relax}\unskip}, whereas + |\xintthe\xintiiexpr 7 + 3 5\relax| expands (in two steps) to + \dtt{\detokenize\expandafter\expandafter\expandafter {\xintthe\xintiiexpr 7 + + 3 5\relax}}.% +% +\footnote {Since |1.2l| one can also use the underscore |_| to separate digits +for readability of long numbers.} +\item Inside an |\edef|, an expression |\xintiiexpr...\relax| get fully + evaluated, whereas |\numexpr| without |\the| or |\number| prefix would not, + if not itself embedded in another |\the\numexpr| or similar context. +\item (ctd.) The private format to which |\xintiiexpr...\relax| (et al.) + evaluates may use |\xintthe| prefix to turn into explicit digits, + (for example in arguments to some macros which expand their arguments). The |\the| \TeX\ primitive prefix would + not work here. +\item (ctd.) One can embed a |\numexpr...\relax| (with its |\relax|!) inside an + |\xintiiexpr...\relax| without |\the| or |\number|, but the reverse situation + requires usage of |\xintthe| or \csbxint{eval} user interface, +\item |\numexpr -(1)\relax| is illegal. In contrast |\xintiiexpr -(1)\relax| is + perfectly legal and gives the expected result (what else ?). +\item |\numexpr 2\cnta\relax| is illegal (with |\cnta| a |\count| register.) + In contrast + |\xintiiexpr 2\cnta\relax| is perfectly legal and will do the tacit + multiplication. +\item |\the\numexpr| or |\number\numexpr| expands in one step, but + |\xintthe\xintiiexpr| or |\xinttheiiexpr| needs two steps. +\end{itemize} -\subsection{\csh{xintKeepUnbraced}}\label{xintKeepUnbraced} +\subsection{Chaining expressions for expandable algorithmics} +\label{ssec:fibonacci} -Same as \csbxint{Keep} but no brace pairs are added around the kept items from -the head of the list in the case |x>0|: each such item will lose one level of -braces. Thus, to remove braces from all items of the list, one can use -\csbxint{KeepUnbraced} with its first argument larger than the length of the -list; the same is obtained from \csbxint{ListWithSep}|{}|\marg{list}. But the -new list will then have generally many more items than the original ones, -corresponding to the unbraced original items. +We will see in this section how to chain |\xintexpr|-essions with +|\expandafter|'s, like it is possible with |\numexpr|. For this it is +convenient to use |\romannumeral0\xintexpro| which is the once-expanded form of +|\xintexpr|, as we can then chain using only one |\expandafter| each time. -For |x<0| the macro is no different from \csbxint{Keep}. Hence the name is a -bit misleading because brace removal will happen only if |x>0|. +For example, here is the code employed +on the title page to compute (expandably, of course!) the 1250th Fibonacci +number: -\csa{xintKeepUnbracedNoExpand} does the same without first \fexpan ding -its list argument. -% \begin{everbatim*} -\fdef\test {\xintKeepUnbraced {10}{\xintSeq {1}{100}}}\meaning\test\par -\noindent\fdef\test {\xintKeepUnbraced {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintKeepUnbraced {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintKeepUnbraced {7}{123456789}}\meaning\test\par -\noindent\fdef\test {\xintKeepUnbraced {-7}{123456789}}\meaning\test\par +\catcode`_ 11 +\def\Fibonacci #1{% \Fibonacci{N} computes F(N) with F(0)=0, F(1)=1. + \expandafter\Fibonacci_a\expandafter + {\the\numexpr #1\expandafter}\expandafter + {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter + {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter + {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter + {\romannumeral0\xintiiexpro 0\relax}} +% +\def\Fibonacci_a #1{% + \ifcase #1 + \expandafter\Fibonacci_end_i + \or + \expandafter\Fibonacci_end_ii + \else + \ifodd #1 + \expandafter\expandafter\expandafter\Fibonacci_b_ii + \else + \expandafter\expandafter\expandafter\Fibonacci_b_i + \fi + \fi {#1}% +}% * signs are omitted from the next macros, tacit multiplications +\def\Fibonacci_b_i #1#2#3{\expandafter\Fibonacci_a\expandafter + {\the\numexpr #1/2\expandafter}\expandafter + {\romannumeral0\xintiiexpro sqr(#2)+sqr(#3)\expandafter\relax\expandafter}\expandafter + {\romannumeral0\xintiiexpro (2#2-#3)#3\relax}% +}% end of Fibonacci_b_i +\def\Fibonacci_b_ii #1#2#3#4#5{\expandafter\Fibonacci_a\expandafter + {\the\numexpr (#1-1)/2\expandafter}\expandafter + {\romannumeral0\xintiiexpro sqr(#2)+sqr(#3)\expandafter\relax\expandafter}\expandafter + {\romannumeral0\xintiiexpro (2#2-#3)#3\expandafter\relax\expandafter}\expandafter + {\romannumeral0\xintiiexpro #2#4+#3#5\expandafter\relax\expandafter}\expandafter + {\romannumeral0\xintiiexpro #2#5+#3(#4-#5)\relax}% +}% end of Fibonacci_b_ii +% code as used on title page: +%\def\Fibonacci_end_i #1#2#3#4#5{\xintthe#5} +%\def\Fibonacci_end_ii #1#2#3#4#5{\xinttheiiexpr #2#5+#3(#4-#5)\relax} +% new definitions: +\def\Fibonacci_end_i #1#2#3#4#5{{#4}{#5}}% {F(N+1)}{F(N)} in \xintexpr format +\def\Fibonacci_end_ii #1#2#3#4#5% + {\expandafter + {\romannumeral0\xintiiexpro #2#4+#3#5\expandafter\relax + \expandafter}\expandafter + {\romannumeral0\xintiiexpro #2#5+#3(#4-#5)\relax}}% idem. +% \FibonacciN returns F(N) (in encapsulated format: needs \xintthe for printing) +\def\FibonacciN {\expandafter\xint_secondoftwo\romannumeral-`0\Fibonacci }% +\catcode`_ 8 \end{everbatim*} -\subsection{\csh{xintTrim}}\label{xintTrim} -\csa{xintTrim\x}\marg{list}\etype{\numx f} expands the list argument and -gobbles its first |x| elements. -\begin{itemize}[nosep] -\item if |x>0|, the first |x| items from |L| are gobbled. The remaining items - are not modified. -\item if |x>=length(L)|, the returned list is empty. -\item if |x=0| the original list is returned (with no added braces.) -\item if |x<0| the last \verb+|x|+ items of the list are removed. \emph{The - head items end up braced in the output.} Use \csbxint{TrimUnbraced} if - this is not desired. -\item if |x<=-length(L)| the output is empty. -\end{itemize} +The macro |\Fibonacci| produces not one specific value |F(N)| but a pair of +successive values |{F(N)}{F(N+1)}| which can then serve as starting point of +another routine devoted to compute a whole sequence |F(N), F(N+1), +F(N+2),....|. Each of |F(N)| and |F(N+1)| is kept in the encapsulated internal +\xintexprname format. -\csa{xintTrimNoExpand} does the same without first \fexpan ding its list -argument. -\begin{everbatim*} -\fdef\test {\xintTrim {17}{\xintTrim {-69}{\xintSeq {1}{100}}}}\meaning\test\par -\noindent\fdef\test {\xintTrim {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintTrim {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintTrim {7}{123456789}}\meaning\test\par -\noindent\fdef\test {\xintTrim {-7}{123456789}}\meaning\test\par -\end{everbatim*} +|\FibonacciN| produces the single |F(N)|. It also keeps it in the private +format; thus printing it will need the |\xintthe| prefix. -\subsection{\csh{xintTrimUnbraced}}\label{xintTrimUnbraced} +\begingroup\footnotesize\sffamily\baselineskip 10pt +Here a code snippet which +checks the routine via a \string\message\ of the first $51$ Fibonacci +numbers (this is not an efficient way to generate a sequence of such +numbers, it is only for validating \csa{FibonacciN}). +% +\begin{everbatim} +\def\Fibo #1.{\xintthe\FibonacciN {#1}}% +\message{\xintiloop [0+1] \expandafter\Fibo\xintiloopindex., + \ifnum\xintiloopindex<49 \repeat \xintthe\FibonacciN{50}.} +\end{everbatim} +\endgroup -Same as \csbxint{Trim} but in case of a negative |x| (cutting items from -the tail), the kept items from the head are not enclosed in brace pairs. They -will lose one level of braces. The name is a bit misleading -because when |x>0| there is no brace-stripping done on the kept items, because -the macro works simply by gobbling the head ones. +The way we use |\expandafter|'s to chain successive |\xintiiexpro| evaluations +is exactly analogous to what is possible with |\numexpr|. The various +|\romannumeral0\xintiiexpro| could very well all have been |\xintiiexpr|'s but +then we would have needed |\expandafter\expandafter\expandafter| each +time. -\csa{xintTrimUnbracedNoExpand} does the same without first \fexpan ding its list -argument. +\begin{framed} + There is a difference though: |\numexpr| does \emph{NOT} expand inside an + |\edef|, and to force its expansion we must prefix it with |\the| or + |\number| or |\romannumeral| or another |\numexpr| which is itself prefixed, + etc\dots. -\begin{everbatim*} -\fdef\test {\xintTrimUnbraced {-90}{\xintSeq {1}{100}}}\meaning\test\par -\noindent\fdef\test {\xintTrimUnbraced {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintTrimUnbraced {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintTrimUnbraced {7}{123456789}}\meaning\test\par -\noindent\fdef\test {\xintTrimUnbraced {-7}{123456789}}\meaning\test\par -\end{everbatim*} + But |\xintexpr|, |\xintiexpr|, ..., expand fully in an |\edef|, with the + completely expanded + result encapsulated in a private format. -\subsection{\csh{xintListWithSep}}\label{xintListWithSep} + Using |\xintthe| as prefix is necessary to print the result (like |\the| or + |\number| in the case of |\numexpr|), but it is not necessary to get the + computation done (contrarily to the situation with |\numexpr|). +\end{framed} -\def\macro #1{\the\numexpr 9-#1\relax} +Our |\Fibonacci| expands completely under \fexpan sion, so we can use +\hyperref[fdef]{\ttfamily\char92fdef} rather than |\edef| in a situation such +as +% +\leftedline {|\fdef \X {\FibonacciN {100}}|} +% +but it is usually about as efficient to employ |\edef|. And if we want +% +\leftedline{|\edef \Y {(\FibonacciN{100},\FibonacciN{200})}|,} +% +then |\edef| is necessary. -\csa{xintListWithSep}\marg{sep}\marg{list}\etype{nf} inserts the separator -\meta{sep} in-between all items of the given list of braced items (or -individual tokens). The items are fetched as does \TeX\ with undelimited macro -arguments, thus they end up unbraced in output. If the \meta{list} is only one -(or multiple) space tokens, the output is empty. +Allright, so let's now give the code to generate |{F(N)}{F(N+1)}{F(N+2)}...|, +using |\Fibonacci| for the first two and then using the standard recursion +|F(N+2)=F(N+1)+F(N)|: -The list argument \meta{list} gets \fexpan ded first (thus if it is a macro -whose contents are braced items, the first opening brace stops the expansion, -and it is as if the macro had been expanded once.) The separator \meta{sep} is -not pre-expanded, it ends up as is in the output (if the \meta{list} contained -at least two items.) +\catcode`_ 11 +\def\FibonacciSeq #1#2{%#1=starting index, #2>#1=ending index + \expandafter\Fibonacci_Seq\expandafter + {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2-1}% +}% +\def\Fibonacci_Seq #1#2{% + \expandafter\Fibonacci_Seq_loop\expandafter + {\the\numexpr #1\expandafter}\romannumeral0\Fibonacci {#1}{#2}% +}% +\def\Fibonacci_Seq_loop #1#2#3#4{% standard Fibonacci recursion + {#3}\unless\ifnum #1<#4 \Fibonacci_Seq_end\fi + \expandafter\Fibonacci_Seq_loop\expandafter + {\the\numexpr #1+1\expandafter}\expandafter + {\romannumeral0\xintiiexpro #2+#3\relax}{#2}{#4}% +}% +\def\Fibonacci_Seq_end\fi\expandafter\Fibonacci_Seq_loop\expandafter + #1\expandafter #2#3#4{\fi {#3}}% +\catcode`_ 8 -The variant \csa{xintListWithSepNoExpand}\etype{nn} does the same -job without the initial expansion of the \meta{list} argument. -\begin{everbatim*} -\edef\foo{\xintListWithSep{, }{123456789{10}{11}{12}}}\meaning\foo\newline -\edef\foo{\xintListWithSep{:}{\xintiiFac{20}}}\meaning\foo\newline -\oodef\FOO{\xintListWithSepNoExpand{\FOO}{\bat\baz\biz\buz}}\meaning\FOO\newline -% a braced item or a space stops the f-expansion: -\oodef\foo{\xintListWithSep{\FOO}{{\bat}\baz\biz\buz}}\meaning\foo\newline -\oodef\foo{\xintListWithSep{\FOO}{ \bat\baz\biz\buz}}\meaning\foo\par -\end{everbatim*} +\begingroup\footnotesize\baselineskip10pt +\everb|@ +\catcode`_ 11 +\def\FibonacciSeq #1#2{%#1=starting index, #2>#1=ending index + \expandafter\Fibonacci_Seq\expandafter + {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2-1}% +}% +\def\Fibonacci_Seq #1#2{% + \expandafter\Fibonacci_Seq_loop\expandafter + {\the\numexpr #1\expandafter}\romannumeral0\Fibonacci {#1}{#2}% +}% +\def\Fibonacci_Seq_loop #1#2#3#4{% standard Fibonacci recursion + {#3}\unless\ifnum #1<#4 \Fibonacci_Seq_end\fi + \expandafter\Fibonacci_Seq_loop\expandafter + {\the\numexpr #1+1\expandafter}\expandafter + {\romannumeral0\xintiiexpro #2+#3\relax}{#2}{#4}% +}% +\def\Fibonacci_Seq_end\fi\expandafter\Fibonacci_Seq_loop\expandafter + #1\expandafter #2#3#4{\fi {#3}}% +\catcode`_ 8 +| +\endgroup -\subsection{\csh{xintApply}}\label{xintApply} +This |\FibonacciSeq| macro is +completely expandable but it is not \fexpan dable. + +This is not a problem in the next example which uses \csbxint{For*} as the +latter applies repeatedly full expansion to what comes next each time it +fetches an item from its list argument. Thus \csbxint{For*} still manages to +generate the list via iterated full expansion. -\def\macro #1{\the\numexpr 9-#1\relax} +\begin{figure*}[ht!] + \phantomsection\label{fibonacci} + \newcounter{myindex} + \fdef\Fibxxx{\FibonacciN {30}}% + \setcounter{myindex}{30}% +\centeredline{\tabskip 1ex +\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr + \xintFor* #1 in {\FibonacciSeq {30}{59}}\do + {\themyindex &\xintthe#1 & + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% +}\vrule +\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr + \xintFor* #1 in {\FibonacciSeq {60}{89}}\do + {\themyindex &\xintthe#1 & + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% +}\vrule +\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr + \xintFor* #1 in {\FibonacciSeq {90}{119}}\do + {\themyindex &\xintthe#1 & + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% +}}% +% +\centeredline{Some Fibonacci numbers together with their residues modulo + |F(30)|\dtt{=\xintthe\Fibxxx}} +\end{figure*} + +\begingroup\footnotesize\baselineskip10pt +\everb|@ +\newcounter{myindex}% not "index", which would overwrite theindex environment! +% (many have probably been bitten by this trap) +\tabskip 1ex + \fdef\Fibxxx{\FibonacciN {30}}% + \setcounter{myindex}{30}% +\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr + \xintFor* #1 in {\FibonacciSeq {30}{59}}\do + {\themyindex &\xintthe#1 & + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% +}\vrule +\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr + \xintFor* #1 in {\FibonacciSeq {60}{89}}\do + {\themyindex &\xintthe#1 & + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% +}\vrule +\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr + \xintFor* #1 in {\FibonacciSeq {90}{119}}\do + {\themyindex &\xintthe#1 & + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% +}% +| +\endgroup -\csa{xintApply}|{\macro}|\marg{list}\etype{ff} expandably applies the one -parameter macro |\macro| to each item in the \meta{list} given as second -argument and returns a new list with these outputs: each item is given one after -the other as parameter to |\macro| which is expanded at that time (as usual, -\emph{i.e.} fully for what comes first), the results are braced and output -together as a succession of braced items (if |\macro| is defined to start with a -space, the space will be gobbled and the |\macro| will not be expanded; it is -allowed to have its own arguments, the list items serve as last arguments to -|\macro|). Hence |\xintApply{\macro}{{1}{2}{3}}| returns -|{\macro{1}}{\macro{2}}{\macro{3}}| where all instances of |\macro| have been -already \fexpan ded. +This produces the Fibonacci numbers from |F(30)| to |F(119)|, and +computes also all the +congruence classes modulo |F(30)|. The output has +been put in a \hyperref[fibonacci]{float}, which appears +\vpageref[above]{fibonacci}. I leave to the mathematically inclined +readers the task to explain the visible patterns\dots |;-)|. -Being expandable, |\xintApply| is useful for example inside alignments where -implicit groups make standard loops constructs usually fail. In such situation -it is often not wished that the new list elements be braced, see -\csbxint{ApplyUnbraced}. The |\macro| does not have to be expandable: -|\xintApply| will try to expand it, the expansion may remain partial. +\subsection{When expandability is too much} -The \meta{list} may -itself be some macro expanding (in the previously described way) to the list of -tokens to which the macro |\macro| will be applied. For example, if the -\meta{list} expands to some positive number, then each digit will be replaced by -the result of applying |\macro| on it. % -% -\leftedline{|\def\macro #1{\the\numexpr - 9-#1\relax}|} % -% -\leftedline{|\xintApply\macro{\xintiiFac - {20}}|\dtt{=\xintApply\macro{\xintiiFac {20}}}} +Let's use the macros of \autoref{ssec:fibonacci} related to Fibonacci numbers. +Notice that the $47$th Fibonacci number is \dtt{\xintthe\FibonacciN {47}} thus +already too big for \TeX{} and \eTeX{}. -The macro \csa{xintApplyNoExpand}\etype{fn} does the same job without the first -initial expansion which gave the \meta{list} of braced tokens to which |\macro| -is applied. -\subsection{\csh{xintApplyUnbraced}}\label{xintApplyUnbraced} +The |\FibonacciN| macro found in \autoref{ssec:fibonacci} is completely +expandable, it is even \fexpan dable. We need a wrapper with |\xintthe| +prefix +\begin{everbatim*} +\def\theFibonacciN{\xintthe\FibonacciN} +\end{everbatim*} +to print in the document or to use within |\message| (or \LaTeX\ |typeout|) to +write to the log and terminal. +\begingroup + \def\A {1859} \def\B {1573} + \edef\X {\theFibonacciN\A} \edef\Y {\theFibonacciN\B} + \edef\GCDAB {\xintiiGCD\A\B}\edef\Z {\theFibonacciN\GCDAB} + \edef\GCDXY{\xintiiGCD\X\Y} -\csa{xintApplyUnbraced}|{\macro}|\marg{list}\etype{ff} is like \csbxint{Apply}. -The difference is that after having expanded its list argument, and applied -|\macro| in turn to each item from the list, it reassembles the outputs without -enclosing them in braces. The net effect is the same as doing + The |\xintthe| prefix also allows its use it as argument to the \xintname + macros: for example if we are interested in knowing how many digits + $F(1250)$ has, it suffices to issue |\xintLen {\theFibonacciN {1250}}| + (which expands to \dtt{\xintLen {\theFibonacciN {1250}}}). Or if we want to + check the formula $gcd(F(1859),F(1573))=F(gcd(1859,1573))=F(143)$, we only + need% % -\leftedline{|\xintListWithSep {}{\xintApply {\macro}|\marg{list}|}|} This is -useful for preparing a macro which will itself define some other macros or make -assignments, as the scope will not be limited by brace pairs. +\footnote{The + \csa{xintiiGCD} macro is provided by both the \xintgcdname package (since + |1.0|) and by the \xintname package (since |1.3d|).} % -\begin{everbatim*} -\def\macro #1{\expandafter\def\csname myself#1\endcsname {#1}} -\xintApplyUnbraced\macro{{elta}{eltb}{eltc}} -\begin{enumerate}[nosep,label=(\arabic{*})] -\item \meaning\myselfelta -\item \meaning\myselfeltb -\item \meaning\myselfeltc -\end{enumerate} -\end{everbatim*} - +\begin{everbatim} +$\xintiiGCD{\theFibonacciN{1859}}{\theFibonacciN{1573}}=% + \theFibonacciN{\xintiiGCD{1859}{1573}}$ +\end{everbatim} % -The macro \csa{xintApplyUnbracedNoExpand}\etype{fn} does the same job without -the first initial expansion which gave the \meta{list} of braced tokens to which -|\macro| is applied. - -\subsection{\csh{xintSeq}}\label{xintSeq} - -\csa{xintSeq}|[d]{x}{y}|\etype{{{\upshape[\numx]}}\numx\numx} generates -expandably |{x}{x+d}...| up to and possibly including |{y}| if |d>0| or down -to and including |{y}| if |d<0|. Naturally |{y}| is omitted if |y-x| is not a -multiple of |d|. If |d=0| the macro returns |{x}|. If |y-x| and |d| have -opposite signs, the macro returns nothing. If the optional argument |d| is -omitted it is taken to be the sign of |y-x|. Hence |\xintSeq {1}{0}| is not -empty but |{1}{0}|. But |\xintSeq [1]{1}{0}| is empty. - +which produces: +% +\leftedline{$\dtt{\xintiiGCD{\X}{\Y}}=\dtt{\theFibonacciN{\GCDAB}}$} -The arguments |x| and |y| are expanded inside a |\numexpr| so they may be -count registers or a \LaTeX{} |\value{countername}|, or arithmetic with such -things. +The |\theFibonacciN| macro expanded its |\xintiiGCD{1859}{1573}| argument via the +services of |\numexpr|: this step allows only things obeying the \TeX{} bound, +naturally! (but \dtt{F(\xintiiPow2{31}}) would be rather big anyhow...). -% -\begin{everbatim*} -\xintListWithSep{,\hskip2pt plus 1pt minus 1pt }{\xintSeq {12}{-25}} -\end{everbatim*} -% -\begin{everbatim*} -\xintiiSum{\xintSeq [3]{1}{1000}} -\end{everbatim*} +This is very convenient but of course it repeats the complete evaluation each +time it is done. In practice, it is often useful to store the result of such +evaluations in macros. Any |\edef| will break expandability, but if the goal +is at some point to print something to the |dvi| or |pdf| output, and not only +to the |log| file, then expandability has to be broken one day or another! -When the macro is used without the optional argument |d|, it can only generate -up to about $5000$ numbers\IMPORTANT, the precise value depends upon some -\TeX{} memory parameter (input save stack). +Hence, in practice, if we want to print in the document some computation +results, we can proceed like this and avoid having to repeat identical +evaluations: +\begin{everbatim} +\begingroup + \def\A {1859} \def\B {1573} + \edef\X {\theFibonacciN\A} \edef\Y {\theFibonacciN\B} + \edef\GCDAB {\xintiiGCD\A\B}\edef\Z {\theFibonacciN\GCDAB} + \edef\GCDXY{\xintiiGCD\X\Y} +The identity $\gcd(F(\A),F(\B))=F(\gcd(\A,\B))$ can be checked via evaluation +of both sides: $\gcd(F(\A),F(\B))=\gcd(\printnumber\X,\printnumber\Y)= +\printnumber{\GCDXY} = F(\gcd(\A,\B)) = F(\GCDAB) =\printnumber\Z$.\par + % some further computations involving \A, \B, \X, \Y +\endgroup % closing the group removes assignments to \A, \B, ... +% or choose longer names less susceptible to overwrite something. +% Note: there is no LaTeX \newecommand which would be to \edef like \newcommand is to \def +\end{everbatim} +The identity $\gcd(F(\A),F(\B))=F(\gcd(\A,\B))$ can be checked via evaluation +of both sides: $\gcd(F(\A),F(\B))=\gcd(\printnumber\X,\printnumber\Y)= +\printnumber{\GCDXY} = F(\gcd(\A,\B)) = F(\GCDAB) =\printnumber\Z$.\par +\endgroup -With the optional argument |d| the macro proceeds differently (but less -efficiently) and does not stress the input save stack. +One may legitimately ask the author: why expandability +to such extremes, for things such as big fractions or floating point numbers +(even continued fractions...) which anyhow can not be used directly within +\TeX's primitives such as |\ifnum|? Why insist on a concept +which is foreign to the vast majority of \TeX\ users and even programmers? +I have no answer: it made definitely sense at the start of \xintname (see +\autoref{ssec:origins}) and once started I could not stop. -\subsection{\csh{xintloop}, \csh{xintbreakloop}, \csh{xintbreakloopanddo}, \csh{xintloopskiptonext}} -\label{xintloop} -\label{xintbreakloop} -\label{xintbreakloopanddo} -\label{xintloopskiptonext} +\subsection{Acknowledgements (2013/05/25)} -|\xintloop|\meta{stuff}|\if...\repeat|\retype{} is an expandable loop -compatible with nesting. However to break out of the loop one almost always need -some un-expandable step. The cousin \csbxint{iloop} is \csbxint{loop} with an -embedded expandable mechanism allowing to exit from the loop. The iterated -macros may contain |\par| tokens or empty lines. +I was greatly helped in my preparatory thinking, prior to producing such an +expandable parser, by the commented source of the +\href{https://ctan.org/pkg/l3kernel}{l3fp} package, specifically the +|l3fp-parse.dtx| file (in the version of April-May 2013; I think there was in +particular a text called ``roadmap'' which was helpful). Also the source of the +|calc| package was instructive, despite the fact that here for |\xintexpr| the +principles are necessarily different due to the aim of achieving expandability. -If a sub-loop is to be used all the material from the start of the main loop and -up to the end of the entire subloop should be braced; these braces will be -removed and do not create a group. The simplest to allow the nesting of one or -more sub-loops is to brace everything between \csa{xintloop} and \csa{repeat}, -being careful not to leave a space between the closing brace and |\repeat|. +\clearpage +\expandafter\let\csname xintexprnameUp\endcsname\undefined +\csname ExamplesnameUp\endcsname +\section {More examples with \xinttoolsname or \xintexprname or both} +\RaisedLabel{sec:examples} -As this loop and \csbxint{iloop} will primarily be of interest to experienced -\TeX{} macro programmers, my description will assume that the user is -knowledgeable enough. Some examples in this document will be perhaps more -illustrative than my attemps at explanation of use. +Note: \xintexprname.sty automatically loads \xinttoolsname.sty. -One can abort the loop with \csbxint{breakloop}; this should not be used inside -the final test, and one should expand the |\fi| from the corresponding test -before. One has also \csbxint{breakloopanddo} whose first argument will be -inserted in the token stream after the loop; one may need a macro such as -|\xint_afterfi| to move the whole thing after the |\fi|, as a simple -|\expandafter| will not be enough. +The examples given here start to feel dated and are currently in need of some +rewrite to better illustrate newer features of the package. -One will usually employ some count registers to manage the exit test from the -loop; this breaks expandability, see \csbxint{iloop} for an expandable integer -indexed loop. Use in alignments will be complicated by the fact that cells -create groups, and also from the fact that any encountered unexpandable material -will cause the \TeX{} input scanner to insert |\endtemplate| on each encountered -|&| or |\cr|; thus |\xintbreakloop| may not work as expected, but the situation -can be resolved via |\xint_firstofone{&}| or use of |\TAB| with |\def\TAB{&}|. -It is thus simpler for alignments to use rather than \csbxint{loop} either the -expandable \csbxint{ApplyUnbraced} or the non-expandable but alignment -compatible \csbxint{ApplyInline}, \csbxint{For} or \csbxint{For*}. + +\localtableofcontents -As an example, let us suppose we have two macros |\A|\marg{i}\marg{j} and -|\B|\marg{i}\marg{j} behaving like (small) integer valued matrix entries, and we -want to define a macro |\C|\marg{i}\marg{j} giving the matrix product (|i| and -|j| may be count registers). We will assume that |\A[I]| expands to the number -of rows, |\A[J]| to the number of columns and want the produced |\C| to act in -the same manner. The code is very dispendious in use of |\count| registers, not -optimized in any way, not made very robust (the defined macro can not have the -same name as the first two matrices for example), we just wanted to quickly -illustrate use of the nesting capabilities of |\xintloop|.% -% -\footnote{for a more sophisticated implementation of matrix - multiplication, inclusive of determinants, inverses, and display - utilities, with entries big integers or decimal numbers or even - fractions see some code online posted - from - November 11, 2013.} -% +\subsection{More examples with dummy variables} +\label{ssec:moredummies} +These examples were first added to this manual at the time of the |1.1| +release (|2014/10/29|). \begin{everbatim*} -\newcount\rowmax \newcount\colmax \newcount\summax -\newcount\rowindex \newcount\colindex \newcount\sumindex -\newcount\tmpcount -\makeatletter -\def\MatrixMultiplication #1#2#3{% - \rowmax #1[I]\relax - \colmax #2[J]\relax - \summax #1[J]\relax - \rowindex 1 - \xintloop % loop over row index i - {\colindex 1 - \xintloop % loop over col index k - {\tmpcount 0 - \sumindex 1 - \xintloop % loop over intermediate index j - \advance\tmpcount \numexpr #1\rowindex\sumindex*#2\sumindex\colindex\relax - \ifnum\sumindex<\summax - \advance\sumindex 1 - \repeat }% - \expandafter\edef\csname\string#3{\the\rowindex.\the\colindex}\endcsname - {\the\tmpcount}% - \ifnum\colindex<\colmax - \advance\colindex 1 - \repeat }% - \ifnum\rowindex<\rowmax - \advance\rowindex 1 - \repeat - \expandafter\edef\csname\string#3{I}\endcsname{\the\rowmax}% - \expandafter\edef\csname\string#3{J}\endcsname{\the\colmax}% - \def #3##1{\ifx[##1\expandafter\Matrix@helper@size - \else\expandafter\Matrix@helper@entry\fi #3{##1}}% -}% -\def\Matrix@helper@size #1#2#3]{\csname\string#1{#3}\endcsname }% -\def\Matrix@helper@entry #1#2#3% - {\csname\string#1{\the\numexpr#2.\the\numexpr#3}\endcsname }% -\def\A #1{\ifx[#1\expandafter\A@size - \else\expandafter\A@entry\fi {#1}}% -\def\A@size #1#2]{\ifx I#23\else4\fi}% 3rows, 4columns -\def\A@entry #1#2{\the\numexpr #1+#2-1\relax}% not pre-computed... -\def\B #1{\ifx[#1\expandafter\B@size - \else\expandafter\B@entry\fi {#1}}% -\def\B@size #1#2]{\ifx I#24\else3\fi}% 4rows, 3columns -\def\B@entry #1#2{\the\numexpr #1-#2\relax}% not pre-computed... -\makeatother -\MatrixMultiplication\A\B\C \MatrixMultiplication\C\C\D -\MatrixMultiplication\C\D\E \MatrixMultiplication\C\E\F -\begin{multicols}2 - \[\begin{pmatrix} - \A11&\A12&\A13&\A14\\ - \A21&\A22&\A23&\A24\\ - \A31&\A32&\A33&\A34 - \end{pmatrix} - \times - \begin{pmatrix} - \B11&\B12&\B13\\ - \B21&\B22&\B23\\ - \B31&\B32&\B33\\ - \B41&\B42&\B43 - \end{pmatrix} - = - \begin{pmatrix} - \C11&\C12&\C13\\ - \C21&\C22&\C23\\ - \C31&\C32&\C33 - \end{pmatrix}\] - \[\begin{pmatrix} - \C11&\C12&\C13\\ - \C21&\C22&\C23\\ - \C31&\C32&\C33 - \end{pmatrix}^2 = \begin{pmatrix} - \D11&\D12&\D13\\ - \D21&\D22&\D23\\ - \D31&\D32&\D33 - \end{pmatrix}\] - \[\begin{pmatrix} - \C11&\C12&\C13\\ - \C21&\C22&\C23\\ - \C31&\C32&\C33 - \end{pmatrix}^3 = \begin{pmatrix} - \E11&\E12&\E13\\ - \E21&\E22&\E23\\ - \E31&\E32&\E33 - \end{pmatrix}\] - \[\begin{pmatrix} - \C11&\C12&\C13\\ - \C21&\C22&\C23\\ - \C31&\C32&\C33 - \end{pmatrix}^4 = \begin{pmatrix} - \F11&\F12&\F13\\ - \F21&\F22&\F23\\ - \F31&\F32&\F33 - \end{pmatrix}\] -\end{multicols} +Prime numbers are always cool +\xinttheiiexpr seq((seq((subs((x/:m)?{(m*m>x)?{1}{0}}{-1},m=2n+1)) + ??{break(0)}{omit}{break(1)},n=1++))?{x}{omit}, + x=10001..[2]..10200)\relax \end{everbatim*} +The syntax in this last example may look a bit involved (... and it is so I +admit). First |x/:m| computes |x modulo m| (this is the modulo with respect to +floored division). The |(x)?{yes}{no}| construct checks if |x| (which +\emph{must} be within parentheses) is true or false, i.e. non zero or zero. It +then executes either the |yes| or the |no| branch, the non chosen branch is +\emph{not} evaluated. Thus if |m| divides |x| we are in the second (``false'') +branch. This gives a |-1|. This |-1| is the argument to a |??| branch which is +of the type |(y)??{y<0}{y=0}{y>0}|, thus here the |y<0|, i.e., |break(0)| is +chosen. This |0| is thus given to another |?| which consequently chooses +|omit|, hence the number is not kept in the list. The numbers which survive +are the prime numbers. -\subsection{\csh{xintiloop}, \csh{xintiloopindex}, \csh{xintouteriloopindex}, - \csh{xintbreakiloop}, \csh{xintbreakiloopanddo}, \csh{xintiloopskiptonext}, -\csh{xintiloopskipandredo}} -\label{xintiloop} -\label{xintbreakiloop} -\label{xintbreakiloopanddo} -\label{xintiloopskiptonext} -\label{xintiloopskipandredo} -\label{xintiloopindex} -\label{xintouteriloopindex} - -\csa{xintiloop}|[start+delta]|\meta{stuff}|\if ... \repeat|\retype{} is a -completely expandable nestable loop. complete expandability depends naturally on -the actual iterated contents, and complete expansion will not be achievable -under a sole \fexpan sion, as is indicated by the hollow star in the margin; -thus the loop can be used inside an |\edef| but not inside arguments to the -package macros. It can be used inside an |\xintexpr..\relax|. The -|[start+delta]| is mandatory, not optional. - -This loop benefits via \csbxint{iloopindex} to (a limited access to) the integer -index of the iteration. The starting value |start| (which may be a |\count|) and -increment |delta| (\emph{id.}) are mandatory arguments. A space after the -closing square bracket is not significant, it will be ignored. Spaces inside the -square brackets will also be ignored as the two arguments are first given to a -|\numexpr...\relax|. Empty lines and explicit |\par| tokens are accepted. - -As with \csbxint{loop}, this tool will mostly be of interest to advanced users. -For nesting, one puts inside braces all the -material from the start (immediately after |[start+delta]|) and up to and -inclusive of the inner loop, these braces will be removed and do not create a -loop. In case of nesting, \csbxint{outeriloopindex} gives access to the index of -the outer loop. If needed one could write on its model a macro giving access to -the index of the outer outer loop (or even to the |nth| outer loop). - -The \csa{xintiloopindex} and \csa{xintouteriloopindex} can not be used inside -braces, and generally speaking this means they should be expanded first when -given as argument to a macro, and that this macro receives them as delimited -arguments, not braced ones. Or, but naturally this will break expandability, one -can assign the value of \csa{xintiloopindex} to some |\count|. Both -\csa{xintiloopindex} and \csa{xintouteriloopindex} extend to the litteral -representation of the index, thus in |\ifnum| tests, if it comes last one has to -correctly end the macro with a |\space|, or encapsulate it in a -|\numexpr..\relax|. - -When the repeat-test of the loop is, for example, |\ifnum\xintiloopindex<10 -\repeat|, this means that the last iteration will be with |\xintiloopindex=10| -(assuming |delta=1|). There is also |\ifnum\xintiloopindex=10 \else\repeat| to -get the last iteration to be the one with |\xintiloopindex=10|. - -One has \csbxint{breakiloop} and \csbxint{breakiloopanddo} to abort the loop. -The syntax of |\xintbreakiloopanddo| is a bit surprising, the sequence of tokens -to be executed after breaking the loop is not within braces but is delimited by -a dot as in: -% -\leftedline{|\xintbreakiloopanddo .etc.. etc... \repeat|} -% -The reason is that one may wish to use the then current value of -|\xintiloopindex| in || but it can't be within braces at the time it -is evaluated. However, it is not that easy as |\xintiloopindex| must be expanded -before, so one ends up with code like this: -% -\leftedline -{|\expandafter\xintbreakiloopanddo\expandafter\macro\xintiloopindex.%|} -% -\leftedline{|etc.. etc.. \repeat|} -% -As moreover the |\fi| from the test leading to the decision of breaking out of -the loop must be cleared out of the way, the above should be -a branch of an expandable conditional test, else one needs something such -as: -% -\leftedline -{|\xint_afterfi{\expandafter\xintbreakiloopanddo\expandafter\macro\xintiloopindex.}%|} -% -\leftedline{|\fi etc..etc.. \repeat|} - -There is \csbxint{iloopskiptonext} to abort the current iteration and skip to -the next, \hyperref[xintiloopskipandredo]{\ttfamily\hyphenchar\font45 \char92 - xintiloopskip\-and\-redo} to skip to the end of the current iteration and redo -it with the same value of the index (something else will have to change for this -not to become an eternal loop\dots ). +\begin{everbatim*} +The first Fibonacci number beyond |2^64| bound is +\xinttheiiexpr subs(iterr(0,1;(@1>N)?{break(i)}{@1+@2},i=1++),N=2^64)\relax{} +and the previous number was its index. +\end{everbatim*} -Inside alignments, if the looped-over text contains a |&| or a |\cr|, any -un-expandable material before a \csbxint{iloopindex} will make it fail because -of |\endtemplate|; in such cases one can always either replace |&| by a macro -expanding to it or replace it by a suitable |\firstofone{&}|, and similarly for -|\cr|. +% A006877 In the `3x+1' problem, these values for the starting value set new +% records for number of steps to reach 1. (Formerly M0748) 14 1, 2, 3, 6, 7, +% 9, 18, 25, 27, 54, 73, 97, 129, 171, 231, 313, 327, 649, 703, 871, 1161, +% 2223, 2463, 2919, 3711, 6171, 10971, 13255, 17647, 23529, 26623, 34239, +% 35655, 52527, 77031, 106239, 142587, 156159, 216367, 230631, 410011, 511935, +% 626331, 837799 -\phantomsection\label{edefprimes} -As an example, let us construct an |\edef\z{...}| which will define |\z| to be a -list of prime numbers: +One more recursion: \begin{everbatim*} -\begingroup -\edef\z -{\xintiloop [10001+2] - {\xintiloop [3+2] - \ifnum\xintouteriloopindex<\numexpr\xintiloopindex*\xintiloopindex\relax - \xintouteriloopindex, - \expandafter\xintbreakiloop - \fi - \ifnum\xintouteriloopindex=\numexpr - (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax - \else - \repeat - }% no space here - \ifnum \xintiloopindex < 10999 \repeat }% -\meaning\z\endgroup -\end{everbatim*}and we should have taken -some steps to not have a trailing comma, but -the point was to show that one can do that in an |\edef|\,! See also -\autoref{ssec:primesII} which extracts from this code its way of testing -primality. +\def\syr #1{\xinttheiiexpr rseq(#1; (@<=1)?{break(i)}{odd(@)?{3@+1}{@//2}},i=0++)\relax} +The 3x+1 problem: \syr{231}\par +\end{everbatim*} -Let us create an alignment where each row will contain all divisors of its -first entry. -Here is the output, thus obtained without any count register: +OK, a final one: \begin{everbatim*} -\begin{multicols}2 -\tabskip1ex \normalcolor -\halign{&\hfil#\hfil\cr - \xintiloop [1+1] - {\expandafter\bfseries\xintiloopindex & - \xintiloop [1+1] - \ifnum\xintouteriloopindex=\numexpr - (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax - \xintiloopindex&\fi - \ifnum\xintiloopindex<\xintouteriloopindex\space % CRUCIAL \space HERE - \repeat \cr }% - \ifnum\xintiloopindex<30 - \repeat -} -\end{multicols} +\def\syrMax #1{\xinttheiiexpr iterr(#1,#1;even(i)? + {(@2<=1)?{break(i/2)}{odd(@2)?{3@2+1}{@2//2}}} + {(@1>@2)?{@1}{@2}},i=0++)\relax } +With initial value 1161, the maximal number attained is \syrMax{1161} and that latter +number is the number of steps which was needed to reach 1.\par \end{everbatim*} -We wanted this first entry in bold face, but |\bfseries| leads to -unexpandable tokens, so the |\expandafter| was necessary for |\xintiloopindex| -and |\xintouteriloopindex| not to be confronted with a hard to digest -|\endtemplate|. An alternative way of coding: -% -\begin{everbatim} -\tabskip1ex -\def\firstofone #1{#1}% -\halign{&\hfil#\hfil\cr - \xintiloop [1+1] - {\bfseries\xintiloopindex\firstofone{&}% - \xintiloop [1+1] \ifnum\xintouteriloopindex=\numexpr - (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax - \xintiloopindex\firstofone{&}\fi - \ifnum\xintiloopindex<\xintouteriloopindex\space % \space is CRUCIAL - \repeat \firstofone{\cr}}% - \ifnum\xintiloopindex<30 \repeat } -\end{everbatim} - -\begin{framed} - The next utilities are not compatible with expansion-only context. -\end{framed} -\subsection{\csh{xintApplyInline}}\label{xintApplyInline} +Look at the + \hyperlink{BrentSalamin}{Brent-Salamin algorithm implementation} for a more + interesting recursion. +% \begin{everbatim*} +% \newcommand\Factors [1]{\xinttheiiexpr +% subs(seq((i/:3=1)?{omit}{[L][i]},i=0..len(L)-1), +% L=rseq(#1;(p^2>[@][0])?{([@][0]>1)?{break(1,[@][0],1)}{abort}} +% {(([@][0])/:p)?{omit} +% {iter(([@][0])//p; (@/:p)?{break(@,p,e)}{@//p},e=1++)}},p=2++))\relax } +% \Factors {41^4*59^2*29^3*13^5*17^8*29^2*59^4*37^6} +% \end{everbatim*} -\csa{xintApplyInline}|{\macro}|\marg{list}\ntype{o{\lowast f}} works non -expandably. It applies the one-parameter |\macro| to the first element of the -expanded list (|\macro| may have itself some arguments, the list item will be -appended as last argument), and is then re-inserted in the input stream after -the tokens resulting from this first expansion of |\macro|. The next item is -then handled. +% This might look a bit scary, I admit.% +% % +% \footnote{Look at the +% \hyperlink{BrentSalamin}{Brent-Salamin algorithm implementation} for a much +% saner example.} +% % -This is to be used in situations where one needs to do some repetitive -things. It is not expandable and can not be completely expanded inside a -macro definition, to prepare material for later execution, contrarily to what -\csbxint{Apply} or \csbxint{ApplyUnbraced} achieve. +% \xintexprname has minimal tools and +% is obstinate about doing everything expandably! We are hampered by absence of a +% notion of ``nuple''. The algorithm divides |N| by |2| until no more possible, +% then by |3|, then by |4| (which is silly), then by |5|, then by |6| (silly +% again), \dots. -\begin{everbatim*} -\def\Macro #1{\advance\cnta #1 , \the\cnta} -\cnta 0 -0\xintApplyInline\Macro {3141592653}. -\end{everbatim*} -The first argument |\macro| does not have to be an expandable macro. +% The variable |L=rseq(#1;...)| expands, if one follows the steps, to a comma +% separated list starting with the initial (evaluated) |N=#1| and then +% pseudo-triplets where the first item is |N| trimmed of small primes, the +% second item is the last prime divisor found, and the third item is its +% exponent in original |N|. -\csa{xintApplyInline} submits its second, token list parameter to an -\hyperref[ssec:expansions]{\fexpan -sion}. Then, each \emph{unbraced} item will also be \fexpan ded. This provides -an easy way to insert one list inside another. \emph{Braced} items are not -expanded. Spaces in-between items are gobbled (as well as those at the start -or the end of the list), but not the spaces \emph{inside} the braced items. +% The algorithm needs to keep handy the last computed quotient by prime powers, +% hence all of them, but at the very end it will be cleaner to get rid of them +% (this corresponds to the first line in the code above). This is achieved in a +% cumbersome inefficient way; indeed each item extraction |[L][i]| is costly: it +% is not like accessing an array stored in memory, due to expandability, nothing +% can be stored in memory! Nevertheless, this step could be done here in a far +% less inefficient manner if there was a variant of |seq| which, in the spirit +% of \csbxint{iloopindex}, would know how many steps it had been through so far. +% This is a feature to be added to |\xintexpr|! (as well as a |++| construct +% allowing a non unit step). -\csa{xintApplyInline}, despite being non-expandable, does survive to -contexts where the executed |\macro| closes groups, as happens inside -alignments with the tabulation character |&|. -This tabular provides an example:\par -\begin{everbatim*} -\centerline{\normalcolor\begin{tabular}{ccc} - $N$ & $N^2$ & $N^3$ \\ \hline - \def\Row #1{ #1 & \xintiiSqr {#1} & \xintiiPow {#1}{3} \\ \hline }% - \xintApplyInline \Row {\xintCSVtoList{17,28,39,50,61}} -\end{tabular}}\medskip -\end{everbatim*} +% Notice that in |iter(([@][0])//p;| the |@| refers to the previous triplet (or +% in the first step to |N|), but the latter |@| showing up in |(@/:p)?| refers +% to the previous value computed by |iter|. -We see that despite the fact that the first encountered tabulation character in -the first row close a group and thus erases |\Row| from \TeX's memory, -|\xintApplyInline| knows how to deal with this. +% \begin{snugframed} +% Parentheses are essential in |..([y][0])| else the parser will see |..[| and +% end up in ultimate confusion, and also in |([@][0])/:p| else the parser will +% see the itemwise operator |]/| on lists and again be very confused (I could +% implement a |]/:| on lists, but in this situation this would also be very +% confusing to the parser.) +% \end{snugframed} -Using \csbxint{ApplyUnbraced} is an alternative: the difference is that -this would have prepared all rows first and only put them back into the -token stream once they are all assembled, whereas with |\xintApplyInline| -each row is constructed and immediately fed back into the token stream: when -one does things with numbers having hundreds of digits, one learns that -keeping on hold and shuffling around hundreds of tokens has an impact on -\TeX{}'s speed (make this ``thousands of tokens'' for the impact to be -noticeable). +% See \autoref{ssec:factorize} for a routine |\Factorize| written directly with +% \xintname macros. Last time I checked |\Factors| was about seven times slower +% than |\Factorize| in test cases such as +% |16246355912554185673266068721806243461403654781833| and others. Among the +% various things explaining the speed difference, there is fact that the +% |\Factorize| algorithm step by increments of two, not one, and also it divides +% only once, obtaining quotient and remainder in one go. These two things +% already make for a speed-up factor of about four. Thus, |\Factors| is not +% completely inefficient in comparison, and was quite easier to come up with +% than |\Factorize|. -One may nest various |\xintApplyInline|'s. For example (see the -\hyperref[float]{table} \vpageref{float}):\par -\begin{everbatim*} -\begin{figure*}[ht!] - \centering\phantomsection\label{float} - \def\Row #1{#1:\xintApplyInline {\Item {#1}}{0123456789}\\ }% - \def\Item #1#2{&\xintiiPow {#1}{#2}}% - \centeredline {\begin{tabular}{ccccccccccc} &0&1&2&3&4&5&6&7&8&9\\ \hline - \xintApplyInline \Row {0123456789} - \end{tabular}} -\end{figure*} -\end{everbatim*} +\subsection{Completely expandable prime test} +\label{ssec:primesI} -One could not move the definition of |\Item| inside the tabular, -as it would get lost after the first |&|. But this -works: +Let us now construct a completely expandable macro which returns $1$ if its +given input is prime and $0$ if not: \everb|@ -\begin{tabular}{ccccccccccc} - &0&1&2&3&4&5&6&7&8&9\\ \hline - \def\Row #1{#1:\xintApplyInline {&\xintiiPow {#1}}{0123456789}\\ }% - \xintApplyInline \Row {0123456789} -\end{tabular} +\def\remainder #1#2{\the\numexpr #1-(#1/#2)*#2\relax } +\def\IsPrime #1% + {\xintANDof {\xintApply {\remainder {#1}}{\xintSeq {2}{\xintiiSqrt{#1}}}}} | -A limitation is that, contrarily to what one may have expected, the -|\macro| for an |\xintApplyInline| can not be used to define -the |\macro| for a nested sub-|\xintApplyInline|. For example, -this does not work:\par +This uses \csbxint{iiSqrt} and assumes its input is at least $5$. Rather than +\xintname's own \csbxint{iiRem} we used a quicker |\numexpr| expression as we +are dealing with short integers. Also we used \csbxint{ANDof} which will +return $1$ only if all the items are non-zero. The macro is a bit +silly with an even input, ok, let's enhance it to detect an even input: \everb|@ - \def\Row #1{#1:\def\Item ##1{&\xintiiPow {#1}{##1}}% - \xintApplyInline \Item {0123456789}\\ }% - \xintApplyInline \Row {0123456789} % does not work +\def\IsPrime #1% + {\xintiiifOdd {#1} + {\xintANDof % odd case + {\xintApply {\remainder {#1}} + {\xintSeq [2]{3}{\xintiiSqrt{#1}}}% + }% + } + {\xintifEq {#1}{2}{1}{0}}% + } | -\noindent But see \csbxint{For}. -\subsection{\csh{xintFor}, \csh{xintFor*}}\label{xintFor}\label{xintFor*} +We used the \xintname expandable tests (on big integers or fractions) +in order for |\IsPrime| to be \fexpan dable. -\csbxint{For}\ntype{on} is a new kind of for loop.\footnote{first introduced - with \xintname |1.09c| of |2013/10/09|.} Rather than using macros -for encapsulating list items, its behaviour is like a macro with parameters: -|#1|, |#2|, \dots, |#9| are used to represent the items for up to nine levels of -nested loops. Here is an example: +Our integers are short, but without |\expandafter|'s with +|\@firstoftwo|, % @ n'est plus actif dans le dtx 1.1 ! +or some other related techniques, +direct use of |\ifnum..\fi| tests is dangerous. So to make the macro more +efficient we are going to use the expandable tests provided by the package +\href{http://ctan.org/pkg/etoolbox}{etoolbox}% +% +\footnote{\url{http://ctan.org/pkg/etoolbox}}. +% +The macro becomes: % \everb|@ -\xintFor #9 in {1,2,3} \do {% - \xintFor #1 in {4,5,6} \do {% - \xintFor #3 in {7,8,9} \do {% - \xintFor #2 in {10,11,12} \do {% - $$#9\times#1\times#3\times#2=\xintiiPrd{{#1}{#2}{#3}{#9}}$$}}}} +\def\IsPrime #1% + {\ifnumodd {#1} + {\xintANDof % odd case + {\xintApply {\remainder {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}} + {\ifnumequal {#1}{2}{1}{0}}} | -\noindent This example illustrates that one does not have to use |#1| as the -first one: -the order is arbitrary. But each level of nesting should have its specific macro -parameter. Nine levels of nesting is presumably overkill, but I did not know -where it was reasonable to stop. |\par| tokens are accepted in both the comma -separated list and the replacement text. -\begin{framed} - \TeX nical notes: +In the odd case however we have to assume the integer is at least $7$, as +|\xintSeq| generates an empty list if |#1=3| or |5|, and |\xintANDof| returns +$1$ when supplied an empty list. Let us ease up a bit |\xintANDof|'s work by +letting it work on only $0$'s and $1$'s. We could use: +% +\everb|@ +\def\IsNotDivisibleBy #1#2% + {\ifnum\numexpr #1-(#1/#2)*#2=0 \expandafter 0\else \expandafter1\fi} +| +\noindent +where the |\expandafter|'s are crucial for this macro to be \fexpan dable and +hence work within the applied \csbxint{ANDof}. Anyhow, now that we have loaded +\href{http://ctan.org/pkg/etoolbox}{etoolbox}, we might as well use: +% +\everb|@ +\newcommand{\IsNotDivisibleBy}[2]{\ifnumequal{#1-(#1/#2)*#2}{0}{0}{1}} +| +\noindent +Let us enhance our prime macro to work also on the small primes: +\everb|@ +\newcommand{\IsPrime}[1] % returns 1 if #1 is prime, and 0 if not + {\ifnumodd {#1} + {\ifnumless {#1}{8} + {\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes + {\xintANDof + {\xintApply + { \IsNotDivisibleBy {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}% + }}% END OF THE ODD BRANCH + {\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH +} +| -\begin{itemize} - \item The |#1| is replaced in the iterated-over text exactly as in general - \TeX\ macros or \LaTeX\ commands. This spares the user quite a few - |\expandafter|'s or other tricks needed with loops which have the - values encapsulated in macros, like \LaTeX's |\@for| and |\@tfor|. +The input is still assumed positive. There is a deliberate blank before +\csa{IsNotDivisibleBy} to use this feature of \csbxint{Apply}: a space stops the +expansion of the applied macro (and disappears). This expansion will be done by +\csbxint{ANDof}, which has been designed to skip everything as soon as it finds +a false (i.e. zero) input. This way, the efficiency is considerably improved. - \item \csa{xintFor} (and \csa{xintFor*}) isn't purely expandable: one can - not use it inside an |\edef|. But it may be used, as will be shown in - examples, in some contexts such as \LaTeX's |tabular| which are usually - hostile to non-expandable loops. - - \item \csa{xintFor} (and \csa{xintFor*}) does some assignments prior to - executing each iteration of the replacement text, but it acts purely - expandably after the last iteration, hence if for example the replacement - text ends with a |\\|, the loop can be used insided a tabular and be - followed by a |\hline| without creating the dreaded ``|Misplaced - \noalign|'' error. +We did generate via the \csbxint{Seq} too many potential divisors though. Later +sections give two variants: one with \csbxint{iloop} (\autoref{ssec:primesII}) +which is still expandable and another one (\autoref{ssec:primesIII}) which is a +close variant of the |\IsPrime| code above but with the \csbxint{For} loop, thus +breaking expandability. The \hyperref[ssec:primesII]{xintiloop variant} does not +first evaluate the integer square root, the \hyperref[ssec:primesIII]{xintFor + variant} still does. I did not compare their efficiencies. - \item As stated in previous item the first iteration follows some - non-expandable internal dealings. This means for example that in \LaTeX{}, - one can not inject a |\multicolumn| in the first iteration. Sometimes one - way work around this by injecting father |&\multicolumn| or |\\ - \multicolumn|. - \item It does not create groups. +Let us construct with this expandable primality test a table of the prime +numbers up to $1000$. We need to count how many we have in order to know how +many tab stops one shoud add in the last row.% +% +\footnote{although a tabular row may have less tabs than in the + preamble, there is a problem with the \char`\|\space\space vertical + rule, if one does that.} +% +There is some subtlety for this +last row. Turns out to be better to insert a |\\| only when we know for sure we +are starting a new row; this is how we have designed the |\OneCell| macro. And +for the last row, there are many ways, we use again |\xintApplyUnbraced| but +with a macro which gobbles its argument and replaces it with a tabulation +character. The \csbxint{For*} macro would be more elegant here. +% +\everb?@ +\newcounter{primecount} +\newcounter{cellcount} +\newcommand{\NbOfColumns}{13} +\newcommand{\OneCell}[1]{% + \ifnumequal{\IsPrime{#1}}{1} + {\stepcounter{primecount} + \ifnumequal{\value{cellcount}}{\NbOfColumns} + {\\\setcounter{cellcount}{1}#1} + {&\stepcounter{cellcount}#1}% + } % was prime + {}% not a prime, nothing to do +} +\newcommand{\OneTab}[1]{&} +\begin{tabular}{|*{\NbOfColumns}{r}|} +\hline +2 \setcounter{cellcount}{1}\setcounter{primecount}{1}% + \xintApplyUnbraced \OneCell {\xintSeq [2]{3}{999}}% + \xintApplyUnbraced \OneTab + {\xintSeq [1]{1}{\the\numexpr\NbOfColumns-\value{cellcount}\relax}}% + \\ +\hline +\end{tabular} +There are \arabic{primecount} prime numbers up to 1000. +? + +The table has been put in \hyperref[primesupto1000]{float} which appears +\vpageref{primesupto1000}. +We had to be careful to use in the last row \csbxint{Seq} with its optional +argument |[1]| so as to not generate a decreasing sequence from |1| to |0|, but +really an empty sequence in case the row turns out to already have all its +cells (which doesn't happen here but would with a number of columns dividing +$168$). +% +\newcommand{\IsNotDivisibleBy}[2]{\ifnumequal{#1-(#1/#2)*#2}{0}{0}{1}} + +\newcommand{\IsPrime}[1] + {\ifnumodd {#1} + {\ifnumless {#1}{8} + {\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes + {\xintANDof + {\xintApply + { \IsNotDivisibleBy {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}% + }}% END OF THE ODD BRANCH + {\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH +} + +\newcounter{primecount} +\newcounter{cellcount} +\newcommand{\NbOfColumns}{13} +\newcommand{\OneCell}[1] + {\ifnumequal{\IsPrime{#1}}{1} + {\stepcounter{primecount} + \ifnumequal{\value{cellcount}}{\NbOfColumns} + {\\\setcounter{cellcount}{1}#1} + {&\stepcounter{cellcount}#1}% + } % was prime + {}% not a prime nothing to do +} +\newcommand{\OneTab}[1]{&} +\begin{figure*}[ht!] + \centering + \phantomsection\label{primesupto1000} + \begin{tabular}{|*{\NbOfColumns}{r}|} + \hline + 2\setcounter{cellcount}{1}\setcounter{primecount}{1}% + \xintApplyUnbraced \OneCell {\xintSeq [2]{3}{999}}% + \xintApplyUnbraced \OneTab + {\xintSeq [1]{1}{\the\numexpr\NbOfColumns-\value{cellcount}\relax}}% + \\ + \hline + \end{tabular} +\smallskip +\centeredline{There are \arabic{primecount} prime numbers up to 1000.} +\end{figure*} + +\subsection{Another completely expandable prime test} +\label{ssec:primesII} + +The |\IsPrime| macro from \autoref{ssec:primesI} checked expandably if a (short) +integer was prime, here is a partial rewrite using \csbxint{iloop}. We use the +|etoolbox| expandable conditionals for convenience, but not everywhere as +|\xintiloopindex| can not be evaluated while being braced. This is also the +reason why |\xintbreakiloopanddo| is delimited, and the next macro +|\SmallestFactor| which returns the smallest prime factor examplifies that. One +could write more efficient completely expandable routines, the aim here was only +to illustrate use of the general purpose \csbxint{iloop}. A little table giving +the first values of |\SmallestFactor| follows, its coding uses \csbxint{For}, +which is described later; none of this uses count registers. +% - \item It makes no global assignments. - \item The iterated replacement text may close a group which was opened even - before the start of the loop (typical example being with |&| in - alignments). \begin{everbatim*} -\begin{tabular}{rccccc} +\let\IsPrime\undefined \let\SmallestFactor\undefined % clean up possible previous mess +\newcommand{\IsPrime}[1] % returns 1 if #1 is prime, and 0 if not + {\ifnumodd {#1} + {\ifnumless {#1}{8} + {\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes + {\if + \xintiloop [3+2] + \ifnum#1<\numexpr\xintiloopindex*\xintiloopindex\relax + \expandafter\xintbreakiloopanddo\expandafter1\expandafter.% + \fi + \ifnum#1=\numexpr (#1/\xintiloopindex)*\xintiloopindex\relax + \else + \repeat 00\expandafter0\else\expandafter1\fi + }% + }% END OF THE ODD BRANCH + {\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH +}% +\catcode`_ 11 +\newcommand{\SmallestFactor}[1] % returns the smallest prime factor of #1>1 + {\ifnumodd {#1} + {\ifnumless {#1}{8} + {#1}% 3,5,7 are primes + {\xintiloop [3+2] + \ifnum#1<\numexpr\xintiloopindex*\xintiloopindex\relax + \xint_afterfi{\xintbreakiloopanddo#1.}% + \fi + \ifnum#1=\numexpr (#1/\xintiloopindex)*\xintiloopindex\relax + \xint_afterfi{\expandafter\xintbreakiloopanddo\xintiloopindex.}% + \fi + \iftrue\repeat + }% + }% END OF THE ODD BRANCH + {2}% EVEN BRANCH +}% +\catcode`_ 8 +{\centering + \begin{tabular}{|c|*{10}c|} \hline - \xintFor #1 in {A, B, C} \do {% - #1:\xintFor #2 in {a, b, c, d, e} \do {&($ #2 \to #1 $)}\\ }% + \xintFor #1 in {0,1,2,3,4,5,6,7,8,9}\do {&\bfseries #1}\\ \hline -\end{tabular} + \bfseries 0&--&--&2&3&2&5&2&7&2&3\\ + \xintFor #1 in {1,2,3,4,5,6,7,8,9}\do + {\bfseries #1% + \xintFor #2 in {0,1,2,3,4,5,6,7,8,9}\do + {&\SmallestFactor{#1#2}}\\}% + \hline + \end{tabular}\par +} \end{everbatim*} - - \item There is no facility provided which would give access to a count of - the number of iterations as it is technically not easy to do so it in a - way working with nested loops while maintaining the ``expandable after - done'' property; something in the spirit of \csbxint{iloopindex} is - possible but this approach would bring its own limitations and - complications. Hence the user is invited to update her own count or - \LaTeX{} counter or macro at each iteration, if needed. - \item A |\macro| whose definition uses internally an \csbxint{For} loop - may be used inside another \csbxint{For} loop even if the two loops both - use the same macro parameter. The loop definition inside |\macro| - must use |##| as is the general rule for definitions done inside macros. +\subsection{Miller-Rabin Pseudo-Primality expandably} +\label{ssec:PrimesIV} - \item \csbxint{For} is for comma separated values and \csbxint{For*} for - lists of braced items; their respective expansion policies differ. They - are described later. -\end{itemize} -\unskip -\end{framed} -\noindent Regarding \csbxint{For}: -\begin{itemize}[nosep, listparindent=\leftmarginiii] -\item the spaces between the various declarative elements are all optional, -\item in the list of comma separated values, spaces around the commas or at - the start and end are ignored, -\item if an item must contain itself its own commas, then it should - be braced, and the braces will be removed before feeding the iterated-over - text, -\item the list may be a macro, it is expanded only once, -\item items are not pre-expanded. The first item should be braced or start - with a space if the list is explicit and the item should not be - pre-expanded, -\item empty items give empty |#1|'s in the replacement text, they are not - skipped, -\item an empty list executes once the replacement text with an empty parameter - value, -\item the list, if not a macro, \fbox{must be braced.} -\end{itemize} +% At the time of writing, the code at the link above is still the version from +% April 2016 and it needed some hacks to get recursive (pseudo)-functions +% defined. Since |1.2h| of |2016/11/20| there is \csbxint{NewFunction} which +% allows us here to avoid such internal hacking. -\noindent Regarding \csbxint{For*}:\ntype{{\lowast f}n} -\begin{itemize}[nosep, listparindent=\leftmarginiii] -\item it handles lists of braced items (or naked tokens), -\item it \hyperref[ssec:expansions]{\fexpan ds} the list, -\item and more generally it \hyperref[ssec:expansions]{\fexpan ds} each naked - token encountered - before assigning the |#1| values (gobbling spaces in the process); - this - makes it easy to simulate concatenation of multiple lists|\x|, |\y|: - if |\x| expands to |{1}{2}{3}| and |\y| expands to |{4}{5}{6}| then |{\x\y}| - as argument to |\xintFor*| has the same effect as |{{1}{2}{3}{4}{5}{6}}|. +% And since |1.3| of |2018/03/01|, it is possible to use \csbxint{defiifunc} +% also for recursive definitions, so we use it here, but we can benefit from it +% only for modular exponentiation as the rest of the code uses |iter| or |break| +% statements which are not yet compatible with \csbxint{defiifunc}. - For a further illustration see the use of |\xintFor*| at the end of - \autoref{ssec:fibonacci}. -\item spaces at the start, end, or in-between items are gobbled (but naturally - not the spaces inside \emph{braced} items), -\item except if the list argument is a macro (with no parameters), \fbox{it - must be braced.}, -\item an empty list leads to an empty result. -\end{itemize} +The |isPseudoPrime(n)| is usable in \csbxint{iiexpr}-essions and establishes +if its (positive) argument is a Miller-Rabin PseudoPrime to the bases $2, 3, +5, 7, 11, 13, 17$. If this is true and $n<341550071728321$ (which has 15 +digits) then $n$ really is a prime number. + +Similarly $n=3825123056546413051$ (19 digits) is the smallest composite number +which is a strong pseudo prime for bases $2, 3, 5, 7, 11, 13, 17, 19$ and +$23$. It is easy to extend the code below to include these additional tests +(we could make the list of tested bases an argument too, now that I think +about it.) + +For more information see + \centeredline{\url{https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test#Deterministic_variants_of_the_test}} + and +\centeredline{\url{http://primes.utm.edu/prove/prove2_3.html}} + +In particular, according to \textsc{Jaeschke} \emph{On strong pseudoprimes to + several bases,} Math. Comp., 61 (1993) 915-926, if $n < 4,759,123,141$ it is +enough to establish Rabin-Miller pseudo-primality to bases $a = 2, 7, 61$ to +prove that $n$ is prime. This range is enough for \TeX\ numbers and we could +then write a very fast expandable primality test for such numbers using only +|\numexpr|. Left as an exercise\dots -The macro \csbxint{Seq} which generates arithmetic sequences is to be used -with \csbxint{For*} as its output consists of successive braced numbers (given -as digit tokens). \begin{everbatim*} -\xintFor* #1 in {\xintSeq [+2]{-7}{+2}}\do {stuff - with #1\xintifForLast{\par}{\newline}} -\end{everbatim*} +% I -------------------------------- Modular Exponentiation +% Computes x^m modulo n (with m non negative). +% We will always use it with 1 < x < n +% +% With xint 1.4 we should use ? and ?? (although in the case at hand ifsgn() +% and if() are ok; 1.4 still converts them to short-circuit branchers). +% The 1.4 xint.pdf was still giving here the code with ifone() and if() +% functions (given below after the one here using ? as demanded by the +% documentation) +% +\xintdefiifunc powmod_a(x, m, n) := + isone(m)? + % m=1, return x modulo n + { x /: n } + % m > 1 test if odd or even and do recursive call + { odd(m)? { x*sqr(powmod_a(x, m//2, n)) /: n } + { sqr(powmod_a(x, m//2, n)) /: n } + } + ; +\xintdefiifunc powmod(x, m, n) := (m)?{powmod_a(x, m, n)}{1}; + +%% Syntax used before xint 1.4: +% \xintdefiifunc powmod_a(x, m, n) := +% ifone(m, +% % m=1, return x modulo n +% x /: n, +% % m > 1 test if odd or even and do recursive call +% if(odd(m), (x*sqr(powmod_a(x, m//2, n))) /: n, +% sqr(powmod_a(x, m//2, n)) /: n +% ) +% ); +% \xintdefiifunc powmod(x, m, n) := if(m, powmod_a(x, m, n), 1); + +% II ------------------------------ Miller-Rabin compositeness witness + +% n=2^k m + 1 with m odd and k at least 1 + +% Choose 1 if at some point n-1 mod n found, we can't say anything and break out +% -> if however we never find n-1 mod n before reaching +% z=y^{2^{k-1}} with j=k +% we then have z^2=x^{n-1}. + % Suppose z is not -1 mod n. If z^2 is 1 mod n, then n can be prime only if + % z is 1 mod n, and we can go back up, until initial y, and we have already + % excluded y=1. Thus if z is not -1 mod n and z^2 is 1 then n is not prime. + % But if z^2 is not 1, then n is not prime by Fermat. Hence (z not -1 mod n) + % implies (n is composite). (Miller test) +% let's use again xintexpr indecipherable (except to author) syntax. Of course +% doing it with macros only would be faster. -When nesting \csa{xintFor*} loops, using \csa{xintSeq} in the inner loops is -inefficient, as the arithmetic sequence will be re-created each time. A more -efficient style is: -% -\begin{everbatim} - \edef\innersequence {\xintSeq[+2]{-50}{50}}% - \xintFor* #1 in {\xintSeq {13}{27}} \do - {\xintFor* #2 in \innersequence \do {stuff with #1 and #2}% - .. some other macros .. } -\end{everbatim} +% Here \xintdefiifunc is not usable because not compatible with iter, break, ... +% but \xintNewFunction comes to the rescue. -This is a general remark applying for any nesting of loops, one should avoid -recreating the inner lists of arguments at each iteration of the outer loop. +\xintNewFunction{isCompositeWitness}[4]{% x=#1, n=#2, m=#3, k=#4 + subs((y==1)?{0} + {iter(y;(j=#4)?{break(!(@==#2-1))} + {(@==#2-1)?{break(0)}{sqr(@)/:#2}},j=1++)} + ,y=powmod(#1,#3,#2))} +% added note (2018/03/07) it is possible in the above that m=#3 is never +% zero, so we should rather call powmod_a for a small gain, but I don't +% have time to re-read the code comments and settle this. + +% III ------------------------------------- Strong Pseudo Primes -When the loop is defined inside a macro for later execution the |#| characters -must be doubled.% -% -\footnote{sometimes what seems to be a macro argument isn't really; in - \csa{raisebox\{1cm\}\{}\csa{xintFor \#1 in \{a,b,c\} }\csa{do - \{\#1\}\}} no doubling should be done.} -% -For example: -% -\begin{everbatim*} -\def\T{\def\z {}% - \xintFor* ##1 in {{u}{v}{w}} \do {% - \xintFor ##2 in {x,y,z} \do {% - \expandafter\def\expandafter\z\expandafter {\z\sep (##1,##2)} }% - }% -}% -\T\def\sep {\def\sep{, }}\z -\end{everbatim*} +% cf +% http://oeis.org/A014233 +% +% -Similarly when the replacement text -of |\xintFor| defines a macro with parameters, the macro character |#| must be -doubled. +% check if positive integer <49 si a prime. +% 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47 +\def\IsVerySmallPrime #1% + {\ifnum#1=1 \xintdothis0\fi + \ifnum#1=2 \xintdothis1\fi + \ifnum#1=3 \xintdothis1\fi + \ifnum#1=5 \xintdothis1\fi + \ifnum#1=\numexpr (#1/2)*2\relax\xintdothis0\fi + \ifnum#1=\numexpr (#1/3)*3\relax\xintdothis0\fi + \ifnum#1=\numexpr (#1/5)*5\relax\xintdothis0\fi + \xintorthat 1} +\xintNewFunction{isPseudoPrime}[1]{% n = #1 + (#1<49)?% use ? syntax to evaluate only what is needed + {\IsVerySmallPrime{\xintthe#1}}% macro needs to be fed with #1 unlocked. + {(even(#1))? + {0} + {subs(% + % L expands to two values m, k hence isCompositeWitness does get + % its four variables x, n, m, k + isCompositeWitness(2, #1, L)? + {0}% + {isCompositeWitness(3, #1, L)? + {0}% + {isCompositeWitness(5, #1, L)? + {0}% + {isCompositeWitness(7, #1, L)? + {0}% +% above enough for N<3215031751 hence all TeX numbers + {isCompositeWitness(11, #1, L)? + {0}% +% above enough for N<2152302898747, hence all 12-digits numbers + {isCompositeWitness(13, #1, L)? + {0}% +% above enough for N<3474749660383 + {isCompositeWitness(17, #1, L)? + {0}% +% above enough for N<341550071728321 + {1}% + }% not needed to comment-out end of lines spaces inside + }% \xintexpr but this is too much of a habit for me with TeX! + }% I left some after the ? characters. + }% + }% + }% this computes (m, k) such that n = 2^k m + 1, m odd, k>=1 + , L=iter(#1//2;(even(@))?{@//2}{break(@,k)},k=1++))% + }% + }% +} -The iterated macros as well as the list items are allowed to contain explicit -|\par| tokens. +% if needed: +%\def\IsPseudoPrime #1{\xinttheiiexpr isPseudoPrime(#1)\relax} +\noindent The smallest prime number at least equal to 3141592653589 is +\xinttheiiexpr + seq(isPseudoPrime(3141592653589+n)? + {break(3141592653589+n)}{omit}, n=0++)\relax. +% we could not use 3141592653589++ syntax because it works only with TeX numbers +\par +\end{everbatim*} -\subsection{\csh{xintifForFirst}, \csh{xintifForLast}} -\label{xintifForFirst}\label{xintifForLast} -\csbxint{ifForFirst}\,\texttt{\{YES branch\}\{NO branch\}}\etype{nn} - and \csbxint{ifForLast}\,\texttt{\{YES - branch\}\hskip 0pt plus 0.2em \{NO branch\}}\etype{nn} execute the |YES| or -|NO| branch -if the -\csbxint{For} -or \csbxint{For*} loop is currently in its first, respectively last, iteration. -Designed to work as expected under nesting (but see frame next.) Don't forget -an empty brace pair |{}| if a branch is to do nothing. May be used multiple -times in the replacement text of the loop. -\begin{framed} - \noindent Pay attention to these implementation features: - \begin{itemize}[nosep, listparindent=\leftmarginiii] - \item \emph{if an inner \csbxint{For} loop is positioned before the - \csb{xintifForFirst} or \csb{xintifForLast} of the outer loop it will - contaminate their settings. This applies also naturally if the inner loop - arises from the expansion of some macro located before the outer - conditionals.} - One fix is to make sure that the outer conditionals are expanded before the - inner loop is executed, e.g. this will be the case if the inner loop is - located inside one of the branches of the conditional. +\subsection{A table of factorizations} +\label{ssec:factorizationtable} - Another approach is to enclose, if feasible, the inner loop in a group of - its own. - \item \emph{if the replacement text closes a group (e.g. from a |&| inside an - alignment), the conditionals will lose their ascribed meanings and end up - possibly undefined, depending whether there is some outer loop whose - execution started before the opening of the group.} +As one more example with \csbxint{iloop} let us use an alignment to display the +factorization of some numbers. The loop will actually only play a minor r\^ole +here, just handling the row index, the row contents being almost entirely +produced via a macro |\factorize|. The factorizing macro does not use +|\xintiloop| as it didn't appear to be the convenient tool. As |\factorize| will +have to be used on |\xintiloopindex|, it has been defined as a delimited macro. - The fix is to arrange things so that the conditionals are expanded - before \TeX\ encounters the closing-group token. - \end{itemize} -\end{framed} +To spare some fractions of a second in the compilation time of this document +(which has many many other things to do), \number"7FFFFFED{} and +\number"7FFFFFFF, which turn out to be prime numbers, are not given to +|factorize| but just typeset directly; this illustrates use of +\csbxint{iloopskiptonext}. -\subsection{ \csh{xintBreakFor}, \csh{xintBreakForAndDo}} -\label{xintBreakFor}\label{xintBreakForAndDo} +The code next generates a \hyperref[floatfactorize]{table} which has +been made into a float appearing \vpageref{floatfactorize}. Here is now +the code for factorization; the conditionals use the package provided +|\xint_firstoftwo| and |\xint_secondoftwo|, one could have employed +rather \LaTeX{}'s own |\@firstoftwo| and |\@secondoftwo|, or, simpler +still in \LaTeX{} context, the |\ifnumequal|, |\ifnumless| \dots, +utilities from the package |etoolbox| which do exactly that under the +hood. Only \TeX{} acceptable numbers are treated here, but it would be +easy to make a translation and use the \xintname macros, thus extending +the scope to big numbers; naturally up to a cost in speed. -One may immediately terminate an \csbxint{For} or \csbxint{For*} loop with -\csbxint{BreakFor}. +The reason for some strange looking expressions is to avoid arithmetic overflow. -\begin{framed} - As it acts by clearing up all the rest of the replacement text when - encountered, it will not work from inside some |\if...\fi| without - suitable |\expandafter| or swapping technique. +\begin{everbatim*} +\catcode`_ 11 +\def\abortfactorize #1\xint_secondoftwo\fi #2#3{\fi} - Also it can't be used from inside braces as from there it can't see the end - of the replacement text. -\end{framed} +\def\factorize #1.{\ifnum#1=1 \abortfactorize\fi + \ifnum\numexpr #1-2=\numexpr ((#1/2)-1)*2\relax + \expandafter\xint_firstoftwo + \else\expandafter\xint_secondoftwo + \fi + {2&\expandafter\factorize\the\numexpr#1/2.}% + {\factorize_b #1.3.}}% -There is also \csbxint{BreakForAndDo}. Both are illustrated by various examples -in the next section which is devoted to ``forever'' loops. +\def\factorize_b #1.#2.{\ifnum#1=1 \abortfactorize\fi + \ifnum\numexpr #1-(#2-1)*#2<#2 + #1\abortfactorize + \fi + \ifnum \numexpr #1-#2=\numexpr ((#1/#2)-1)*#2\relax + \expandafter\xint_firstoftwo + \else\expandafter\xint_secondoftwo + \fi + {#2&\expandafter\factorize_b\the\numexpr#1/#2.#2.}% + {\expandafter\factorize_b\the\numexpr #1\expandafter.% + \the\numexpr #2+2.}}% +\catcode`_ 8 +\begin{figure*}[ht!] +\centering\phantomsection\label{floatfactorize}\normalcolor +\tabskip1ex +\centeredline{\vbox{\halign {\hfil\strut#\hfil&&\hfil#\hfil\cr\noalign{\hrule} + \xintiloop ["7FFFFFE0+1] + \expandafter\bfseries\xintiloopindex & + \ifnum\xintiloopindex="7FFFFFED + \number"7FFFFFED\cr\noalign{\hrule} + \expandafter\xintiloopskiptonext + \fi + \expandafter\factorize\xintiloopindex.\cr\noalign{\hrule} + \ifnum\xintiloopindex<"7FFFFFFE + \repeat + \bfseries \number"7FFFFFFF&\number "7FFFFFFF\cr\noalign{\hrule} +}}} +\centeredline{A table of factorizations} +\end{figure*} +\end{everbatim*} -\subsection{\csh{xintintegers}, \csh{xintdimensions}, \csh{xintrationals}} -\label{xintegers}\label{xintintegers} -\label{xintdimensions}\label{xintrationals} +\subsection{Another table of primes} +\label{ssec:primesIII} -If the list argument to \csbxint{For} (or \csbxint{For*}, both are equivalent in -this context) is \csbxint{integers} (equivalently \csbxint{egers}) or more -generally \csbxint{integers}|[||start|\allowbreak|+|\allowbreak|delta||]| -(\emph{the whole within braces}!)% -% -\footnote{the |start+delta| optional specification may have extra spaces - around the plus sign of near the square brackets, such spaces are - removed. The same applies with \csa{xintdimensions} and - \csa{xintrationals}.}, -% -then \csbxint{For} does an infinite iteration where -|#1| (or |#2|, \dots, |#9|) will run through the arithmetic sequence of (short) -integers with initial value |start| and increment |delta| (default values: -|start=1|, |delta=1|; if the optional argument is present it must contains both -of them, and they may be explicit integers, or macros or count registers). The -|#1| (or |#2|, \dots, |#9|) will stand for |\numexpr \relax|, -and the litteral representation as a string of digits can thus be obtained as -\fbox{\csa{the\#1}} or |\number#1|. Such a |#1| can be used in an |\ifnum| test -with no need to be postfixed with a space or a |\relax| and one should -\emph{not} add them. +As a further example, let us dynamically generate a tabular with the first $50$ +prime numbers after $12345$. First we need a macro to test if a (short) number +is prime. Such a completely expandable macro was given in \autoref{ssec:primesI}, +here we consider a variant which will be slightly more efficient. This new +|\IsPrime| has two parameters. The first one is a macro which it redefines to +expand to the result of the primality test applied to the second argument. For +convenience we use the \href{http://ctan.org/pkg/etoolbox}{etoolbox} wrappers to +various |\ifnum| tests, although here there isn't anymore the constraint of +complete expandability (but using explicit |\if..\fi| in tabulars has its +quirks); equivalent tests are provided by \xintname, but they have some overhead +as they are able to deal with arbitrarily big integers. -If the list argument is \csbxint{dimensions} or more generally -\csbxint{dimensions}|[||start|\allowbreak|+|\allowbreak|delta||]| (\emph{within - braces}!), then -\csbxint{For} does an infinite iteration where |#1| (or |#2|, \dots, |#9|) will -run through the arithmetic sequence of dimensions with initial value -|start| and increment |delta|. Default values: |start=0pt|, |delta=1pt|; if -the optional argument is present it must contain both of them, and they may -be explicit specifications, or macros, or dimen registers, or length macros -in \LaTeX{} (the stretch and shrink components will be discarded). The |#1| -will be |\dimexpr sp\relax|, from which one can get the -litteral (approximate) representation in points via |\the#1|. So |#1| can be -used anywhere \TeX{} expects a dimension (and there is no need in conditionals -to insert a |\relax|, and one should \emph{not} do it), and to print its value -one uses \fbox{\csa{the\#1}}. The chosen representation guarantees exact -incrementation with no rounding errors accumulating from converting into -points at each step. +\def\IsPrime #1#2% +{\edef\TheNumber {\the\numexpr #2}% positive integer + \ifnumodd {\TheNumber} + {\ifnumgreater {\TheNumber}{1} + {\edef\ItsSquareRoot{\xintiiSqrt \TheNumber}% + \xintFor ##1 in {\xintintegers [3+2]}\do + {\ifnumgreater {##1}{\ItsSquareRoot} + {\def#1{1}\xintBreakFor} + {}% + \ifnumequal {\TheNumber}{(\TheNumber/##1)*##1} + {\def#1{0}\xintBreakFor } + {}% + }} + {\def#1{0}}}% 1 is not prime + {\ifnumequal {\TheNumber}{2}{\def#1{1}}{\def#1{0}}}% +}% +\everb|@ +\def\IsPrime #1#2% """color[named]{PineGreen}#1=\Result, #2=tested number (assumed >0).;! +{\edef\TheNumber {\the\numexpr #2}%"""color[named]{PineGreen} hence #2 may be a count or \numexpr.;! + \ifnumodd {\TheNumber} + {\ifnumgreater {\TheNumber}{1} + {\edef\ItsSquareRoot{\xintiiSqrt \TheNumber}% + \xintFor """color{red}##1;! in {"""color{red}\xintintegers;! [3+2]}\do + {\ifnumgreater {"""color{red}##1;!}{\ItsSquareRoot} """color[named]{PineGreen}% "textcolor{red}{##1} is a \numexpr.;! + {\def#1{1}\xintBreakFor} + {}% + \ifnumequal {\TheNumber}{(\TheNumber/##1)*##1} + {\def#1{0}\xintBreakFor } + {}% + }} + {\def#1{0}}}% 1 is not prime + {\ifnumequal {\TheNumber}{2}{\def#1{1}}{\def#1{0}}}% +} +| +As we used \csbxint{For} inside a macro we had to double the |#| in its |#1| +parameter. Here is now the code which creates the prime table (the table has +been put in a \hyperref[primes]{float}, which should be found on page +\pageref{primes}): +\everb?@ +\newcounter{primecount} +\newcounter{cellcount} +\begin{figure*}[ht!] + \centering + \begin{tabular}{|*{7}c|} + \hline + \setcounter{primecount}{0}\setcounter{cellcount}{0}% + \xintFor """color{red}#1;! in {"""color{red}\xintintegers;! [12345+2]} \do +"""color[named]{PineGreen}% "textcolor{red}{#1} is a \numexpr.;! + {\IsPrime\Result{#1}% + \ifnumgreater{\Result}{0} + {\stepcounter{primecount}% + \stepcounter{cellcount}% + \ifnumequal {\value{cellcount}}{7} + {"""color{red}\the#1;! \\\setcounter{cellcount}{0}} + {"""color{red}\the#1;! &}} + {}% + \ifnumequal {\value{primecount}}{50} + {\xintBreakForAndDo + {\multicolumn {6}{l|}{These are the first 50 primes after 12345.}\\}} + {}% + }\hline +\end{tabular} +\end{figure*} +? +\begin{figure*}[ht!] + \centering\phantomsection\label{primes} + \begin{tabular}{|*{7}c|} + \hline + \setcounter{primecount}{0}\setcounter{cellcount}{0}% + \xintFor #1 in {\xintintegers [12345+2]} \do + {\IsPrime\Result{#1}% + \ifnumgreater{\Result}{0} + {\stepcounter{primecount}% + \stepcounter{cellcount}% + \ifnumequal {\value{cellcount}}{7} + {\the#1 \\\setcounter{cellcount}{0}} + {\the#1 &}} + {}% + \ifnumequal {\value{primecount}}{50} + {\xintBreakForAndDo + {\multicolumn {6}{l|}{These are the first 50 primes after 12345.}\\}} + {}% + }\hline +\end{tabular} +\end{figure*} +\subsection{Factorizing again} +\label{ssec:factorize} -If the list argument to \csbxint{For} (or \csbxint{For*}) is \csbxint{rationals} -or more generally -\csbxint{rationals}|[||start|\allowbreak|+|\allowbreak|delta||]| (\emph{within - braces}!), then \csbxint{For} does an infinite iteration where |#1| (or |#2|, -\dots, |#9|) will run through the arithmetic sequence of \xintfracname fractions -with initial value |start| and increment |delta| (default values: |start=1/1|, -|delta=1/1|). This loop works \emph{only with \xintfracname loaded}. if the -optional argument is present it must contain both of them, and they may be given -in any of the formats recognized by \xintfracname (fractions, decimal -numbers, numbers in scientific notations, numerators and denominators in -scientific notation, etc...) , or as macros or count registers (if they are -short integers). The |#1| (or |#2|, \dots, |#9|) will be an |a/b| fraction -(without a |[n]| part), where -the denominator |b| is the product of the denominators of -|start| and |delta| (for reasons of speed |#1| is not reduced to irreducible -form, and for another reason explained later |start| and |delta| are not put -either into irreducible form; the input may use explicitely \csa{xintIrr} to -achieve that). +Here is an \fexpan dable macro which computes the factors of an integer. It +uses the \xintname macros only. \begin{everbatim*} -\begingroup\small -\noindent\parbox{\dimexpr\linewidth-3em}{\color[named]{OrangeRed}% -\xintFor #1 in {\xintrationals [10/21+1/21]} \do -{#1=\xintifInt {#1} - {\textcolor{blue}{\xintTrunc{10}{#1}}} - {\xintTrunc{10}{#1}}% display in blue if an integer - \xintifGt {#1}{1.123}{\xintBreakFor}{, }% - }} -\endgroup\smallskip +\catcode`\@ 11 +\let\factorize\relax +\newcommand\Factorize [1] + {\romannumeral0\expandafter\factorize\expandafter{\romannumeral-`0#1}}% +\newcommand\factorize [1]{\xintiiifOne{#1}{ 1}{\factors@a #1.{#1};}}% +\def\factors@a #1.{\xintiiifOdd{#1} + {\factors@c 3.#1.}% + {\expandafter\factors@b \expandafter1\expandafter.\romannumeral0\xinthalf{#1}.}}% +\def\factors@b #1.#2.{\xintiiifOne{#2} + {\factors@end {2, #1}}% + {\xintiiifOdd{#2}{\factors@c 3.#2.{2, #1}}% + {\expandafter\factors@b \the\numexpr #1+\@ne\expandafter.% + \romannumeral0\xinthalf{#2}.}}% +}% +\def\factors@c #1.#2.{% + \expandafter\factors@d\romannumeral0\xintiidivision {#2}{#1}{#1}{#2}% +}% +\def\factors@d #1#2#3#4{\xintiiifNotZero{#2} + {\xintiiifGt{#3}{#1} + {\factors@end {#4, 1}}% ultimate quotient is a prime with power 1 + {\expandafter\factors@c\the\numexpr #3+\tw@.#4.}}% + {\factors@e 1.#3.#1.}% +}% +\def\factors@e #1.#2.#3.{\xintiiifOne{#3} + {\factors@end {#2, #1}}% + {\expandafter\factors@f\romannumeral0\xintiidivision {#3}{#2}{#1}{#2}{#3}}% +}% +\def\factors@f #1#2#3#4#5{\xintiiifNotZero{#2} + {\expandafter\factors@c\the\numexpr #4+\tw@.#5.{#4, #3}}% + {\expandafter\factors@e\the\numexpr #3+\@ne.#4.#1.}% +}% +\def\factors@end #1;{\xintlistwithsep{, }{\xintRevWithBraces {#1}}}% +\catcode`@ 12 \end{everbatim*} +The macro will be acceptably efficient only with numbers having somewhat small +prime factors. +\begin{everbatim} +\Factorize{16246355912554185673266068721806243461403654781833} +\end{everbatim} +\begingroup\fdef\Z +{\Factorize{16246355912554185673266068721806243461403654781833}} +\noindent{\small\dtt{\Z}} -\smallskip The example above confirms that computations are done exactly, and -illustrates that the two initial (reduced) denominators are not multiplied when -they are found to be equal. It is thus recommended to input |start| and |delta| -with a common smallest possible denominator, or as fixed point numbers with the -same numbers of digits after the decimal mark; and this is also the reason why -|start| and |delta| are not by default made irreducible. As internally the -computations are done with numerators and denominators completely expanded, one -should be careful not to input numbers in scientific notation with exponents in -the hundreds, as they will get converted into as many zeroes. +It puts a little stress on the input save stack in order +not be bothered with previously gathered things.\footnote{2015/11/18 I have + not revisited this code for a long time, and perhaps I could improve it now + with some new techniques.} + +Its output is a comma separated list with the number first, then its prime +factors with multiplicity. Let's produce something prettier: \begin{everbatim*} -\noindent\parbox{\dimexpr.7\linewidth}{\raggedright -\xintFor #1 in {\xintrationals [0.000+0.125]} \do -{\edef\tmp{\xintTrunc{3}{#1}}% - \xintifInt {#1} - {\textcolor{blue}{\tmp}} - {\tmp}% - \xintifGt {#1}{2}{\xintBreakFor}{, }% - }}\smallskip +\catcode`_ 11 +\def\ShowFactors #1{\expandafter\ShowFactors_a\romannumeral-`0\Factorize{#1},\relax,\relax,} +\def\ShowFactors_a #1,{#1=\ShowFactors_b} +\def\ShowFactors_b #1,#2,{\if\relax#1\else#1^{#2}\expandafter\ShowFactors_b\fi} +\catcode`_ 8 \end{everbatim*} +\begin{everbatim} +$$\ShowFactors{16246355912554185673266068721806243461403654781833}$$ +\end{everbatim} +$$\csname ShowFactors_a\expandafter\endcsname\Z,\relax,\relax,$$ +\endgroup -We see here that \csbxint{Trunc} outputs (deliberately) zero as $0$, not (here) -$0.000$, the idea being not to lose the information that the truncated thing was -truly zero. Perhaps this behaviour should be changed? or made optional? Anyhow -printing of fixed points numbers should be dealt with via dedicated packages -such as |numprint| or |siunitx|.\par - +If we only considered small integers, we could write pure |\numexpr| methods +which would be very much faster (especially if we had a table of small primes +prepared first) but still ridiculously slow compared to any non expandable +implementation, not to mention use of programming languages directly accessing +the CPU registers\dots -\subsection{\csh{xintForpair}, \csh{xintForthree}, \csh{xintForfour}}\label{xintForpair}\label{xintForthree}\label{xintForfour} +\subsection{The Quick Sort algorithm illustrated}\label{ssec:quicksort} -The syntax\ntype{on} is illustrated in this -example. The notation is the usual one for |n|-uples, with parentheses and -commas. Spaces around commas and parentheses are ignored. +First a completely expandable macro which sorts a comma separated list of +numbers.% % -\begin{everbatim*} -{\centering\begin{tabular}{cccc} - \xintForpair #1#2 in { ( A , a ) , ( B , b ) , ( C , c ) } \do {% - \xintForpair #3#4 in { ( X , x ) , ( Y , y ) , ( Z , z ) } \do {% - $\Biggl($\begin{tabular}{cc} - -#1- & -#3-\\ - -#4- & -#2-\\ - \end{tabular}$\Biggr)$&}\\\noalign{\vskip1\jot}}% -\end{tabular}\\} -\end{everbatim*} - -\csbxint{Forpair} must be followed by either |#1#2|, |#2#3|, |#3#4|, \dots, or -|#8#9| with |#1| usable as an alias for |#1#2|, |#2| as alias for |#2#3|, -etc \dots\ and similarly for \csbxint{Forthree} (using |#1#2#3| or simply -|#1|, |#2#3#4| or simply |#2|, \dots) and \csbxint{Forfour} (with |#1#2#3#4| -etc\dots). +\footnote{The code in earlier versions of this manual handled inputs composed + of braced items. I have switched to comma separated inputs on the occasion + of (link removed) + The version here is like + |code 3| on + (link removed) (which is about |3x| faster + than the earlier code it replaced in this manual) with a modification to + make it more efficient if the data has many repeated values. -Nesting works as long as the macro parameters are distinct among |#1|, |#2|, -..., |#9|. A macro which expands to an \csa{xintFor} or a -\csa{xintFor(pair,three,four)} can be used in another one with no constraint -about using distinct macro parameters. + A faster routine (for sorting hundreds of values) is provided as |code 6| at + the link mentioned in the footnote, it is based on Merge Sort, but limited + to inputs which one can handle as \TeX{} dimensions.% -|\par| tokens are accepted in both the comma separated list and the -replacement text. + This |code 6| could be extended to handle more general numbers, as + acceptable by \xintfracname. I have also written a non expandable version, + which is even faster, but this matters really only when handling hundreds or + rather thousands of values.} +% +The |\QSx| macro expands its list argument, which may thus be a macro; its +comma separated items must expand to integers or decimal numbers or fractions +or scientific notation as acceptable to \xintfracname, but if an item is +itself some (expandable) macro, this macro will be expanded each time the item +is considered in a comparison test! This is actually good if the macro expands +in one step to the digits, and there are many many digits, but bad if the macro +needs to do many computations. Thus |\QSx| should be used with either explicit +numbers or with items being macros expanding in one step to the numbers +(particularly if these numbers are very big). -\subsection{\csh{xintAssign}}\label{xintAssign} +If the interest is only in \TeX{} integers, then one should replace the +|\xintifCmp| macro with a suitable conditional, possibly helped by tools such as +|\ifnumgreater|, |\ifnumequal| and |\ifnumless| from +\href{http://ctan.org/pkg/etoolbox}{etoolbox} (\LaTeX{} only; I didn't see a +direct equivalent to |\xintifCmp|.) Or, if we are dealing with decimal numbers +with at most four+four digits, then one should use suitable |\ifdim| tests. +Naturally this will boost consequently the speed, from having skipped all the +overhead in parsing fractions and scientific numbers as are acceptable by +\xintfracname macros, and subsequent treatment. -\csa{xintAssign}\meta{braced things}\csa{to}% -\meta{as many cs as they are things} %\ntype{{(f$\to$\lowast [x)}{\lowast N}} +\begin{everbatim*} +% THE QUICK SORT ALGORITHM EXPANDABLY +% \usepackage{xintfrac} in the preamble (latex) +\makeatletter +% use extra safe delimiters +\catcode`! 3 \catcode`? 3 +\def\QSx {\romannumeral0\qsx }% +% first we check if empty list (else \qsx@finish will not find a comma) +\def\qsx #1{\expandafter\qsx@a\romannumeral-`0#1,!,?}% +\def\qsx@a #1{\ifx,#1\expandafter\qsx@abort\else + \expandafter\qsx@start\fi #1}% +\def\qsx@abort #1?{ }% +\def\qsx@start {\expandafter\qsx@finish\romannumeral0\qsx@b,}% +\def\qsx@finish ,#1{ #1}% % -defines (without checking if something gets overwritten) the control sequences -on the right of \csa{to} to expand to the successive tokens or braced items -located to the left of \csa{to}. \csa{xintAssign} is not an expandable macro. +% we check if empty of single and if not pick up the first as Pivot: +\def\qsx@b ,#1#2,#3{\ifx?#3\xintdothis\qsx@empty\fi + \ifx!#3\xintdothis\qsx@single\fi + \xintorthat\qsx@separate {#1#2}{}{}{#1#2}#3}% +\def\qsx@empty #1#2#3#4#5{ }% +\def\qsx@single #1#2#3#4#5?{, #4}% +\def\qsx@separate #1#2#3#4#5#6,% +{% + \ifx!#5\expandafter\qsx@separate@done\fi + \xintifCmp {#5#6}{#4}% + \qsx@separate@appendtosmaller + \qsx@separate@appendtoequal + \qsx@separate@appendtogreater {#5#6}{#1}{#2}{#3}{#4}% +}% +% +\def\qsx@separate@appendtoequal #1#2{\qsx@separate {#2,#1}}% +\def\qsx@separate@appendtogreater #1#2#3{\qsx@separate {#2}{#3,#1}}% +\def\qsx@separate@appendtosmaller #1#2#3#4{\qsx@separate {#2}{#3}{#4,#1}}% +% +\def\qsx@separate@done\xintifCmp #1% + \qsx@separate@appendtosmaller + \qsx@separate@appendtoequal + \qsx@separate@appendtogreater #2#3#4#5#6#7?% +{% + \expandafter\qsx@f\expandafter {\romannumeral0\qsx@b #4,!,?}{\qsx@b #5,!,?}{#3}% +}% +% +\def\qsx@f #1#2#3{#2, #3#1}% +% +\catcode`! 12 \catcode`? 12 +\makeatother -\fexpan sion is first applied to the material in front of \csa{xintAssign} -which is fetched as one argument if it is braced. Then the expansion of this -argument is examined and successive items are assigned to the macros following -|\to|. There must be exactly as many macros as items. No check is done. The -macro assignments are done with removal of one level of brace pairs from each -item. +% EXAMPLE +\begingroup +\edef\z {\QSx {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, + 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9}} +\meaning\z -After the initial \fexpan sion, each assigned (brace-stripped) item will be -expanded according to the setting of the optional parameter. +\def\a {3.123456789123456789}\def\b {3.123456789123456788} +\def\c {3.123456789123456790}\def\d {3.123456789123456787} +\oodef\z {\QSx { \a, \b, \c, \d}}% +% The space before \a to let it not be expanded during the conversion from CSV +% values to List. The \oodef expands exactly twice (via a bunch of \expandafter's) +\meaning\z +\endgroup +\end{everbatim*} (the spaces after \string\d, etc... come from the use of the +|\meaning| primitive.) -For example |\xintAssign [e]...| means that all assignments are done using -|\edef|. With |[f]| the assignments will be made using -\hyperref[fdef]{\ttfamily\char92fdef}. The default is simply to make the -definitions with |\def|, corresponding to an empty optional paramter |[]|. -Possibilities for the optional parameter are: |[], [g], [e], [x], [o], [go], -[oo], [goo], [f], [gf]|. For example |[oo]| means a double expansion. +The choice of pivot as first element is bad if the list is already almost +sorted. Let's add a variant which will pick up the pivot index randomly. The +previous routine worked also internally with comma separated lists, but for a +change this one will use internally lists of braced items (the initial +conversion via \csbxint{CSVtoList} handles all potential spurious space +problems). + +\unless\ifxetex % pour tester compilation de xint.dtx avec xetex qui n'a pas + % \pdfuniformdeviate \begin{everbatim*} -\xintAssign \xintiiDivision{1000000000000}{133333333}\to\Q\R -\meaning\Q\newline -\meaning\R\newline -\xintAssign {{\xintiiDivision{1000000000000}{133333333}}}\to\X -\meaning\X\newline -\xintAssign [oo]{{\xintiiDivision{1000000000000}{133333333}}}\to\X -\meaning\X\newline -\xintAssign \xintiiPow{7}{13}\to\SevenToThePowerThirteen -\meaning\SevenToThePowerThirteen\par -\end{everbatim*} +% QuickSort expandably on comma separated values with random choice of pivots +% ====> Requires availability of \pdfuniformdeviate <==== +% \usepackage{xintfrac, xinttools} in preamble +\makeatletter +\def\QSx {\romannumeral0\qsx }% This is a f-expandable macro. +% This converts from comma separated values on input and back on output. +% **** NOTE: these steps (and the other ones too, actually) are costly if input +% has thousands of items. +\def\qsx #1{\xintlistwithsep{, }% + {\expandafter\qsx@sort@a\expandafter{\romannumeral0\xintcsvtolist{#1}}}}% +% +% we check if empty or single or double and if not pick up the first as Pivot: +\def\qsx@sort@a #1% + {\expandafter\qsx@sort@b\expandafter{\romannumeral0\xintlength{#1}}{#1}}% +\def\qsx@sort@b #1{\ifcase #1 + \expandafter\qsx@sort@empty + \or\expandafter\qsx@sort@single + \or\expandafter\qsx@sort@double + \else\expandafter\qsx@sort@c\fi {#1}}% +\def\qsx@sort@empty #1#2{ }% +\def\qsx@sort@single #1#2{#2}% +\catcode`_ 11 +\def\qsx@sort@double #1#2{\xintifGt #2{\xint_exchangetwo_keepbraces}{}#2}% +\catcode`_ 8 +\def\qsx@sort@c #1#2{% + \expandafter\qsx@sort@sep@a\expandafter + {\romannumeral0\xintnthelt{\pdfuniformdeviate #1+\@ne}{#2}}#2?}% +\def\qsx@sort@sep@a #1{\qsx@sort@sep@loop {}{}{}{#1}}% +\def\qsx@sort@sep@loop #1#2#3#4#5% +{% + \ifx?#5\expandafter\qsx@sort@sep@done\fi + \xintifCmp {#5}{#4}% + \qsx@sort@sep@appendtosmaller + \qsx@sort@sep@appendtoequal + \qsx@sort@sep@appendtogreater {#5}{#1}{#2}{#3}{#4}% +}% +% +\def\qsx@sort@sep@appendtoequal #1#2{\qsx@sort@sep@loop {#2{#1}}}% +\def\qsx@sort@sep@appendtogreater #1#2#3{\qsx@sort@sep@loop {#2}{#3{#1}}}% +\def\qsx@sort@sep@appendtosmaller #1#2#3#4{\qsx@sort@sep@loop {#2}{#3}{#4{#1}}}% +% +\def\qsx@sort@sep@done\xintifCmp #1% + \qsx@sort@sep@appendtosmaller + \qsx@sort@sep@appendtoequal + \qsx@sort@sep@appendtogreater #2#3#4#5#6% +{% + \expandafter\qsx@sort@recurse\expandafter + {\romannumeral0\qsx@sort@a {#4}}{\qsx@sort@a {#5}}{#3}% +}% +% +\def\qsx@sort@recurse #1#2#3{#2#3#1}% +% +\makeatother -Two special cases: -\begin{itemize}[nosep] -\item if after this initial expansion no brace is found immediately after - \csa{xintAssign}, it is assumed that there is only one control sequence - following |\to|, and this control sequence is then defined via |\def| (or - what is set-up by the optional parameter) to expand to the material between - \csa{xintAssign} and \csa{to}. -\item if the material between \csa{xintAssign} and |\to| is enclosed in two - brace pairs, the first brace pair is removed, then the \fexpan sion is - immediately stopped by the inner brace pair, hence \csa{xintAssign} now - finds a unique item and thus defines only a single macro to be this item, - which is now stripped of the second pair of braces. -\end{itemize} +% EXAMPLES +\begingroup +\edef\z {\QSx {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, + 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9}} +\meaning\z +\def\a {3.123456789123456789}\def\b {3.123456789123456788} +\def\c {3.123456789123456790}\def\d {3.123456789123456787} +\oodef\z {\QSx { \a, \b, \c, \d}}% +% The space before \a to let it not be expanded during the conversion from CSV +% values to List. The \oodef expands exactly twice (via a bunch of \expandafter's) +\meaning\z -\emph{Note:} prior to release |1.09j|, |\xintAssign| did an |\edef| by default -for each item assignment but it now does |\def| corresponding to no or empty -optional parameter. +\def\somenumbers{% +3997.6421, 8809.9358, 1805.4976, 5673.6478, 3179.1328, 1425.4503, 4417.7691, +2166.9040, 9279.7159, 3797.6992, 8057.1926, 2971.9166, 9372.2699, 9128.4052, +1228.0931, 3859.5459, 8561.7670, 2949.6929, 3512.1873, 1698.3952, 5282.9359, +1055.2154, 8760.8428, 7543.6015, 4934.4302, 7526.2729, 6246.0052, 9512.4667, +7423.1124, 5601.8436, 4433.5361, 9970.4849, 1519.3302, 7944.4953, 4910.7662, +3679.1515, 8167.6824, 2644.4325, 8239.4799, 4595.1908, 1560.2458, 6098.9677, +3116.3850, 9130.5298, 3236.2895, 3177.6830, 5373.1193, 5118.4922, 2743.8513, +8008.5975, 4189.2614, 1883.2764, 9090.9641, 2625.5400, 2899.3257, 9157.1094, +8048.4216, 3875.6233, 5684.3375, 8399.4277, 4528.5308, 6926.7729, 6941.6278, +9745.4137, 1875.1205, 2755.0443, 9161.1524, 9491.1593, 8857.3519, 4290.0451, +2382.4218, 3678.2963, 5647.0379, 1528.7301, 2627.8957, 9007.9860, 1988.5417, +2405.1911, 5065.8063, 5856.2141, 8989.8105, 9349.7840, 9970.3013, 8105.4062, +3041.7779, 5058.0480, 8165.0721, 9637.7196, 1795.0894, 7275.3838, 5997.0429, +7562.6481, 8084.0163, 3481.6319, 8078.8512, 2983.7624, 3925.4026, 4931.5812, +1323.1517, 6253.0945}% -It is allowed for the successive braced items to be separated by spaces. They -are removed during the assignments. But if a single macro is defined (which -happens if the argument after \fexpan sion does not start with a brace), -naturally the scooped up material has all intervening spaces, as it is -considered a -single item. But an upfront initial space will have been absorbed by \fexpan -sion. -\begin{everbatim*} -\def\X{ {a} {b} {c} {d} }\def\Y { u {a} {b} {c} {d} } -\xintAssign\X\to\A\B\C\D -\xintAssign\Y\to\Z -\meaning\A, \meaning\B, \meaning\C, \meaning\D+++\newline -\meaning\Z+++\par +\oodef\z {\QSx \somenumbers}% produced as a comma+space separated list +% black magic as workaround to the shrinkability of spaces in last line... +\hsize 87\fontcharwd\font`0 +\lccode`~=32 +\lowercase{\def~}{\discretionary{}{}{\kern\fontcharwd\font`0}}\catcode32 13 +\noindent\phantom{000}\scantokens\expandafter{\meaning\z}\par +\endgroup \end{everbatim*} -As usual successive space characters in input make for a single \TeX\ space token. - +\fi % fin de si pas xetex -\subsection{\csh{xintAssignArray}}\label{xintAssignArray} -\xintAssignArray \xintBezout {1000}{113}\to\Bez +All the previous examples were with numbers which could have been handled via +|\ifdim| tests rather than the \csbxint{ifCmp} macro from \xintfracname; using +|\ifdim| tests would naturally be faster. Even faster routine is |code 6| at +(link removed) which uses |\pdfescapestring| and a +Merge Sort algorithm. -\csa{xintAssignArray}\meta{braced things}\csa{to}\csa{myArray} +We then turn to a graphical illustration of the algorithm.% % -%\ntype{{(f$\to$\lowast x)}N} +\footnote{I have rewritten (2015/11/21) the routine to do only once (and not thrice) the + needed calls to \csa{xintifCmp}, up to the price of one additional |\edef|, + although due to the context execution time on our side is not an issue and + moreover is anyhow overwhelmed by the TikZ's activities. Simultaneously I + have updated the code. + The + variant with the choice of pivot on the right has more overhead: the reason + is simply that we do not convert the data into an array, but maintain a list + of tokens with self-reorganizing delimiters.} % -first expands fully what comes immediately after |\xintAssignArray| and -expects to find a list of braced things |{A}{B}...| (or tokens). It then -defines \csa{myArray} as a macro with one parameter, such that \csa{myArray\x} -expands to give the |x|th braced thing of this original -list (the argument \texttt{\x} itself is fed to a |\numexpr| by |\myArray|, -and |\myArray| expands in two steps to its output). With |0| as parameter, -\csa{myArray}|{0}| returns the number |M| of elements of the array so that the -successive elements are \csa{myArray}|{1}|, \dots, \csa{myArray}|{M}|. +For simplicity the pivot is always chosen as the first list item. Then we also +give a variant which picks up the last item as pivot. +\begin{everbatim*} +% in LaTeX preamble: +% \usepackage{xintfrac, xinttools} +% \usepackage{color} +% or, when using Plain TeX: +% \input xintfrac.sty \input xinttools.sty +% \input color.tex % -\leftedline{|\xintAssignArray \xintBezout {1000}{113}\to\Bez|} will set -|\Bez{0}| to \dtt{\Bez0}, |\Bez{1}| to \dtt{\Bez1}, |\Bez{2}| to -\dtt{\Bez2}, and |\Bez{3}| to \dtt{\Bez3}: -\dtt{$\Bez1\times1000+\Bez2\times113=\Bez3$.} -This macro is incompatible with expansion-only contexts. - -\csa{xintAssignArray} admits an optional parameter, for example -|\xintAssignArray [e]| means that the definitions of the macros will be made -with |\edef|. The empty optional parameter (default) means that definitions -are done with |\def|. Other possibilities: |[], [o], [oo], [f]|. Contrarily to -\csbxint{Assign} one can not use the |g| here to make the definitions global. -For this, one should rather do |\xintAssignArray| within a group starting with -|\globaldefs 1|. - - -\subsection{\csh{xintDigitsOf}}\label{xintDigitsOf} - -This is a synonym for \csbxint{AssignArray},\ntype{fN} to be used to define -an array giving all the digits of a given (positive, else the minus sign will -be treated as first item) number. -\begingroup\xintDigitsOf\xintiiPow {7}{500}\to\digits +% Color definitions +\definecolor{LEFT}{RGB}{216,195,88} +\definecolor{RIGHT}{RGB}{208,231,153} +\definecolor{INERT}{RGB}{199,200,194} +\definecolor{INERTpiv}{RGB}{237,237,237} +\definecolor{PIVOT}{RGB}{109,8,57} +% Start of macro defintions +\makeatletter +% \catcode`? 3 % a bit too paranoid. Normal ? will do. % -\leftedline{|\xintDigitsOf\xintiiPow {7}{500}\to\digits|} -\noindent $7^{500}$ has |\digits{0}=|\digits{0} digits, and the 123rd among them -(starting from the most significant) is -|\digits{123}=|\digits{123}. +% argument will never be empty +\def\QS@cmp@a #1{\QS@cmp@b #1??}% +\def\QS@cmp@b #1{\noexpand\QS@sep@A\@ne{#1}\QS@cmp@d {#1}}% +\def\QS@cmp@d #1#2{\ifx ?#2\expandafter\QS@cmp@done\fi + \xintifCmp {#1}{#2}\tw@\@ne\z@{#2}\QS@cmp@d {#1}}% +\def\QS@cmp@done #1?{?}% +% +\def\QS@sep@A #1?{\QSLr\QS@sep@L #1\thr@@?#1\thr@@?#1\thr@@?}% +\def\QS@sep@L #1#2{\ifcase #1{#2}\or\or\else\expandafter\QS@sep@I@start\fi \QS@sep@L}% +\def\QS@sep@I@start\QS@sep@L {\noexpand\empty?\QSIr\QS@sep@I}% +\def\QS@sep@I #1#2{\ifcase#1\or{#2}\or\else\expandafter\QS@sep@R@start\fi\QS@sep@I}% +\def\QS@sep@R@start\QS@sep@I {\noexpand\empty?\QSRr\QS@sep@R}% +\def\QS@sep@R #1#2{\ifcase#1\or\or{#2}\else\expandafter\QS@sep@done\fi\QS@sep@R}% +\def\QS@sep@done\QS@sep@R {\noexpand\empty?}% +% +\def\QS@loop {% + \xintloop + % pivot phase + \def\QS@pivotcount{0}% + \let\QSLr\DecoLEFTwithPivot \let\QSIr \DecoINERT + \let\QSRr\DecoRIGHTwithPivot \let\QSIrr\DecoINERT + \centerline{\QS@list}% + % sorting phase + \ifnum\QS@pivotcount>\z@ + \def\QSLr {\QS@cmp@a}\def\QSRr {\QS@cmp@a}% + \def\QSIr {\QSIrr}\let\QSIrr\relax + \edef\QS@list{\QS@list}% compare + \let\QSLr\relax\let\QSRr\relax\let\QSIr\relax + \edef\QS@list{\QS@list}% separate + \def\QSLr ##1##2?{\ifx\empty##1\else\noexpand \QSLr {{##1}##2}\fi}% + \def\QSIr ##1##2?{\ifx\empty##1\else\noexpand \QSIr {{##1}##2}\fi}% + \def\QSRr ##1##2?{\ifx\empty##1\else\noexpand \QSRr {{##1}##2}\fi}% + \edef\QS@list{\QS@list}% gather + \let\QSLr\DecoLEFT \let\QSRr\DecoRIGHT + \let\QSIr\DecoINERTwithPivot \let\QSIrr\DecoINERT + \centerline{\QS@list}% + \repeat }% +% +% \xintFor* loops handle gracefully empty lists. +\def\DecoLEFT #1{\xintFor* ##1 in {#1} \do {\colorbox{LEFT}{##1}}}% +\def\DecoINERT #1{\xintFor* ##1 in {#1} \do {\colorbox{INERT}{##1}}}% +\def\DecoRIGHT #1{\xintFor* ##1 in {#1} \do {\colorbox{RIGHT}{##1}}}% +\def\DecoPivot #1{\begingroup\color{PIVOT}\advance\fboxsep-\fboxrule\fbox{#1}\endgroup}% +% +\def\DecoLEFTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% + \xintFor* ##1 in {#1} \do + {\xintifForFirst {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}}% +\def\DecoINERTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% + \xintFor* ##1 in {#1} \do + {\xintifForFirst {\colorbox{INERTpiv}{##1}}{\colorbox{INERT}{##1}}}}% +\def\DecoRIGHTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% + \xintFor* ##1 in {#1} \do + {\xintifForFirst {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}}% +% +\def\QuickSort #1{% warning: not compatible with empty #1. + % initialize, doing conversion from comma separated values to a list of braced items + \edef\QS@list{\noexpand\QSRr{\xintCSVtoList{#1}}}% many \edef's are to follow anyhow +% earlier I did a first drawing of the list, here with the color of RIGHT elements, +% but the color should have been for example white, anyway I drop this first line + %\let\QSRr\DecoRIGHT + %\par\centerline{\QS@list}% +% + % loop as many times as needed + \QS@loop }% +% +% \catcode`? 12 % in case we had used a funny ? as delimiter. +\makeatother +%% End of macro definitions. +%% Start of Example +\begingroup\offinterlineskip +\small +% \QuickSort {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, +% 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9} +% \medskip +% with repeated values +\QuickSort {1.0, 0.5, 0.3, 0.8, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, + 1.3, 1.1, 0.7, 0.3, 1.6, 0.6, 0.3, 0.8, 0.2, 0.8, 0.7, 1.2} \endgroup +\end{everbatim*} -\subsection{\csh{xintRelaxArray}}\label{xintRelaxArray} +Here is the variant which always picks the pivot as the rightmost element. -\csa{xintRelaxArray}\csa{myArray} %\ntype{N} +\begin{everbatim*} +\makeatletter % -(globally) sets to \csa{relax} all macros which were defined by the previous -\csa{xintAssignArray} with \csa{myArray} as array macro. +\def\QS@cmp@a #1{\noexpand\QS@sep@A\expandafter\QS@cmp@d\expandafter + {\romannumeral0\xintnthelt{-1}{#1}}#1??}% +% +\def\DecoLEFTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% + \xintFor* ##1 in {#1} \do + {\xintifForLast {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}} +\def\DecoINERTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% + \xintFor* ##1 in {#1} \do + {\xintifForLast {\colorbox{INERTpiv}{##1}}{\colorbox{INERT}{##1}}}} +\def\DecoRIGHTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% + \xintFor* ##1 in {#1} \do + {\xintifForLast {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}} +\def\QuickSort #1{% + % initialize, doing conversion from comma separated values to a list of braced items + \edef\QS@list{\noexpand\QSLr {\xintCSVtoList{#1}}}% many \edef's are to follow anyhow + % + % loop as many times as needed + \QS@loop }% +\makeatother +\begingroup\offinterlineskip +\small +% \QuickSort {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, +% 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9} +% \medskip +% with repeated values +\QuickSort {1.0, 0.5, 0.3, 0.8, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, + 1.3, 1.1, 0.7, 0.3, 1.6, 0.6, 0.3, 0.8, 0.2, 0.8, 0.7, 1.2} +\endgroup +\end{everbatim*} + +The choice of the first or last item as pivot is not a good one as nearly +ordered lists will take quadratic time. But for explaining the algorithm via a +graphical interpretation, it is not that bad. If one wanted to pick up the +pivot randomly, the routine would have to be substantially rewritten: in +particular the |\Deco..withPivot| macros need to know where the pivot is, and +currently this is implemented by using either |\xintifForFirst| or +|\xintifForLast|. \clearpage -\let\xinttoolsnameUp\undefined + +\expandafter\let\csname ExamplesnameUp\endcsname\undefined \ifnum\NoSourceCode=1 \bigskip @@ -17372,32 +17629,36 @@ be treated as first item) number. \makeatother -\section{Introduction to this document and (very much) shortened version history} +\section{History timeline} This is \expandafter|\xintbndlversion| of \expandafter|\xintbndldate|. -Please refer |CHANGES.html|.\centeredline{Internet: +Please refer |CHANGES.html| for a (much more) detailed history. +\centeredline{Internet: \url{http://mirrors.ctan.org/macros/generic/xint/CHANGES.html}} -We keep here only a brief timeline of the most important changes. \begin{itemize} -\item Release |1.4| of |2020/01/31|: this was a major release with - breaking changes, devoted to a re-write of \xintexprnameimp - with |\expanded| based expansion control rather than |\csname| storage - of intermediate computation results. Support for input and output - of nested structures, and multiple additions to \xintexprnameimp. +\item Release |1.4a| of |2020/02/19|: + fixes |1.4| known bugs. Improves documentation. +\item Release |1.4| of |2020/01/31|: \xintexprnameimp overhaul to use + |\expanded| based expansion control. Many new features, in particular support + for input and output of nested structures. Breaking changes, main ones + being the (provisory) drop of |x*[a, b,...]|, |x+[a, b,...]| et al.\@ syntax and the + requirement of |\expanded| primitive (currently required only by \xintexprnameimp). \item Release |1.3f| of |2019/09/10|: starred variant \csbxint{Digits*}. -\item Release |1.3e| of |2019/04/05|: \xinttrignameimp, \xintlognameimp, - \csa{xintdefefunc} ``non-protected'' variant of \csbxint{deffunc}. - - Indices removed from |sourcexint.pdf|. Their functionality is advantageously - made available via the search function in PDF viewers. Already the local - tables of contents are useful enough most of the time. -\item Release |1.3d| of |2019/01/06|: bugfix of |1.2p| bug for division with a +\item Release |1.3e| of |2019/04/05|: packages \xinttrignameimp, \xintlognameimp; + \csa{xintdefefunc} ``non-protected'' variant of \csbxint{deffunc} (at |1.4| + the two got merged and \csa{xintdefefunc} became a deprecated alias for + \csbxint{deffunc}). + Indices removed from |sourcexint.pdf|. +% Their functionality is advantageously + % made available via the search function in PDF viewers. Already the local + % tables of contents are useful enough most of the time. +\item Release |1.3d| of |2019/01/06|: fix of |1.2p| bug for division with a zero dividend and a one-digit divisor, \csbxint{eval} et al. wrappers, |gcd()| and |lcm()| work with fractions. \item Release |1.3c| of |2018/06/17|: documentation better hyperlinked, - |sourcexint.pdf| with indices of macros. Colon in |:=| now optional for + indices added to |sourcexint.pdf|. Colon in |:=| now optional for \csbxint{defvar} and \csbxint{deffunc}. \item Release |1.3b| of |2018/05/18|: randomness related additions (still WIP). \item Release |1.3a| of |2018/03/07|: efficiency fix of the mechanism for @@ -17406,8 +17667,8 @@ We keep here only a brief timeline of the most important changes. systematically least common multiple of denominators. Extensive under-the-hood refactoring of \csbxint{NewExpr} and \csbxint{deffunc} which now allow recursive definitions. Removal of |1.2o| deprecated macros. -\item Release |1.2q| of |2018/02/06|: bugfix release (|1.2l| subtraction bug - in special situation); tacit multiplication extended to cases such as +\item Release |1.2q| of |2018/02/06|: fix of |1.2l| subtraction bug + in special situation; tacit multiplication extended to cases such as |10!20!30!|. \item Release |1.2p| of |2017/12/05|: maps |//| and |/:| to the floored, not truncated, division. Simultaneous assignments possible with \csbxint{defvar}. @@ -17430,6 +17691,21 @@ We keep here only a brief timeline of the most important changes. Addition and subtraction do not multiply denominators blindly but sometimes produce smaller ones. Also with that release, packages \xintkernelnameimp and \xintcorenameimp got extracted from \xinttoolsnameimp and \xintnameimp. +\item Release |1.09g| of |2013/11/22|: the \xinttoolsnameimp package is + extracted from \xintnameimp; addition of \csbxint{loop} and \csbxint{iloop}. +\item Release |1.09c| of |2013/10/09|: \csbxint{For}, \csa{xintNewNumExpr} + (ancestor of \csbxint{NewExpr}/\csbxint{deffunc} mechanism). +\item Release |1.09a| of |2013/09/24|: support for functions by \xintexprnameimp. +\item Release |1.08| of |2013/06/07|: the \xintbinhexnameimp package. +\item Release |1.07| of |2013/05/25|: support for floating point numbers + added to \xintfracnameimp and first release of the \xintexprnameimp package + (provided + \csbxint{expr} and \csbxint{floatexpr}). +\item Release |1.04| of |2013/04/25|: the \xintcfracnameimp package. +\item Release |1.03| of |2013/04/14|: the \xintfracnameimp and + \xintseriesnameimp packages. +\item Release |1.0| of |2013/03/28|: initial release of the \xintnameimp and + \xintgcdnameimp packages. \end{itemize} Some parts of the code still date back to the initial release, and @@ -17638,7 +17914,7 @@ math shift catcode. \fi \XINT_providespackage \ProvidesPackage {xintkernel}% - [2020/01/31 v1.4 Paraphernalia for the xint packages (JFB)]% + [2020/02/19 v1.4a Paraphernalia for the xint packages (JFB)]% % \end{macrocode} % \subsection{Constants} % \begin{macrocode} @@ -18424,7 +18700,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xinttools}% - [2020/01/31 v1.4 Expandable and non-expandable utilities (JFB)]% + [2020/02/19 v1.4a Expandable and non-expandable utilities (JFB)]% % \end{macrocode} % \lverb|\XINT_toks is used in macros such as \xintFor. It is not used % elsewhere in the xint bundle.| @@ -20588,7 +20864,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcore}% - [2020/01/31 v1.4 Expandable arithmetic on big integers (JFB)]% + [2020/02/19 v1.4a Expandable arithmetic on big integers (JFB)]% % \end{macrocode} % \subsection{(WIP!) Error conditions and exceptions} % \lverb|As per the Mike Cowlishaw/IBM's General Decimal Arithmetic Specification @@ -23890,7 +24166,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xint}% - [2020/01/31 v1.4 Expandable operations on big integers (JFB)]% + [2020/02/19 v1.4a Expandable operations on big integers (JFB)]% % \end{macrocode} % \subsection{More token management} % \begin{macrocode} @@ -26456,7 +26732,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintbinhex}% - [2020/01/31 v1.4 Expandable binary and hexadecimal conversions (JFB)]% + [2020/02/19 v1.4a Expandable binary and hexadecimal conversions (JFB)]% % \end{macrocode} % \subsection{Constants, etc...} % \lverb|1.2n switches to \csname-governed expansion at various places.| @@ -27052,16 +27328,16 @@ math shift catcode. % From |1.1| to |1.3f| the package loaded only \xintcorenameimp. At |1.4| it % now automatically loads both of \xintnameimp and \xinttoolsnameimp (the % latter being in fact a requirement of \csbxint{TypesetEuclideAlgorithm} and -% \csbxint{TypesetBezoutAlgorithm} since |1.09h|. +% \csbxint{TypesetBezoutAlgorithm} since |1.09h|). % % \begin{framed} % At |1.4| \csbxint{GCD}, \csbxint{LCM}, \csbxint{GCDof}, and \csbxint{LCMof} % are \emph{removed} from the package:\IMPORTANTf they are provided only by % \xintfracnameimp and they handle general fractions, not only integers. % -% The original integer-only macros have been renamed into respectively +% The original\CHANGEDf{1.4} integer-only macros have been renamed into respectively % \csbxint{iiGCD}, \csbxint{iiLCM}, \csbxint{iiGCDof}, and \csbxint{iiLCMof} -% and got relocated into \xintnameimp package.\CHANGEDf{1.4} +% and got relocated into \xintnameimp package. % \end{framed} % % \subsection{Catcodes, \protect\eTeX{} and reload detection} @@ -27128,7 +27404,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintgcd}% - [2020/01/31 v1.4 Euclide algorithm with xint package (JFB)]% + [2020/02/19 v1.4a Euclide algorithm with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintBezout}} % \lverb|& @@ -27728,7 +28004,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintfrac}% - [2020/01/31 v1.4 Expandable operations on fractions (JFB)]% + [2020/02/19 v1.4a Expandable operations on fractions (JFB)]% % \end{macrocode} % \subsection{\csh{XINT_cntSgnFork}} % \lverb|1.09i. Used internally, #1 must expand to \m@ne, \z@, or \@ne or @@ -28835,6 +29111,9 @@ math shift catcode. % \end{macrocode} % \subsection{\csh{xintTrunc}, \csh{xintiTrunc}} % \lverb|& +% +% This of course has a long history. Only showing here some comments. +% % 1.2i release notes: ever since its inception this macro was stupid for a % decimal input: it did not handle it separately from the general fraction % case A/B[N] with B>1, hence ended up doing divisions by powers of ten. But @@ -28846,6 +29125,31 @@ math shift catcode. % is quite longer and making it f-expandable would not shorten it... I decided % for the time being to not complicate things here. % | +% \lverb|& +% +% 1.4a (2020/02/18) adds handling of a negative first argument. +% +% Zero input still gives single digit 0 output as I did not want to complicate +% the code. But if quantization gives 0, the exponent [D] will be there. Well +% actually eD because of problem that sign of original is preserved in output +% so we can have -0 and I can not use -0[D] notation as it is not legal for +% strict format. So I will use -0eD hence eD generally even though this means +% so slight suboptimality for trunc() function in \xintexpr. +% +% The idea to give a meaning to negative D (in the context of optional +% argument to \xintiexpr) was suggested a long time ago by Kpym (October 20, +% 2015). His suggestion was then to treat it as positive D but trim trailing +% zeroes. But since then, there is \xintDecToString which can be combined with +% \xintREZ, and I feel matters of formatting output require a whole module (or +% rather use existing third-party tools), and I decided to opt rather for an +% operation similar as the quantize() of Python Decimal module. I.e. we +% truncate (or round) to an integer multiple of a given power of 10. +% +% Other reason to decide to do this is that it looks as if I don't even need +% to understand the original code to hack into its ending via \XINT_trunc_G or +% \XINT_itrunc_G. For the latter it looks as if logically I simply have to do +% nothing. For the former I simply have to add some eD postfix. +% | % \begin{macrocode} \def\xintTrunc {\romannumeral0\xinttrunc }% \def\xintiTrunc {\romannumeral0\xintitrunc}% @@ -28862,16 +29166,8 @@ math shift catcode. \xint_orthat\XINT_trunc_b #1+#4.{#2}{#3}#5#4.% }% \def\XINT_trunc_zero #1.#2.{ 0}% -% \end{macrocode} -% \lverb|& -% | -% \begin{macrocode} \def\XINT_trunc_b {\expandafter\XINT_trunc_B\the\numexpr}% \def\XINT_trunc_sp_b {\expandafter\XINT_trunc_sp_B\the\numexpr}% -% \end{macrocode} -% \lverb|& -% | -% \begin{macrocode} \def\XINT_trunc_B #1% {% \xint_UDsignfork @@ -28879,10 +29175,6 @@ math shift catcode. -\XINT_trunc_D \krof #1% }% -% \end{macrocode} -% \lverb|& -% | -% \begin{macrocode} \def\XINT_trunc_sp_B #1% {% \xint_UDsignfork @@ -28890,10 +29182,6 @@ math shift catcode. -\XINT_trunc_sp_D \krof #1% }% -% \end{macrocode} -% \lverb@& -% @ -% \begin{macrocode} \def\XINT_trunc_C -#1.#2#3% {% \expandafter\XINT_trunc_CE @@ -28915,10 +29203,6 @@ math shift catcode. \def\XINT_trunc_sp_Cb #1#2.#3.% {% \expandafter\XINT_trunc_sp_Cc -% \end{macrocode} -% \lverb|& -% | -% \begin{macrocode} \romannumeral0\expandafter\XINT_split_fromright_a \the\numexpr#3-\numexpr\XINT_length_loop #2\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint: @@ -28926,10 +29210,6 @@ math shift catcode. \xint_c_iv\xint_c_iii\xint_c_ii\xint_c_i\xint_c_\xint_bye .#2\xint_bye2345678\xint_bye..#1% }% -% \end{macrocode} -% \lverb|& -% | -% \begin{macrocode} \def\XINT_trunc_sp_Cc #1% {% \if.#1\xint_dothis{\XINT_trunc_sp_Cd 0.}\fi @@ -28967,29 +29247,32 @@ math shift catcode. {\expandafter#4\romannumeral`&&@\expandafter\xint_firstoftwo \romannumeral0\XINT_div_prepare {#3}{#2}.#1}% \def\XINT_trunc_sp_F #1#2.#3{#3#2.#1}% -\def\XINT_itrunc_G #1#2.#3#4.{\if#10\xint_dothis{ 0}\fi\xint_orthat{#3#1}#2}% -\def\XINT_trunc_G #1.#2#3.% +\def\XINT_itrunc_G #1#2.#3#4.% +{% + \if#10\xint_dothis{ 0}\fi + \xint_orthat{#3#1}#2% +}% +\def\XINT_trunc_G #1.#2#3#4.% {% + \xint_gob_til_minus#3\XINT_trunc_Hc-% \expandafter\XINT_trunc_H - \the\numexpr\romannumeral0\xintlength {#1}-#3.#3.{#1}#2% + \the\numexpr\romannumeral0\xintlength {#1}-#3#4.#3#4.{#1}#2% }% +\def\XINT_trunc_Hc-\expandafter\XINT_trunc_H + \the\numexpr\romannumeral0\xintlength #1.-#2.#3#4{#4#3e#2}% \def\XINT_trunc_H #1.#2.% {% - \ifnum #1 > \xint_c_ - \xint_afterfi {\XINT_trunc_Ha {#2}}% - \else - \xint_afterfi {\XINT_trunc_Hb {-#1}}% -0,--1,--2, .... - \fi + \ifnum #1 > \xint_c_ \xint_dothis{\XINT_trunc_Ha {#2}}\fi + \xint_orthat {\XINT_trunc_Hb {-#1}}% -0,--1,--2, .... +}% +\def\XINT_trunc_Ha% +{% + \expandafter\XINT_trunc_Haa\romannumeral0\xintdecsplit }% -\def\XINT_trunc_Ha{\expandafter\XINT_trunc_Haa\romannumeral0\xintdecsplit}% \def\XINT_trunc_Haa #1#2#3{#3#1.#2}% \def\XINT_trunc_Hb #1#2#3% {% \expandafter #3\expandafter0\expandafter.% -% \end{macrocode} -% \lverb|& -% | -% \begin{macrocode} \romannumeral\xintreplicate{#1}0#2% }% % \end{macrocode} @@ -29012,7 +29295,9 @@ math shift catcode. % input is already a decimal number (denominator B=1). % % And the rounding is now done in 1.2 style (with much delay, sorry), like of -% the rewritten \xintInc and \xintDec.| +% the rewritten \xintInc and \xintDec. +% +% At 1.4a, first argument can be negative. This is handled at \XINT_trunc_G.| % \begin{macrocode} \def\xintRound {\romannumeral0\xintround }% \def\xintiRound {\romannumeral0\xintiround }% @@ -32846,7 +33131,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintseries}% - [2020/01/31 v1.4 Expandable partial sums with xint package (JFB)]% + [2020/02/19 v1.4a Expandable partial sums with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintSeries}} % \begin{macrocode} @@ -33347,7 +33632,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcfrac}% - [2020/01/31 v1.4 Expandable continued fractions with xint package (JFB)]% + [2020/02/19 v1.4a Expandable continued fractions with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintCFrac}} % \begin{macrocode} @@ -34489,29 +34774,33 @@ math shift catcode. % it became possible to let the [...] syntax be associated to a true internal type of «tuple» % or «list». % -% The output of \xintexpr after expansion is thus modified at 1.4. It now looks like +% The output of \xintexpr (after \romannumeral0 or \romannumeral-`0 triggered +% expansion or double expansion) is thus modified at 1.4. It now looks like % this: % % \XINTfstop \XINTexprprint .{{}} in simplest case % % \XINTfstop \XINTexprprint .{{...}...{...}} in general case % -% where ... stands for nested braces ultimately ending in {} leaves. -% The is some internal representation, possibly empty. -% Both on input and output from \xintthexpr an empty leaf is rendered as []. -% The $xintfracnameimp numerical macros convert this to 0, but the integer -% only parser \xintiiexpr will currently not do this and will break -% if some arithmetic operation is attempted. +% where ... stands for nested braces ultimately ending in {} leaves. +% The stands for some internal representation of numeric data. It +% may be empty, and currently as well as probably in future uses only catcode +% 12 tokens (no spaces currently). +% +% {{}} corresponds (in input as in output) to []. The external TeX braces also +% serve as set-theoretical braces. The comma is concatenation, so for example +% [], [] will become {{}{}}, or rather {}{} if sub-unit of something else. % -% Only normal catcodes are output, i.e. the backslash, regular braces, and the -% catcode 12 characters which are used for the internal number representations -% (scientific notation is internally converted to raw -% $xintfracnameimp representation [N]). +% The associated vocabulary is explained in the user manual and we avoid +% too much duplication here. $xintfracnameimp numerical macros receiving an +% empty argument usually handle it as being 0, but this is not the case of the +% $xintcorenameimp macros supporting \xintiiexpr, they usually break if +% exercised on some empty argument. % -% See the user manual for changes the novel internal representation implies at -% interface level, in particular regarding the way the commas are interpreted. -% The user manual explains some terminology («ople», «oneple», «nutple»,...) whose -% meaning I don't repeat here. +% The above expansion result uses thus only normal catcodes are output, i.e. +% the backslash, regular braces, and catcode 12 characters (scientific +% notation is internally converted to raw $xintfracnameimp representation +% [N]). % % Additional data may be located before the dot; this is the case only for % \xintfloatexpr currently. As @@ -34519,18 +34808,16 @@ math shift catcode. % \xintfloatexpr but tries to share as much code as possible, some overhead % is induced to fit all into the same mold. % -% \XINTfstop stops \romannumeral-`0 type spanned expansion, and is invariant -% under \edef, but simply disappears in typesetting context. It is thus now -% legal to use \xintexpr directly in typesetting flow. See user manual for -% some further comments. +% \XINTfstop stops \romannumeral-`0 (or 0) type spanned expansion, and is +% invariant under \edef, but simply disappears in typesetting context. It is +% thus now legal to use \xintexpr directly in typesetting flow. % % \XINTexprprint is \protected. % -% The f-expansion (\romannumeral-`0 type of expansion) of an \xintexpr -% \relax is a complete expansion, i.e. whose result remains -% invariant under \edef. But if exposed to finitely many expansion steps (at -% least two) there is a «blinking» \noexpand upfront depending on parity of -% number of steps. +% The f-expansion of an \xintexpr \relax is a complete expansion, +% i.e. one whose result remains invariant under \edef. But if exposed to +% finitely many expansion steps (at least two) there is a «blinking» \noexpand +% upfront depending on parity of number of steps. % % \xintthe\xintexpr \relax or \xinteval{} serve as % formerly to deliver the explicit digits, or more exactly some prettifying @@ -34736,7 +35023,7 @@ math shift catcode. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintexpr}% - [2020/01/31 v1.4 Expandable expression parser (JFB)]% + [2020/02/19 v1.4a Expandable expression parser (JFB)]% \catcode`! 11 \let\XINT_Cmp \xintiiCmp \def\XINTfstop{\noexpand\XINTfstop}% @@ -34789,22 +35076,27 @@ math shift catcode. \catcode`{ 1 \catcode`} 2 \catcode`< 12 \catcode`> 12 % \end{macrocode} % \subsubsection{Braced contents rendering via a \TeX{} alignment with prettifying of leaves} -% \lverb|1.4.| +% \lverb|1.4. +% +% Breaking change at 1.4a as helper macros were renamed and their meanings +% refactored: no more \xintexpraligntab nor \xintexpraligninnercomma or +% \xintexpralignoutercomma but \xintexpraligninnersep, etc... +% .| % \begin{macrocode} \catcode`& 4 \protected\def\xintexpralignbegin {\halign\bgroup\tabskip2ex\hfil##&&##\hfil\cr}% \protected\def\xintexpralignend {\crcr\egroup}% -\protected\def\xintexpraligncr {\cr}% +\protected\def\xintexpralignlinesep {,\cr}% \protected\def\xintexpralignleftbracket {[}% \protected\def\xintexpralignrightbracket{]}% -\protected\def\xintexpraligninnercomma {,}% -\protected\def\xintexpralignoutercomma {,}% -\protected\def\xintexpraligntab {&}% +\protected\def\xintexpralignleftsep {&}% +\protected\def\xintexpralignrightsep {&}% +\protected\def\xintexpraligninnersep {,&}% \catcode`& 7 \def\XINT:expr:toalignwith#1#2% {% {\expandafter\XINT:expr:toalign_checkempty - \expanded{\noexpand#1!\expandafter}\detokenize{#2}^}% + \expanded{\noexpand#1!\expandafter}\detokenize{#2}^\expandafter}% \xintexpralignend }% \def\XINT:expr:toalign_checkempty #1!#2% @@ -34816,23 +35108,27 @@ math shift catcode. \def\XINT:expr:toalign_a #1{#2% <% \if{#2\xint_dothis<\xintexpralignleftbracket\XINT:expr:toalign_a>\fi - \xint_orthat\XINT:expr:toalign_b #1#2% + \xint_orthat<\xintexpralignleftsep\XINT:expr:toalign_b>#1#2% >% \def\XINT:expr:toalign_b #1!#2}% <% - \xintexpraligntab \if\relax#2\relax\xintexprEmptyItem\else#1<#2>\fi\XINT:expr:toalign_c #1!}% >% \def\XINT:expr:toalign_c #1}#2% <% \if ^#2\xint_dothis<\xint_gob_til_^>\fi - \if {#2\xint_dothis<\xintexpraligninnercomma\XINT:expr:toalign_a>\fi - \xint_orthat<\xintexpraligntab\xintexpralignrightbracket\XINT:expr:toalign_C>#1#2% + \if {#2\xint_dothis<\xintexpraligninnersep\XINT:expr:toalign_A>\fi + \xint_orthat<\xintexpralignrightsep\xintexpralignrightbracket\XINT:expr:toalign_C>#1#2% +>% +\def\XINT:expr:toalign_A #1{#2% +<% + \if{#2\xint_dothis<\xintexpralignleftbracket\XINT:expr:toalign_A>\fi + \xint_orthat\XINT:expr:toalign_b #1#2% >% \def\XINT:expr:toalign_C #1}#2% <% \if ^#2\xint_dothis<\xint_gob_til_^>\fi - \if {#2\xint_dothis<\xintexpralignoutercomma\xintexpraligncr\XINT:expr:toalign_a>\fi + \if {#2\xint_dothis<\xintexpralignlinesep\XINT:expr:toalign_a>\fi \xint_orthat<\xintexpralignrightbracket\XINT:expr:toalign_C>#1#2% >% \catcode`{ 1 \catcode`} 2 \catcode`< 12 \catcode`> 12 @@ -34903,6 +35199,9 @@ math shift catcode. % ATTENTION! 1.3d renamed \xinteval to \xintexpro etc... % % +% +% The 1.4a version of optional argument [D] for \xintiexpr accepts a negative +% D, with same meaning as \xintTrunc from xintfrac.sty. % | % \begin{macrocode} \def\xintexpr {\romannumeral0\xintexpro }% @@ -35042,7 +35341,7 @@ math shift catcode. % required some work...| % \begin{macrocode} \def\xintthe #1{\expanded\expandafter\xint_gobble_i\romannumeral`&&@#1}% -\def\xintthealign #1{\xintexpralignbegin +\def\xintthealign #1{\expandafter\xintexpralignbegin \expanded\expandafter\XINT:expr:toalignwith \romannumeral0\expandafter\expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\xint_gob_andstop_ii @@ -35186,6 +35485,20 @@ math shift catcode. {\xint_gob_til_! #3\XINT_thecoords_c ! (#1#2, #3#4)\XINT_thecoords_b }% \def\XINT_thecoords_c #1^{}% % \end{macrocode} +% \paragraph{\csh{xintthespaceseparated}} +% \lverb|1.4a This is a utility macro which was distributed previously +% separately for usage with PSTricks \listplot| +% \begin{macrocode} +\def\xintthespaceseparated#1% + {\romannumeral`&&@\expandafter\xintthespaceseparated_a\romannumeral0#1}% +\def\xintthespaceseparated_a #1#2.#3% + {\expanded{\expandafter\xintthespaceseparated_b\expanded#2.{#3},!,!,!,!,!,!,!,!,!,^}}% +\def\xintthespaceseparated_b #1,#2,#3,#4,#5,#6,#7,#8,#9,% + {\xint_gob_til_! #9\xintthespaceseparated_c !% + #1#2#3#4#5#6#7#8#9% + \xintthespaceseparated_b}% +\def\xintthespaceseparated_c !#1!#2^{#1}% +% \end{macrocode} % \subsection{Hooks into the numeric parser for usage by the % \cshnolabel{xintdeffunc} symbolic parser} % \lverb|This is new with 1.3 and considerably refactored at 1.4. See @@ -38127,18 +38440,48 @@ math shift catcode. % \begin{macrocode} \def\XINT_expr_onliteral_add {\expandafter\XINT_allexpr_add_f\romannumeral`&&@\XINT_expr_fetch_E_comma_V_equal_E_a {}}% -\def\XINT_allexpr_add_f #1#2{\xint_c_ii^v `{opx}#2)\relax #1{+@}{0}}% +\def\XINT_allexpr_add_f #1#2{\xint_c_ii^v `{opx}#2)\relax #1{+}{0}}% \def\XINT_expr_onliteral_mul {\expandafter\XINT_allexpr_mul_f\romannumeral`&&@\XINT_expr_fetch_E_comma_V_equal_E_a {}}% -\def\XINT_allexpr_mul_f #1#2{\xint_c_ii^v `{opx}#2)\relax #1{*@}{1}}% +\def\XINT_allexpr_mul_f #1#2{\xint_c_ii^v `{opx}#2)\relax #1{*}{1}}% \def\XINT_expr_func_opx {\XINT:NEhook:opx \XINT_allexpr_opx \xintbareeval }% \def\XINT_flexpr_func_opx {\XINT:NEhook:opx \XINT_allexpr_opx \xintbarefloateval}% \def\XINT_iiexpr_func_opx {\XINT:NEhook:opx \XINT_allexpr_opx \xintbareiieval }% +% \end{macrocode} +% \lverb|1.4a In case of usage of omit (did I not test it? obviously +% I didn't as neither omit nor abort could work; and break neither), +% 1.4 code using (#6) syntax caused a +% (somewhat misleading) «missing )» error message which originated in the +% #6. This is non-obvious problem (perhaps explained why prior to 1.4 I had +% not added support for omit and break() to add() and mul()... +% +% Allowing () is not enough as it would have to be 0 or 1 depending on +% whether we are using add() or mul(). Hence the somewhat complicated +% detour (relying on precise way var_omit and var_abort work) via +% \XINT_allexpr_opx_ifnotomitted. +% +% \break() has special meaning here as it is used as last operand, not as last +% value. The code is very unsatisfactory and inefficient but this is hotfix +% for 1.4a.| +% \begin{macrocode} \def\XINT_allexpr_opx #1#2#3#4#5#6#7#8% {% \expandafter\XINT_expr_put_op_first \expanded \bgroup {\iffalse}\fi - \XINT_expr_iter:_b {#1(#6)#7\relax !#5}#4^~{{#8}}\XINT_expr_cb_and_getop + \XINT_expr_iter:_b {#1% + \expandafter\XINT_allexpr_opx_ifnotomitted + \romannumeral0#1#6\relax#7@\relax !#5}#4^~{{#8}}\XINT_expr_cb_and_getop +}% +\def\XINT_allexpr_opx_ifnotomitted #1% +{% + \ifx !#1\xint_dothis{@\relax}\fi + \ifx ^#1\xint_dothis{\XINTfstop. ^\relax}\fi + \if ?\xintFirstItem{#1}\xint_dothis{\XINT_allexpr_opx_break{#1}}\fi + \xint_orthat{\XINTfstop.{#1}}% +}% +\def\XINT_allexpr_opx_break #1#2\relax +{% + break(\expandafter\XINTfstop\expandafter.\expandafter{\xint_gobble_i#1}#2)\relax }% % \end{macrocode} % \subsubsection{\cshn{rseq()}} @@ -39773,12 +40116,12 @@ math shift catcode. \xint_dothis\XINT:NE:f:one:and:opt_a\fi \xint_orthat\XINT:NE:f:tacitzeroifone_b ##1&&A% }}\expandafter\XINT:NE:f:tacitzeroifone:direct\string#% -\def\XINT:NE:f:tacitzeroifone:direct\XINT:expr:f:tacizeroifone #1#2#3&&A#4#5% +\def\XINT:NE:f:tacitzeroifone_b\XINT:expr:f:tacitzeroifone #1#2#3&&A#4#5% {% \if\relax#3\relax\expandafter\xint_firstoftwo\else \expandafter\xint_secondoftwo\fi - {\XINT:NE:f:one:from:two#4{0}}% - {\expandafter\XINT:NE:f:one:from:two\expandafter#5% + {\XINT:NE:f:one:from:two:direct#4{0}}% + {\expandafter\XINT:NE:f:one:from:two:direct\expandafter#5% \expanded{{\XINT:NE:f:one:from:one:direct\xintNum{#2}}}}% {#1}% }% @@ -39794,12 +40137,12 @@ math shift catcode. {% \detokenize{\romannumeral`-0\expandafter#1\expanded{#2}$XINT_expr_exclam#3}%$ }% -\def\XINT:NE:f:iitacitzeroifone:direct\XINT:expr:f:iitacizeroifone #1#2#3&&A#4% +\def\XINT:NE:f:iitacitzeroifone_b\XINT:expr:f:iitacitzeroifone #1#2#3&&A#4% {% \if\relax#3\relax\expandafter\xint_firstoftwo\else \expandafter\xint_secondoftwo\fi - {\XINT:NE:f:one:from:two#4{0}}% - {\XINT:NE:f:one:from:two#4{#2}}% + {\XINT:NE:f:one:from:two:direct#4{0}}% + {\XINT:NE:f:one:from:two:direct#4{#2}}% {#1}% }% \def\XINT:NE:x:one:from:two #1#2#3{\XINT:NE:x:one:from:two_fork #2&&A#3&&A#1{#2}{#3}}% @@ -40001,7 +40344,9 @@ math shift catcode. \detokenize {% \expanded\bgroup - \expanded{\unexpanded{\XINT_expr_iter:_b{#1(#6)#7\relax $XINT_expr_exclam #5}}% + \expanded{\unexpanded{\XINT_expr_iter:_b + {#1\expandafter\XINT_allexpr_opx_ifnotomitted + \romannumeral0#1#6\relax#7@\relax $XINT_expr_exclam #5}}% #4$XINT_expr_caret$XINT_expr_tilde{{#8}}}%$ }% }% @@ -40596,10 +40941,10 @@ math shift catcode. \expandafter\xint_secondoftwo \fi {\immediate\write-1{Reloading xinttrig library using Digits=\xinttheDigits.}}% -{\expandafter\gdef\csname xintlibver@trig\endcsname{2020/01/31 v1.4}% +{\expandafter\gdef\csname xintlibver@trig\endcsname{2020/02/19 v1.4a}% \XINT_providespackage \ProvidesPackage{xinttrig}% -[2020/01/31 v1.4 Trigonometrical functions for xintexpr (JFB)]% +[2020/02/19 v1.4a Trigonometrical functions for xintexpr (JFB)]% }% % \end{macrocode} % \subsection{Ensure used letters are dummy letters} @@ -41629,7 +41974,7 @@ math shift catcode. \xintexprSafeCatcodes\catcode`_ 11 \XINT_providespackage \ProvidesPackage{xintlog}% -[2020/01/31 v1.4 Logarithms and exponentials for xintexpr (JFB)]% +[2020/02/19 v1.4a Logarithms and exponentials for xintexpr (JFB)]% % \end{macrocode} % \subsection{Loading of \cshn{poormanlog} package} % \lverb|Attention to catcode regime when loading poormanlog. It matters less @@ -41826,8 +42171,8 @@ xint.sty:205 xintbinhex.sty:53 xintcfrac.sty:183 xintcore.sty:271 -xintexpr.sty:412 -xintfrac.sty:492 +xintexpr.sty:414 +xintfrac.sty:494 xintgcd.sty:41 xintkernel.sty:17 xintlog.sty:9 @@ -41836,15 +42181,15 @@ xinttools.sty:153 xinttrig.sty:31 \fi % grep -o "^{%" xint*sty | wc -l -\def\totala{ 1915} +\def\totala{ 1919} \iffalse % grep -c -e "^}%" xint*sty xint.sty:204 xintbinhex.sty:52 xintcfrac.sty:183 xintcore.sty:268 -xintexpr.sty:400 -xintfrac.sty:495 +xintexpr.sty:402 +xintfrac.sty:497 xintgcd.sty:43 xintkernel.sty:18 xintlog.sty:9 @@ -41853,7 +42198,7 @@ xinttools.sty:152 xinttrig.sty:32 \fi % grep -o "^}%" xint*sty | wc -l -\def\totalb{ 1904} +\def\totalb{ 1908} \cleardoublepage \section{Cumulative line count} @@ -41877,7 +42222,8 @@ xinttrig.sty:32 \TeX\strut. Version {\xintbndlversion} of {\xintbndldate}.\par } -\CheckSum {34575}% 1.4 +\CheckSum {34648}% 1.4a +% 34575 pour 1.4 % 33497 pour 1.3f, 33274 pour 1.3e, 31601 pour 1.3d, 31122 pour 1.3c % 31069 pour 1.3b, 30482 pour 1.3a, 30621 pour 1.3, 30988 pour 1.2q, % 30982 pour 1.2p, 30524 pour 1.2o, 30303 pour 1.2h, 30403 pour 1.2i, -- cgit v1.2.3