From c9f8bd8bf029f005f02efea2a67dade996df2515 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 24 Nov 2013 00:00:29 +0000 Subject: xint (23nov13) git-svn-id: svn://tug.org/texlive/trunk@32224 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/generic/xint/xint.dtx | 5653 ++++++++++++++---------- Master/texmf-dist/source/generic/xint/xint.ins | 8 +- 2 files changed, 3212 insertions(+), 2449 deletions(-) (limited to 'Master/texmf-dist/source/generic/xint') diff --git a/Master/texmf-dist/source/generic/xint/xint.dtx b/Master/texmf-dist/source/generic/xint/xint.dtx index 2f7cd536ac0..65c15c30343 100644 --- a/Master/texmf-dist/source/generic/xint/xint.dtx +++ b/Master/texmf-dist/source/generic/xint/xint.dtx @@ -1,13 +1,14 @@ % -*- coding: iso-latin-1; -*- %<*doc> -\def\lasttimestamp{Time-stamp <04-11-2013 13:50:22 CET *>} +\def\lasttimestamp{Time-stamp <23-11-2013 12:26:51 CET *>} % -% xint.dtx, 1.09f (2013/11/04) +% xint.dtx, 1.09g (2013/11/22) % % Copyright (C) 2013 by Jean-François Burnol % % Style files which will self-extract from xint.dtx: -% (base) xint.sty Expandable operations on long numbers +% xinttools.sty Expandable and non expandable utilities +% xint.sty Expandable operations on long numbers % xintfrac.sty Expandable operations on fractions % xintexpr.sty Expandable expression parser % xintbinhex.sty Expandable binary and hexadecimal conversions @@ -20,9 +21,9 @@ % ======= % % This work consists of the source file xint.dtx and of its derived files: -% xint.sty, xintfrac.sty, xintexpr.sty, xintbinhex.sty, xintgcd.sty, -% xintseries.sty, xintcfrac.sty, as well as xint.ins and the documentation -% xint.pdf (or xint.dvi). +% xinttools.sty xint.sty, xintfrac.sty, xintexpr.sty, xintbinhex.sty, +% xintgcd.sty, xintseries.sty, xintcfrac.sty, as well as xint.ins and the +% documentation xint.pdf (or xint.dvi). % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either @@ -54,10 +55,11 @@ % % To get xint.pdf run pdflatex thrice on xint.dtx % +% xinttools.sty | % xint.sty | % xintfrac.sty | -% xintexpr.sty | -% xintbinhex.sty | --> TDS:tex/generic/xint/ +% xintexpr.sty | --> TDS:tex/generic/xint/ +% xintbinhex.sty | % xintgcd.sty | % xintseries.sty | % xintcfrac.sty | @@ -67,7 +69,8 @@ % It may be necessary to then refresh the TeX installation filename % database. % -% Usage with LaTeX: \usepackage{xint} +% Usage with LaTeX: \usepackage{xinttools} +% \usepackage{xint} % (loads xinttools) % \usepackage{xintfrac} % (loads xint) % \usepackage{xintexpr} % (loads xintfrac) % @@ -76,7 +79,8 @@ % \usepackage{xintseries} % (loads xintfrac) % \usepackage{xintcfrac} % (loads xintfrac) % -% Usage with TeX: \input xint.sty\relax +% Usage with TeX: \input xinttools.sty\relax +% \input xint.sty\relax % (loads xinttools) % \input xintfrac.sty\relax % (loads xint) % \input xintexpr.sty\relax % (loads xintfrac) % @@ -87,7 +91,8 @@ % %% %%---------------------------------------------------------------- -%% The xint bundle (version 1.09f of November 4, 2013) +%% The xint bundle (version 1.09g of November 22, 2013) +%%% xinttools: Expandable and non-expandable utilities %%% xint: Expandable operations on long numbers %%% xintfrac: Expandable operations on fractions %%% xintexpr: Expandable expression parser @@ -99,8 +104,8 @@ %%---------------------------------------------------------------- %% %<*doc> -\def\pkgversion{1.09f} -\def\pkgdate{2013/11/04} +\def\pkgversion{1.09g} +\def\pkgdate{2013/11/22} \def\striptimestamp #1 <#2 #3 #4 #5>{#2 at #3 #4} \def\getdocdate #1 <#2-#3-#4 #5>{#4/#3/#2} \edef\docdate{\expandafter\getdocdate\lasttimestamp} @@ -111,6 +116,7 @@ \generate{\nopreamble \file{xint.ins}{\from{xint.dtx}{ins}} \usepreamble\defaultpreamble +\file{xinttools.sty}{\from{xint.dtx}{xinttools}} \file{xint.sty}{\from{xint.dtx}{xint}} \file{xintbinhex.sty}{\from{xint.dtx}{xintbinhex}} \file{xintgcd.sty}{\from{xint.dtx}{xintgcd}} @@ -125,8 +131,9 @@ %----------- to .ins file ---------------------------------------- %% %% This is a generated file. Run tex or latex on this file to -%% extract xint.sty, xintfrac.sty, xintexpr.sty, xintbinhex.sty, -%% xintgcd.sty, xintseries.sty and xintcfrac.sty from xint.dtx +%% extract xinttools.sty, xint.sty, xintfrac.sty, xintexpr.sty, +%% xintbinhex.sty, xintgcd.sty, xintseries.sty and xintcfrac.sty +%% from xint.dtx %% %% See xint.dtx for the copyright and the conditions for %% distribution and/or modification of this work. @@ -134,6 +141,7 @@ \input docstrip.tex \askforoverwritefalse \generate{\usepreamble\defaultpreamble +\file{xinttools.sty}{\from{xint.dtx}{xinttools}} \file{xint.sty}{\from{xint.dtx}{xint}} \file{xintbinhex.sty}{\from{xint.dtx}{xintbinhex}} \file{xintgcd.sty}{\from{xint.dtx}{xintgcd}} @@ -185,11 +193,12 @@ \def\sectioncouleur{{cyan}} -% attention à ce 22 hard codé. 23 maintenant,... +% attention à ce 22 hard codé. 23 maintenant,... 24; et 31 non 32... \etocsetstyle{section}{} {} - {\ifnum\etocthenumber=23 \gdef\sectioncouleur{{joli}}\fi + {\ifnum\etocthenumber=24 \gdef\sectioncouleur{{joli}}\fi + \ifnum\etocthenumber=32 \gdef\sectioncouleur{[named]{RoyalPurple}}\fi \savedsectionline{\numberline{\expandafter\textcolor\sectioncouleur {\etocnumber}}\etocname} {{\mdseries\etocpage}}% @@ -490,12 +499,22 @@ pdfpagemode=UseOutlines} \newcommand\csbh[1]{\texorpdfstring{\csbnolk{#1}}{\textbackslash #1}} % emploi de \xintFor à partir de 1.09c -\xintFor #1 in {xint,xintbinhex,xintgcd,xintfrac,xintseries,xintcfrac,xintexpr} +\xintForpair #1#2 in +{(xinttools,tools),(xint,xint),(xintbinhex,binhex),(xintgcd,gcd),% + (xintfrac,frac),(xintseries,series),(xintcfrac,cfrac),(xintexpr,expr)} \do {% \expandafter\def\csname #1name\endcsname {\texorpdfstring - {{\color{joli}\ttfamily\hyphenchar\font45 \bfseries #1}} + {\hyperref[sec:#2]% + {\color{joli}\bfseries\ttfamily\hyphenchar\font45 #1}} + {#1}% + \xspace }% + \expandafter\def\csname #1nameimp\endcsname + {\texorpdfstring + {\hyperref[sec:#2imp]% + {\color[named]{RoyalPurple}% + \bfseries\ttfamily\hyphenchar\font45 #1}} {#1}% \xspace }% }% @@ -557,32 +576,57 @@ pdfpagemode=UseOutlines} {\centering \textsc{Jean-François Burnol}\par \footnotesize \ttfamily - jfbu (at) free (dot) fr\\ - Package version: \pkgversion\ (\pkgdate)\\ - Documentation generated from the source file\\ - with timestamp ``\dtxtimestamp''\par + jfbu (at) free (dot) fr\par + Package version: \pkgversion\ (\pkgdate)% + \let\thefootnote\empty + \footnote{Documentation generated from the + source file with timestamp ``\dtxtimestamp''.}\par } +\setcounter{footnote}{0} + +\bigskip +\begin{addmargin}{1cm}\footnotesize +\makeatletter +\renewenvironment{description} + {\list{}{\topsep\z@ \parsep\z@ \labelwidth\z@ \itemindent-\leftmargin + \let\makelabel\descriptionlabel}} + {\endlist} +\makeatother +\begin{description} +\item[\xinttoolsname] is loaded by \xintname (hence by all other packages of the + bundle, too): it provides utilities of independent interest such as expandable + and non-expandable loops. + +\item[\xintname] implements with expandable \TeX{} macros additions, + subtractions, multiplications, divisions and powers with arbitrarily long + numbers. + +\item[\xintfracname] extends the scope of \xintname to decimal numbers, to + numbers in scientific notation and also to fractions with arbitrarily + long such numerators and denominators separated by a forward slash. + +\item[\xintexprname] extends \xintfracname with an expandable parser |\xintexpr + . . . \relax| of expressions involving arithmetic operations in infix notation + on decimal numbers, fractions, numbers in scientific notation, with + parentheses, factorial symbol, function names, comparison operators, logic + operators, twofold and threefold way conditionals, sub-expressions, macros + expanding to the previous items. +\end{description} + +\noindent Further modules: +% +\begin{description} +\item[\xintbinhexname] is for conversions to and from binary and + hexadecimal bases. -\begin{abstract} -The \xintname package implements with expandable \TeX{} macros the basic - arithmetic operations of addition, subtraction, multiplication and division, - applied to arbitrarily long numbers. The \xintfracname package extends the - scope of \xintname to fractional numbers with arbitrarily long numerators and - denominators. - - \xintexprname provides an expandable parser |\xintexpr . . . \relax| - of expressions involving arithmetic operations in infix notation on - decimal numbers, fractions, numbers in scientific notation, with - parentheses, factorial symbol, function names, comparison operators, - logic operators, twofold and threefold way conditionals, - sub-expressions, macros expanding to the previous items. - - The \xintbinhexname package is for conversions to and from binary and - hexadecimal bases, \xintseriesname provides some basic functionality for - computing in an expandable manner partial sums of series and power series with - fractional coefficients, \xintgcdname implements the Euclidean algorithm and - its typesetting, and \xintcfracname deals with the computation of continued - fractions. +\item[\xintseriesname] provides some basic functionality for computing in an + expandable manner partial sums of series and power series with fractional + coefficients. + +\item[\xintgcdname] implements the Euclidean algorithm and its typesetting. + +\item[\xintcfracname] deals with the computation of continued fractions. +\end{description} Most macros, and all of those doing computations, work purely by expansion without assignments, and may thus be used almost everywhere in \TeX{}. @@ -590,8 +634,9 @@ The \xintname package implements with expandable \TeX{} macros the basic The packages may be used with any flavor of \TeX{} supporting the \eTeX{} extensions. \LaTeX{} users will use |\usepackage| and others |\input| to load the package components. -\end{abstract} +\end{addmargin} +\bigskip % 18 octobre 2013, je remets la TOC ici. % je ne veux pas non plus que la main toc se liste elle-même donc je passe pour @@ -599,6 +644,9 @@ The \xintname package implements with expandable \TeX{} macros the basic \etocsetlevel{toctobookmark}{6} % 9 octobre 2013, je fais des petits tricks. +% 18 novembre 2013, je n'inclus plus la TOC détaillée de +% xintexpr. Je reconfigure la TOC + \etocsettocdepth {subsection} \renewcommand*{\etocbelowtocskip}{0pt} @@ -609,41 +657,24 @@ The \xintname package implements with expandable \TeX{} macros the basic \phantomsection\section* {Contents} \etoctoccontentsline*{toctobookmark}{Contents}{1}% } + \etocsettagdepth {description}{section} - \etocsettagdepth {commandsA} {section} - \etocsettagdepth {xintexpr} {none} - \etocsettagdepth {commandsB} {none} - \etocsettagdepth {implementation}{none} -\tableofcontents - \etocsettagdepth {description}{none} \etocsettagdepth {commandsA} {none} - \etocsettagdepth {xintexpr} {subsection} + \etocsettagdepth {xintexpr} {none} \etocsettagdepth {commandsB} {none} \etocsettagdepth {implementation}{none} -\etocsettocstyle {}{} \tableofcontents +\etocmulticolstyle [2]{\raggedcolumns}{} \etocsettagdepth {description}{none} - \etocsettagdepth {commandsA} {none} - \etocsettagdepth {xintexpr} {none} + \etocsettagdepth {commandsA} {section} + \etocsettagdepth {xintexpr} {section} \etocsettagdepth {commandsB} {section} - \etocsettagdepth {implementation}{none} -\etocmulticolstyle [2]{}{} -\tableofcontents - \etocsettagdepth {description}{none} - \etocsettagdepth {commandsA} {none} - \etocsettagdepth {xintexpr} {none} - \etocsettagdepth {commandsB} {none} \etocsettagdepth {implementation}{section} - \etocsettocstyle {}{} -\def\sectioncouleur{[named]{RoyalPurple}} -\begin{addmargin}{3cm} - \tableofcontents -\end{addmargin} +\tableofcontents \medskip % pour la suite: \etocignoredepthtags - \etocmulticolstyle [1]{% \phantomsection\section* {Contents} \etoctoccontentsline*{toctobookmark}{Contents}{2}% @@ -654,23 +685,34 @@ The \xintname package implements with expandable \TeX{} macros the basic \section{Quick introduction}\label{sec:quickintro} -The \xintname bundle consists of three principal components \xintname, +The \xintname bundle consists of the three principal components \xintname, \xintfracname (which loads \xintname), and \xintexprname (which loads -\xintfracname), and four additional modules. They may be used with Plain \TeX{}, -\LaTeX{} or any other format based on \TeX{}. The package requires the -\eTeX{} extensions which in modern distributions are made available by default, -except if you invoke \TeX{} under the name |tex| in command line. +\xintfracname), and four additional modules. Release |1.09g| has moved the +macros of \xintname not dealing with the manipulation of big numbers to a +separate package \xinttoolsname (which is automatically loaded by \xintname), of +independent interest. + +All components may be used as regular packages with \LaTeX{} or loaded directly +via \string\input{} (e.g. |\input xint.sty\relax|) in any other format based on +\TeX. Each of them automatically loads those not alreadly loaded it depends +on. + +The \eTeX{} extensions must be enabled; this is the case in modern distributions +by default, except if you invoke \TeX{} under the name |tex| in command line +(|etex| should be used then, or |pdftex| in |DVI| output mode). The goal is too compute \emph{exactly}, purely by expansion, without count registers nor assignments nor definitions, with arbitrarily big -numbers and fractions. As will be commented upon more later, this works -fine when the data has dozens of digits, but multiplying out two @1000@ -digits numbers under this constraint of expandability is expensive; so -in many situations the package will be used for fixed point (rounding or -truncating each intermediate result) or floating point computations. The -``floating point'' macros work with a given arbitrary precision (default -is @16@ digits; from the remark made above, beyond @100@ digits things -will start becoming too slow if hundreds of computations are needed). The only +numbers and fractions. +% As will be commented upon more later, this works +% fine when the data has dozens of digits, but multiplying out two @1000@ +% digits numbers under this constraint of expandability is expensive; so +% in many situations the package will be used for fixed point (rounding or +% truncating each intermediate result) or floating point computations. The +% ``floating point'' macros work with a given arbitrary precision (default +% is @16@ digits; from the remark made above, beyond @100@ digits things +% will start becoming too slow if hundreds of computations are needed). +The only non-algebraic operation which is currently implemented is the extraction of square roots. @@ -678,12 +720,12 @@ The package macros expand their arguments\footnote{see in \autoref{sec:expansions} the related explanations.}; as they are themselves completely expandable, this means that one may nest them arbitrarily deep to construct complicated (and still completely expandable) formulas. - But one will presumably prefer to use the (expandable!) \csbxint{expr}| ... \relax| parser as it allows infix notations, function names (corresponding to some of the package macros), comparison operators, boolean operators, 2way and 3way conditionals. +\footnotesize 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 of the time made use of these macros (not provided by the package:) @@ -693,8 +735,7 @@ When producing very long numbers there is the question of printing them on \def\allowsplits #1% {\ifx #1\relax \else #1\hskip 0pt plus 1pt\relax\expandafter\allowsplits\fi}% \def\printnumber #1{\expandafter\expandafter\expandafter\allowsplits #1\relax }% -%% expands twice before printing (all macros from the xint bundle expand in two steps -%% to their final output).|\par\endgroup +%% (all macros from the xint bundle expand in two steps to their final output).|\par\endgroup An alternative (\autoref{fn:np}) is to suitably configure the thousand separator with the \href{http://ctan.org/pkg/numprint}{numprint} package (does not work in math mode; I also tried \href{http://ctan.org/pkg/siunitx}{siunitx} but even in @@ -705,23 +746,35 @@ package\footnote{\url{http://ctan.org/pkg/seqsplit}} which can be used to achieve this splitting accross lines, and does work in inline math mode. -The package \xintname also provides utilities (\autoref{sec:utilsxint}), some -completely expandable, others not, of independent interest. Their use is +\normalsize +The utilities provided by \xinttoolsname (\autoref{sec:tools}), some +completely expandable, others not, are of independent interest. Their use is illustrated through various examples: among those, it is shown in \autoref{ssec:quicksort} how to implement in a completely expandable way the quick sort algorithm and also how to illustrate it graphically. Other examples -include some dynamically constructed alignments with cells giving the prime -numbers (\autoref{ssec:primesI}, \autoref{ssec:primesII}). +include some dynamically constructed alignments with automatically computed +prime number cells (\autoref{ssec:primesI}, \autoref{ssec:primesII}). -Some other traditional computational examples are \hyperref[ssec:Machin]{the - computations of $\pi$ and $\log 2$} and the computation of the -\hyperlink{e-convergents}{convergents of $e$} with the help of the +Some other computational examples are \hyperref[ssec:Machin]{the + computations of $\pi$ and $\log 2$} using \xintname and the computation of the +\hyperlink{e-convergents}{convergents of $e$} with the further help of the \xintcfracname package. \section{Recent changes} \footnotesize + +\noindent Release |1.09g| (|[2013/11/22]|): +\begin{itemize} +\item package \xinttoolsname is detached from \xintname, to make tools such as + \csbxint{For}, \csbxint{ApplyUnbraced}, and \csbxint{iloop} available without + the \xintname overhead. +\item new expandable nestable loops \csbxint{loop} and \csbxint{iloop}. +\item bugfix: \csbxint{For} and \csbxint{For*} do not modify anymore the value + of |\count 255|. +\end{itemize} + \noindent Release |1.09f| (|[2013/11/04]|): \begin{itemize} \item new \csbxint{ZapFirstSpaces}, \csbxint{ZapLastSpaces}, @@ -748,6 +801,8 @@ Some other traditional computational examples are \hyperref[ssec:Machin]{the % changing outputs) to some inner macros. \end{itemize} +\clearpage + \noindent Release |1.09e| (|[2013/10/29]|): \begin{itemize} \item new \csbxint{integers}, \csbxint{dimensions}, \csbxint{rationals} for @@ -880,7 +935,7 @@ version \fexpan ds the un-braced list items. After \item Extraction of square roots, for floating point numbers (\csbxint{FloatSqrt}), and also in a version adapted to integers (\csbxint{iSqrt}). -\item New package \xintbinhexname providing \hyperref[sec:combinhex]{conversion +\item New package \xintbinhexname providing \hyperref[sec:binhex]{conversion routines} to and from binary and hexadecimal bases. \end{itemize} @@ -910,7 +965,7 @@ will replace pointwise |D|; this argument may exceed the |32767| bound. \item To write the |\xintexpr| parser I benefited from the commented source of the \LaTeX3 parser; the |\xintexpr| parser has its own features and peculiarities. -See \hyperref[sec:comexpr]{its documentation}. +See \hyperref[sec:expr]{its documentation}. \end{itemize} % The |\xintexpr..\relax| and |\xintfloatexpr..\relax| are usable as @@ -1084,7 +1139,7 @@ with @8@ digits after the decimal mark, and printed. with the inherent difficulty of keeping up with braces and everything... \item if such a formula is used thousands of times in a document (for plots?), this could impact some parts of the \TeX{} program memory (for technical - reasons explained in \autoref{sec:comexpr}). So, a utility \csbxint{NewExpr} + reasons explained in \autoref{sec:expr}). So, a utility \csbxint{NewExpr} is provided to do the work of translating an |\xintexpr|-ession with parameters into a chain of macro evaluations.\footnote{As its makes some macro definitions, it is not an expandable command. It does not need protection @@ -1999,7 +2054,7 @@ where spaces could break havoc. So the best is to avoid them entirely. This is entirely otherwise inside an |\xintexpr|-ession, where spaces are expected to, as a general rule (with possible exceptions related to the allowed use of braces, see the -\hyperref[sec:comexpr]{documentation}) be completely +\hyperref[sec:expr]{documentation}) be completely harmless, and even recommended for making the source more legible. Syntax such as |\xintMul\A\B| is accepted and equivalent\footnote{see however @@ -2329,13 +2384,16 @@ for typesetting: this is just an example of one way to do it. \section{Utilities for expandable manipulations} -The package now has more utilities to deal -expandably with `lists of things', which were treated un-expandably in the -previous section with \csa{xintAssign} and \csa{xintAssignArray}: -\csbxint{ReverseOrder} and \csbxint{Length} since the first -release, \csbxint{Apply} and \csbxint{ListWithSep} since |1.04|, -\csbxint{RevWithBraces}, \csbxint{CSVtoList}, \csbxint{NthElt} since |1.06|, and -\csbxint{ApplyUnbraced}, since |1.06b|. +The package now has more utilities to deal expandably with `lists of things', +which were treated un-expandably in the previous section with \csa{xintAssign} +and \csa{xintAssignArray}: \csbxint{ReverseOrder} and \csbxint{Length} since the +first release, \csbxint{Apply} and \csbxint{ListWithSep} since |1.04|, +\csbxint{RevWithBraces}, \csbxint{CSVtoList}, \csbxint{NthElt} since |1.06|, +\csbxint{ApplyUnbraced}, since |1.06b|, \csbxint{loop} and \csbxint{iloop} since +|1.09g|.\footnote{All these utilities, as well as \csbxint{Assign}, + \csbxint{AssignArray} and the \csbxint{For} loops are now available from the + \xinttoolsname package, independently of the big integers facilities of + \xintname.} \edef\z{\xintiPow {2}{100}} @@ -2370,10 +2428,16 @@ Expandably computing primes is done in \autoref{xintSeq}. \section{A new kind of for loop} -As part of the \hyperref[sec:utilsxint]{utilities} coming with the \xintname +As part of the \hyperref[sec:tools]{utilities} coming with the \xinttoolsname package, there is a new kind of for loop, \csbxint{For}. Check it out (\autoref{xintFor}). +\section{A new kind of expandable loop} + +Also included in \xinttoolsname, \csbxint{iloop} is an expandable loop giving +access to an iteration index, without using count registers. Check it out +(\autoref{xintiloop}). + \section{Exceptions (error messages)} In situations such as division by zero, the package will insert in the @@ -2525,6 +2589,7 @@ Lastly, the macros \csa{xintRelaxArray} (of \xintname) and compatible. \csa{xintTypesetBezoutAlgorithm} also uses the \csa{endgraf} macro. +\enlargethispage{\baselineskip} \section{Installation} @@ -2557,2448 +2622,2973 @@ It may be necessary to then refresh the TeX installation filename database. + -\etocdepthtag.toc {commandsA} - -\section{Commands of the \xintname package}\label{sec:comxint} - -\def\n{\string{N\string}} -\def\m{\string{M\string}} -\def\x{\string{x\string}} - -In the description of the macros \texttt{\n} (or also \texttt{\m}) stands -(except if mentioned otherwise) for a (long) number within braces or for a -control sequence possibly within braces and \hyperref[sec:expansions]{\fexpan - ding} to such a number -(without the braces!), or for material within braces which \fexpan ds to such -a number, as is acceptable on input by the \csbxint{Num} macro: a sequence of -plus and minus signs, followed by some string of zeros, followed by digits. +%\clearpage -The letter \texttt{x} stands for something which will be inserted in-between a -|\numexpr| and a |\relax|. It will thus be completely expanded and must give an -integer obeying the \TeX{} bounds. Thus, it may be for example a count register, -or itself a \csa{numexpr} expression, or just a number written explicitely with -digits or something like |4*\count 255 + 17|, etc... +\etocdepthtag.toc {commandsA} -For the rules regarding direct use of count registers or \csa{numexpr} -expression, in the argument to the package macros, see the -\hyperlink{useofcount}{use of count section} in \autoref{sec:inputs}. +\section{Commands of the \xinttoolsname package} +\label{sec:tools} -Some of these macros are extended by \xintfracname to accept fractions on input, -and, generally, to output a fraction. But this means that additions, -subtractions, multiplications output fractions and not integers; to guarantee -the integer format on output when the inputs are integers, the original -integer-only macros \csa{xintAdd}, \csa{xintSub}, \csa{xintMul} remain available -under the names \csa{xintiAdd}, \csa{xintiSub}, \csa{xintiMul}. Even the -original integer-only macros may now accept fractions on input as long as they -are integers in disguise; they still produce on output integers without any -forward slash mark nor trailing |[n]|. On the other hand macros such as -|\xintAdd| will output fractions |A/B[n]|, with |B| present even if its value is -one. To remove this unit denominator and convert the |[n]| part into explicit -zeros, one has \csbxint{Num} (if one is certain to deal with an integer; see -also \csbxint{PRaw}). This is mandatory when the computation result is fetched -into a context where \TeX{} expects a number (assuming it does not exceed -@2^31@). See the also the \xintfracname \hyperref[sec:comfrac]{documentation} -for more information on how macros of \xintname are modified after loading -\xintfracname (or \xintexprname). +These utilities used to be provided within the \xintname package; since |1.09g| +they have been moved to an independently usable package \xinttoolsname, which +has none of the \xintname facilities regarding big numbers. +The first listed are the completely expandable utilities up to \csbxint{iloop}. -Package \xintname also provides some general macro programming or token -manipulation utilities (expandable as well as non-expandable), which are -described in the next section (\autoref{sec:utilsxint}). +This section contains various concrete examples and ends with a +\hyperref[ssec:quicksort]{completely expandable implementation of the Quick Sort + algorithm} together with a graphical illustration of its action. \localtableofcontents -\subsection{\csbh{xintRev}} \label{xintRev} - -\csa{xintRev\n} will revert the order of the digits of the number, -keeping the optional sign. Leading zeros -resulting from the operation are not removed (see the -\csa{xintNum} macro for this). This macro and all other -macros dealing with numbers first expand `fully' their arguments. -\centeredline{|\xintRev{-123000}|\digitstt{=\xintRev{-123000}}} -\centeredline{|\xintNum{\xintRev{-123000}}|% - \digitstt{=\xintNum{\xintRev{-123000}}}} - +\subsection{\csbh{xintReverseOrder}}\label{xintReverseOrder} -\subsection{\csbh{xintLen}}\label{xintiLen} +\csa{xintReverseOrder}\marg{list} does not do any +expansion of its argument and just reverses the order of the +tokens in the \meta{list}.\footnote{the argument is not a token list variable, + just a + \meta{list} of tokens.} Brace pairs encountered are removed once and the +enclosed +material does not get reverted. Spaces are gobbled. +\centeredline{|\xintReverseOrder{\xintDigitsOf\xintiPow {2}{100}\to\Stuff}|} +\centeredline{gives: + \ttfamily{\string\Stuff\string\to1002\string\xintiPow\string\xintDigitsOf}} -\csa{xintLen\n} returns the length of the number, not counting the sign. -\centeredline{|\xintLen{-12345678901234567890123456789}|\digitstt - {=\xintLen{-12345678901234567890123456789}}} Extended by \xintfracname to -fractions: 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). -\centeredline{|\xintLen{-1e3/5.425}|\digitstt - {=\xintLen{-1e3/5.425}}} -The length is computed on the |A/B[n]| which would have been returned by -\csbxint{Raw}: |\xintRaw {-1e3/5.425}|\digitstt{=\xintRaw {-1e3/5.425}}. +\subsection{\csbh{xintRevWithBraces}}\label{xintRevWithBraces} -Let's point out that the whole thing should sum up to -less than circa @2^{31}@, but this is a bit theoretical. +{\small New in release |1.06|.\par} +\edef\X{\xintRevWithBraces{12345}} +\edef\y{\xintRevWithBraces\X} +\expandafter\def\expandafter\w\expandafter + {\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}} -|\xintLen| is only for numbers or fractions. See \csbxint{Length} for counting -tokens (or rather braced groups), more generally. -\subsection{\csbh{xintDigitsOf}}\label{xintDigitsOf} +\csa{xintRevWithBraces}\marg{list} first does the expansion of its argument +(which thus may be macro), then it reverses the order of the tokens, or braced +material, it encounters, adding a pair of braces to each (thus, maintaining +brace pairs already existing). Spaces (in-between external brace pairs) 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 expansion 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. \centeredline{|\edef\x{\xintRevWithBraces{12345}}|} +\centeredline{|\meaning\x:|\ttfamily{\meaning\X}} +\centeredline{|\edef\y{\xintRevWithBraces\x}|}% +\centeredline{|\meaning\y:|\ttfamily{\meaning\y}} The examples above could be +defined with |\edef|'s because the braced material did not contain macros. +Alternatively: \centeredline{|\expandafter\def\expandafter\w\expandafter|}% +\centeredline{|{\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}}|} +\centeredline{|\meaning\w:|\ttfamily{\meaning\w}} The macro +\csa{xintReverseWithBracesNoExpand} +does the same job without the initial expansion of its argument. -This is a synonym for \csbxint{AssignArray}, 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\xintiPow {7}{500}\to\digits -\centeredline{|\xintDigitsOf\xintiPow {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 +\subsection{\csbh{xintLength}}\label{xintLength} -\subsection{\csbh{xintNum}}\label{xintiNum} +\csa{xintLength}\marg{list} does not do \emph{any} expansion of its argument and just +counts how many tokens there are (possibly none). So to use it to count things +in the replacement text of a macro one should do +|\expandafter\xintLength\expandafter{\x}|. One may also use it inside macros +as |\xintLength{#1}|. Things enclosed in braces +count as one. Blanks between tokens are not counted. See \csbxint{NthElt}|{0}| +for a variant which first \fexpan ds its argument. +\centeredline{|\xintLength {\xintiPow + {2}{100}}|\digitstt{=\xintLength {\xintiPow{2}{100}}}} +\centeredline{${}\neq{}$|\xintLen {\xintiPow {2}{100}}|\digitstt{=\xintLen + {\xintiPow{2}{100}}}} -\csa{xintNum\n} removes chains of plus or minus signs, followed by zeros. -\centeredline{|\xintNum{+---++----+--000000000367941789479}|\digitstt - {=\xintNum{+---++----+--000000000367941789479}}} Extended by \xintfracname to -accept also a fraction on input, as long as it reduces to an integer after -division of the numerator by the denominator. -\centeredline{|\xintNum{123.48/-0.03}|\digitstt{=\xintNum{123.48/-0.03}}} +\subsection{\csbh{xintZapFirstSpaces}, \csbh{xintZapLastSpaces}, \csbh{xintZapSpaces}, \csbh{xintZapSpacesB}} +\label{xintZapFirstSpaces} +\label{xintZapLastSpaces} +\label{xintZapSpaces} +\label{xintZapSpacesB} +{\small New with release |1.09f|.\par} +\csa{xintZapFirstSpaces}\marg{stuff} 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. -\subsection{\csbh{xintSgn}}\label{xintiSgn} +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.} -\csa{xintSgn\n} returns 1 if the number is positive, 0 if it is -zero and -1 if it is negative. Extended by \xintfracname to fractions. +\TeX's input scanner already converts consecutive blanks into single space +tokens, but \csa{xintZapFirstSpaces} handles successfully also inputs with +consecutive multiple space tokens. +However, it is assumed that \meta{stuff} does not contain (except in braced +sub-material) space tokens of character code distinct from @32@. -\subsection{\csbh{xintOpp}}\label{xintiOpp} +It expands in two steps, and if the goal is to apply it to the +expansion text of |\x| to define |\y|, then one should do: +|\expandafter\def\expandafter\y\expandafter + {\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}|. -\csa{xintOpp\n} returns the opposite |-N| of the number |N|. -Extended by \xintfracname to fractions. +Other use case: inside a macro as |\edef\x{\xintZapFirstSpaces {#1}}| assuming +naturally that |#1| is compatible with such an |\edef| once the leading spaces +have been stripped. +\begingroup +\def\x { \a { \X } { \b \Y } } +\centeredline{|\xintZapFirstSpaces { \a { \X } { \b \Y } }->|% +\digitstt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}}+++} +\endgroup -\subsection{\csbh{xintAbs}}\label{xintiAbs} +\medskip -\csa{xintAbs\n} returns the absolute value of the number. Extended -by \xintfracname to fractions. +\noindent\csbxint{ZapLastSpaces}\marg{stuff} 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. -\subsection{\csbh{xintAdd}}\label{xintiAdd} +% ATTENTION à l'\ignorespaces fait par \color! +\begingroup +\def\x { \a { \X } { \b \Y } } +\centeredline{|\xintZapLastSpaces { \a { \X } { \b \Y } }->|% +\digitstt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzaplastspaces\expandafter{\x}}}+++} +\endgroup -\csa{xintAdd\n\m} returns the sum of the two numbers. Extended by -\xintfracname to fractions. +\medskip -\subsection{\csbh{xintSub}}\label{xintiSub} +\noindent\csbxint{ZapSpaces}\marg{stuff} 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. -\csa{xintSub\n\m} returns the difference |N-M|. Extended by -\xintfracname to fractions. +\begingroup +\def\x { \a { \X } { \b \Y } } +\centeredline{|\xintZapSpaces { \a { \X } { \b \Y } }->|% +\digitstt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapspaces\expandafter{\x}}}+++} +\endgroup -\subsection{\csbh{xintCmp}}\label{xintiCmp} +\medskip -\csa{xintCmp\n\m} returns 1 if |N>M|, 0 if |N=M|, and -1 if |N{braced}|. The same remarks as for +\csbxint{ZapFirstSpaces} apply. -\subsection{\csbh{xintEq}}\label{xintEq} -{\small New with release |1.09a|.\par} - -\csa{xintEq\n\m} returns 1 if |N=M|, 0 otherwise. -Extended by \xintfracname to fractions. +\begingroup +\def\x { \a { \X } { \b \Y } } +\centeredline{|\xintZapSpacesB { \a { \X } { \b \Y } }->|% +\digitstt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++} +\def\x { { \a { \X } { \b \Y } } } +\centeredline{|\xintZapSpacesB { { \a { \X } { \b \Y } } }->|% +\digitstt{\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{\csbh{xintGt}}\label{xintGt} -{\small New with release |1.09a|.\par} +\subsection{\csbh{xintCSVtoList}} +\label{xintCSVtoList} +\label{xintCSVtoListNoExpand} -% attention dans la doc du 9 octobre j'avais écrit \geq au lieu de > +{\small New with release |1.06|. Starting with |1.09f|, \fbox{\emph{removes + spaces around commas}!}\par} -\csa{xintGt\n\m} returns 1 if |N|$>$|M|, 0 otherwise. -Extended by \xintfracname to fractions. +\csa{xintCSVtoList}|{a,b,c...,z}| 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 command 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{\csbh{xintLt}}\label{xintLt} -{\small New with release |1.09a|.\par} +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[sec: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 disappear). The macro \csbxint{CSVtoListNoExpand} does the same job without +the initial expansion of the list argument. -% attention dans la doc du 9 octobre j'avais écrit \leq au lieu de < +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). -\csa{xintLt\n\m} returns 1 if |N|$<$|M|, 0 otherwise. -Extended by \xintfracname to fractions. +Contiguous spaces, tab characters, or other blanc spaces (empty lines not +allowed) 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.} -\subsection{\csbh{xintIsZero}}\label{xintIsZero} -{\small New with release |1.09a|.\par} +\begingroup -\csa{xintIsZero\n} returns 1 if |N=0|, 0 otherwise. -Extended by \xintfracname to fractions. +\edef\X{\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , { {x , + y} } }} -\subsection{\csbh{xintNot}}\label{xintNot} -{\small New with release |1.09c|.\par} +\centeredline{|\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , + { {x , y} } }|} +\centeredline{|->|% +{\makeatletter\digitstt{\expandafter\strip@prefix\meaning\X}}} -\csa{xintNot} is a synonym for \csa{xintIsZero}. +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{\csbh{xintIsNotZero}}\label{xintIsNotZero} -{\small New with release |1.09a|.\par} +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. -\csa{xintIsNotZero\n} returns 1 if |N<>0|, 0 otherwise. -Extended by \xintfracname to fractions. +From the rules above: for an empty argument (only spaces, no braces, no comma) +the output is +\digitstt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist { }}} +(a list with one empty item), +for ``|{}|'' the output is +\digitstt{\expandafter\detokenize\expandafter + {\romannumeral0\xintcsvtolist { {} }}} +(again a list with one empty item, the braces were removed), +for ``|{ }|'' the output is +\digitstt{\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 +\digitstt{\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 +\digitstt{\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 +\digitstt{\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). -\subsection{\csbh{xintIsOne}}\label{xintIsOne} -{\small New with release |1.09a|.\par} +\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}} -\csa{xintIsOne\n} returns 1 if |N=1|, 0 otherwise. -Extended by \xintfracname to fractions. +\centeredline{|\def\y{ \a,\b,\c,\d,\e} \xintCSVtoList\y->|% + {\makeatletter\digitstt{\expandafter\strip@prefix\meaning\Y}}} +\centeredline{|\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} \centeredline +{|\xintCSVtoList\t->|\makeatletter\digitstt{\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: +\centeredline{|\expandafter\xintCSVtoListNoExpand\expandafter {\y}|} Else, we +may have direct use: \centeredline{|\xintCSVtoListNoExpand + {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} +\centeredline{|->|\digitstt{\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). The original non-stripping +macro is available as \csa{xintCSVtoListNonStripped}. There is also +\csa{xintCSVtoListNonStrippedNoExpand}. -\subsection{\csbh{xintAND}}\label{xintAND} -{\small New with release |1.09a|.\par} +\endgroup -\csa{xintAND\n\m} returns 1 if |N<>0| and |M<>0| and zero otherwise. - Extended by \xintfracname to fractions. +\subsection{\csbh{xintNthElt}}\label{xintNthElt} -\subsection{\csbh{xintOR}}\label{xintOR} -{\small New with release |1.09a|.\par} +{\small New in release |1.06|. With |1.09b| negative indices count from the tail.\par} -\csa{xintOR\n\m} returns 1 if |N<>0| or |M<>0| and zero otherwise. - Extended by \xintfracname to fractions. +\def\macro #1{\the\numexpr 9-#1\relax} +\csa{xintNthElt\x}\marg{list} gets (expandably) the |x|th element of the +\meta{list}, which may be a macro: the list argument is first expanded. The +seeked element is returned with one pair of braces removed (if initially +present). +\centeredline{|\xintNthElt {3}{{agh}\u{zzz}\v{Z}}| is + \texttt{\xintNthElt {3}{{agh}\u{zzz}\v{Z}}}}\centeredline{|\xintNthElt + {37}{\xintFac {100}}|\digitstt{=\xintNthElt {37}{\xintFac {100}}} is the + thirty-seventh digit of @100!@.} \centeredline{|\xintNthElt {10}{\xintFtoCv + {566827/208524}}|\digitstt{=\xintNthElt {10}{\xintFtoCv {566827/208524}}}} +is the tenth convergent of @566827/208524@ (uses \xintcfracname package). +\centeredline{|\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% + \digitstt{=\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}}% +\centeredline{|\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% + \digitstt{=\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} +\centeredline{|\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% + \digitstt{=\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} 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. -\subsection{\csbh{xintXOR}}\label{xintXOR} -{\small New with release |1.09a|.\par} +If |x<0|, the macro returns the \texttt{|x|}th element from the end of the list. + \centeredline{|\xintNthElt + {-5}{{{agh}}\u{zzz}\v{Z}}| is \texttt{\expandafter\expandafter\expandafter + \detokenize + \expandafter\expandafter\expandafter{\xintNthElt + {-5}{{{agh}}\u{zzz}\v{Z}}}}} -\csa{xintXOR\n\m} returns 1 if exactly one of |N| or |M| is true (i.e. -non-zero). - Extended by \xintfracname to fractions. -\subsection{\csbh{xintANDof}}\label{xintANDof} -{\small New with release |1.09a|.\par} +The macro +\csa{xintNthEltNoExpand} 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}. -\csa{xintANDof}|{{a}{b}{c}...}| returns 1 if all are true (i.e. non -zero) and zero otherwise. The list argument -may be a macro, it (or rather its first token) is \fexpan ded first (each -item also is \fexpan ded). Extended by \xintfracname to fractions. +In cases where |x| is larger (in absolute value) than the length of the list +then |\xintNthElt| returns nothing. +\subsection{\csbh{xintListWithSep}}\label{xintListWithSep} -\subsection{\csbh{xintORof}}\label{xintORof} -{\small New with release |1.09a|.\par} +{\small New with release |1.04|.\par} -\csa{xintORof}|{{a}{b}{c}...}| returns 1 if at least one is true -(i.e. does not vanish). The list argument -may be a macro, it is \fexpan ded first. Extended by \xintfracname to fractions. +\def\macro #1{\the\numexpr 9-#1\relax} +\csa{xintListWithSep}|{sep}|\marg{list} inserts the given separator |sep| +in-between all elements of the given list: this separator may be a macro but +will not be expanded. The second argument also may be itself a macro: it is +expanded as usual, \emph{i.e.} fully for what comes first. Applying +\csa{xintListWithSep} removes one level of top braces to each list constituent. +An empty input gives an empty output, a singleton gives a singleton, the +separator is used starting with at least two elements. Using an empty separator +has the net effect of removing one-level of brace pairs from each ot the +top-level braced material constituting the \meta{list} (in such cases the new +list may thus be longer than the original). +\centeredline{|\xintListWithSep{:}{\xintFac + {20}}|\digitstt{=\xintListWithSep{:}{\xintFac {20}}}} -\subsection{\csbh{xintXORof}}\label{xintXORof} -{\small New with release |1.09a|.\par} +The macro \csa{xintListWithSepNoExpand} does the same +job without the initial expansion. -\csa{xintXORof}|{{a}{b}{c}...}| returns 1 if an odd number of them are -true (i.e. does not vanish). The list argument may be a macro, it is -\fexpan ded first. Extended by \xintfracname to fractions. +\subsection{\csbh{xintApply}}\label{xintApply} +{\small New with release |1.04|.\par} -\subsection{\csbh{xintGeq}}\label{xintiGeq} +\def\macro #1{\the\numexpr 9-#1\relax} -\csa{xintGeq\n\m} 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. Extended by \xintfracname to fractions (starting with release -|1.07|). Please note that the macro compares \emph{absolute values}. +\csa{xintApply}|{\macro}|\marg{list} expandably applies the one parameter +command |\macro| to each item in the \meta{list} given as second argument and +return a new list with these outputs: each item is given one after the other as +parameter to |\macro| which is expanded (as usual, \emph{i.e.} fully for what +comes first), and the result is braced. On output, a new list with these braced +results (if |\macro| is defined to start with a space, the space will be gobbled +and the |\macro| will not be executed; |\macro| +is allowed to have its own arguments, the list items will serve as last +arguments to the macro.). -\subsection{\csbh{xintMax}}\label{xintiMax} +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| is not necessarily compatible with +expansion only contexts: |\xintApply| will try to expand it, but the expansion +may remain partial. -\csa{xintMax\n\m} 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): |\xintiMax -{-5}{-6}|\digitstt{=\xintiMax{-5}{-6}}. Extended by \xintfracname to fractions. - -\subsection{\csbh{xintMaxof}}\label{xintMaxof} -{\small New with release |1.09a|.\par} - -\csa{xintMaxof}|{{a}{b}{c}...}| returns the maximum. The list argument -may be a macro, it is \fexpan ded first. Extended by \xintfracname to -fractions. - - -\subsection{\csbh{xintMin}}\label{xintiMin} - -\csa{xintMin\n\m} 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): |\xintiMin -{-5}{-6}|\digitstt{=\xintiMin{-5}{-6}}. Extended by \xintfracname to fractions. - -\subsection{\csbh{xintMinof}}\label{xintMinof} -{\small New with release |1.09a|.\par} - -\csa{xintMinof}|{{a}{b}{c}...}| returns the minimum. The list argument -may be a macro, it is \fexpan ded first. Extended by \xintfracname to -fractions. - -\subsection{\csbh{xintSum}}\label{xintiSum} - -\csa{xintSum}\marg{braced things} after expanding its argument -expects to find a sequence of tokens (or braced material). -Each is expanded (with the usual meaning), and the sum of all these numbers is -returned. -\centeredline{% - \csa{xintiSum}|{{123}{-98763450}{\xintFac{7}}{\xintiMul{3347}{591}}}|% - \digitstt{=\xintiSum{{123}{-98763450}{\xintFac{7}}{\xintiMul{3347}{591}}}}} -\centeredline{\csa{xintiSum}|{1234567890}|\digitstt{=\xintiSum{1234567890}}} -An empty sum is no error and returns zero: |\xintiSum -{}|\digitstt{=\xintiSum {}}. A sum with only one -term returns that number: |\xintiSum {{-1234}}|\digitstt{=\xintiSum - {{-1234}}}. Attention that |\xintiSum {-1234}| is not legal input -and will make the \TeX{} run fail. On the other hand |\xintiSum -{1234}|\digitstt{=\xintiSum{1234}}. Extended by \xintfracname -to fractions. - -% retiré de la doc le 22 octobre 2013 +The \meta{list} may +itself be some macro expanding (in the previously described way) to the list of +tokens to which the command |\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. \centeredline{|\def\macro #1{\the\numexpr + 9-#1\relax}|} \centeredline{|\xintApply\macro{\xintFac + {20}}|\digitstt{=\xintApply\macro{\xintFac {20}}}} -% \subsection{\csbh{xintSumExpr}}\label{xintiSumExpr} +The macro +\csa{xintApplyNoExpand} does the same job without the first initial expansion +which gave the \meta{list} of braced tokens to which |\macro| is applied. -% \csa{xintSumExpr}\meta{braced things}\csa{relax} is to what \csa{xintSum} -% expands. The argument is then expanded (with the usual meaning) and should give -% a list of braced quantities or macros, each one will be expanded in turn. -% \centeredline{% -% \csa{xintiSumExpr}| {123}{-98763450}|% -% |{\xintFac{7}}{\xintiMul{3347}{591}}\relax|\digitstt{=% -% \xintiSumExpr {123}{-98763450}{\xintFac{7}}{\xintiMul{3347}{591}}\relax}} +\subsection{\csbh{xintApplyUnbraced}}\label{xintApplyUnbraced} -% Note: I am not so happy with the name which seems to suggest that the -% |+| sign should be used instead of braces. Perhaps this will change -% in the future. +{\small New in release |1.06b|.\par} -% Extended by \xintfracname to fractions. +\def\macro #1{\expandafter\def\csname myself#1\endcsname {#1}} +\xintApplyUnbraced\macro{{elta}{eltb}{eltc}} -\subsection{\csbh{xintMul}}\label{xintiMul} -{\small Modified in release |1.03|.\par} +\csa{xintApplyUnbraced}|{\macro}|\marg{list} 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 +\centeredline{|\xintListWithSep {}{\xintApply {\macro}|\marg{list}|}|} +This is useful for preparing a macro which will itself define some other macros +or make assignments. +\lverb|& +$ $ $ $ \def\macro #1{\expandafter\def\csname myself#1\endcsname {#1}}$\ +$null$ $ $ $ \xintApplyUnbraced\macro{{elta}{eltb}{eltc}}$\ +$null$ $ $ $ \meaning\myselfelta:$ $ $meaning$myselfelta$\ +$null$ $ $ $ \meaning\myselfeltb:$ $ $meaning$myselfeltb$\ +$null$ $ $ $ \meaning\myselfeltc:$ $ $meaning$myselfeltc +| +The macro \csa{xintApplyUnbracedNoExpand} does the same job without the first +initial expansion which gave the \meta{list} of braced tokens to which +|\macro| +is applied. -\csa{xintMul\n\m} returns the product of the two numbers. Starting -with release |1.03| of \xintname, the macro checks the lengths of -the two numbers and then activates its algorithm with the best (or -at least, hoped-so) choice of which one to put first. This makes -the macro a bit slower for numbers up to 50 digits, but may give -substantial speed gain when one of the number has 100 digits or more. -Extended by \xintfracname to fractions. +\subsection{\csbh{xintSeq}}\label{xintSeq} +{\small New with release |1.09c|.\par} -\subsection{\csbh{xintSqr}}\label{xintiSqr} +\csa{xintSeq}|[d]{x}{y}| 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|. -\csa{xintSqr\n} returns the square. Extended by \xintfracname to fractions. -\subsection{\csbh{xintPrd}}\label{xintiPrd} +The current implementation is only for (short) integers; possibly, a future +variant could allow big integers and fractions, although one already has +access to similar +functionality using \csbxint{Apply} to get any arithmetic sequence of long +integers. Currently thus, |x| and |y| are expanded inside a +|\numexpr| so they may be count registers or a \LaTeX{} |\value{countername}|, +or arithmetic with such things. -\csa{xintPrd}\marg{braced things} after expanding its argument expects to find a -sequence of tokens (or braced material). Each is expanded (with the usual -meaning), and the product of all these numbers is returned. -\centeredline{% - \csa{xintiPrd}|{{-9876}{\xintFac{7}}{\xintiMul{3347}{591}}}|% - \digitstt{=% - \xintiPrd{{-9876}{\xintFac{7}}{\xintiMul{3347}{591}}}}} -\centeredline{\csa{xintiPrd}|{123456789123456789}|\digitstt{=% - \xintiPrd{123456789123456789}}} An empty product is no error and returns 1: -|\xintiPrd {}|\digitstt{=\xintiPrd {}}. A product reduced to a single term returns -this number: |\xintiPrd {{-1234}}|\digitstt{=\xintiPrd {{-1234}}}. Attention that -|\xintiPrd {-1234}| is not legal input and will make the \TeX{} compilation -fail. On the other hand |\xintiPrd {1234}|\digitstt{=\xintiPrd {1234}}. -\centeredline{$\displaystyle 2^{200}3^{100}7^{100}$} \centeredline{|=\xintiPrd - {{\xintiPow {2}{200}}{\xintiPow {3}{100}}{\xintiPow {7}{100}}}|} -\digitstt{=\printnumber{\xintNum {\xinttheexpr 2^200*3^100*7^100\relax }}} +\centeredline{|\xintListWithSep{,\hskip2pt + plus 1pt minus 1pt }{\xintSeq {12}{-25}}|} +\noindent\digitstt{\xintListWithSep{,\hskip2pt plus 1pt minus 1pt }{\xintSeq + {12}{-25}}} +\centeredline{|\xintiSum{\xintSeq [3]{1}{1000}}|\digitstt{=\xintiSum{\xintSeq [3]{1}{1000}}}} -Extended by \xintfracname to fractions. +\textbf{Important:} for reasons of efficiency, this macro, when not given the +optional argument |d|, works backwards, leaving in the token stream the already +constructed integers, from the tail down (or up). But this will provoke a +failure of \IMPORTANT{} the |tex| run if the number of such items exceeds the +input stack +limit; on my installation this limit is at @5000@. -With \xintexprname, the above would be coded simply as \centeredline -{|\xintthenumexpr 2^200*3^100*7^100\relax |} +However, when given the optional argument |d| (which may be @+1@ or +@-1@), the macro proceeds differently and does not put stress on the input stack +(but is significantly slower for sequences with thousands of integers, +especially if they are somewhat big). For +example: |\xintSeq [1]{0}{5000}| works and |\xintiSum{\xintSeq [1]{0}{5000}}| +returns the correct value \digitstt{\xintHalf{\xintiMul{5000}{5001}}}. -% I temporarily remove mention of \xintPrdExpr from the documentation; I -% really dislike the name now. -% \subsection{\csbh{xintPrdExpr}}\label{xintiPrdExpr} +\subsection{Completely expandable prime test}\label{ssec:primesI} -% {\small Name change in |1.06a|! I apologize, but I suddenly decided that -% \csa{xintProductExpr} was a bad choice; so I just replaced it by the current -% name. \par} +Let us now construct a completely expandable macro which returns @1@ if its +given input is prime and @0@ if not: +\dverb|@ +\def\remainder #1#2{\the\numexpr #1-(#1/#2)*#2\relax } +\def\IsPrime #1{\xintANDof + {\xintApply {\remainder {#1}}{\xintSeq {2}{\xintiSqrt{#1}}}}} +| +This uses \csbxint{iSqrt} and assumes its input is at least @5@. Rather than +\xintname's own \csbxint{Rem} 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: +\dverb|@ +\def\IsPrime #1% + {\xintifOdd {#1} + {\xintANDof % odd case + {\xintApply {\remainder {#1}} + {\xintSeq [2]{3}{\xintiSqrt{#1}}}% + }% + } + {\xintifEq {#1}{2}{1}{0}}% + } +| -% \csa{xintPrdExpr}\marg{argument}\csa{relax} is to what \csa{xintPrd} expands -% ; its argument is expanded (with the usual meaning) and should give a list of -% braced numbers or macros. Each will be expanded when it is its turn. -% \centeredline{\csa{xintiPrdExpr}| 123456789123456789\relax|\digitstt{=% -% \xintiPrdExpr 123456789123456789\relax}} +We used the \xintname provided expandable tests (on big integers or fractions) +to maintain the complete expandability of |\IsPrime| in a strong +sense\footnote{\label{fn:fullexp}technically, prefixing it with + \csa{romannumeral-`0} must expand it completely; this is the case of all + \xintname expandable macros, and in turn the arguments must be of this + type.}. -% Note: I am not so happy with the name which seems to suggest that the -% |*| sign should be used instead of braces. Perhaps this will change -% in the future. +Our integers are short, but without +|\expandafter|'s with \makeatletter|\@firstoftwo|\catcode`@ \active, 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: +\dverb|@ +\def\IsPrime #1% + {\ifnumodd {#1} + {\xintANDof % odd case + {\xintApply {\remainder {#1}}{\xintSeq [2]{3}{\xintiSqrt{#1}}}}} + {\ifnumequal {#1}{2}{1}{0}}} +| -% Extended by \xintfracname to fractions. +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: +% +\dverb|@ +\def\IsNotDivisibleBy #1#2% + {\ifnum\numexpr #1-(#1/#2)*#2=0 \expandafter 0\else \expandafter1\fi} +|% +% +where the |\expandafter|'s are crucial for this macro to be completely +expandable in the restricted sense mentioned in \autoref{fn:fullexp} which we +want for applying confidently \csbxint{ANDof}. Anyhow, now that we have loaded +\href{http://ctan.org/pkg/etoolbox}{etoolbox}, we might as well use: +\dverb|@ +\newcommand{\IsNotDivisibleBy}[2]{\ifnumequal{#1-(#1/#2)*#2}{0}{0}{1}} +|% +Let us enhance our prime macro to work also on the small primes: +\dverb|@ +\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}{\xintiSqrt{#1}}}}% + }}% END OF THE ODD BRANCH + {\ifnumequal {#1}{2}{1}{0}}% END OF THE EVEN BRANCH +} +|% +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. We did generate via \csbxint{Seq} too many +divisors though; if we really wanted to optimize even further it would be +reasonable to drop the requirement of complete expandability and use the tools +provided by +the \csbxint{For} loop. -\subsection{\csbh{xintPow}}\label{xintiPow} -\csa{xintPow\n\x} returns |N^x|. When |x| is zero, this is 1. If |N| is zero and -|x<0|, if \verb+|N|>1+ and |x<0| negative, or if \verb+|N|>1+ and |x>999999999|, -then an error is raised. |2^999999999| has \np{301029996} digits; each exact -multiplication of two one thousand digits numbers already takes a few seconds, -so needless to say this bound is completely irrealistic. Already |2^9999| has -\np{3010} digits,\footnote{on my laptop |\string\xintiPow \{2\}\{9999\}| - obtains all |3010| digits in about ten or eleven seconds. In contrast, the - float versions for - |8|, |16|, |24|, or even more significant figures, do their jobs in circa one - hundredth of a second (|1.08b|). This is done without |log|/|exp| which are - not (yet?) implemented in \xintfracname. The \LaTeX3 - \href{http://www.ctan.org/tex-archive/macros/latex/contrib/l3kernel}{l3fp} - does this with |log|/|exp| and is ten times faster (|16| figures only).} so I -should perhaps lower the bound to |99999|. - -Extended by \xintfracname to fractions (\csbxint{Pow}) and also to floats -(\csbxint{FloatPow}). Negative -exponents do not then cause errors anymore. The float version is able to deal -with things such as -|2^999999999| without any problem. For example -|\xintFloatPow[4]{2}{9999}|\digitstt{=\xintFloatPow[4]{2}{9999}} and -|\xintFloatPow[4]{2}{999999999}| -\digitstt{=\xintFloatPow[4]{2}{999999999}}. - -\subsection{\csbh{xintSgnFork}}\label{xintSgnFork} -{\small New with release |1.07|. See also \csbxint{ifSgn}.\par} +Let us construct 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. 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. +% +\dverb?@ +\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. +?% +% +We had to be careful to use the optional argument |[1]| to \csbxint{Seq} in +this last row to not generate a decreasing sequence from |1| to |0|, but an +empty sequence when the row turns out to already have all its cells. +% +\newcommand{\IsNotDivisibleBy}[2]{\ifnumequal{#1-(#1/#2)*#2}{0}{0}{1}} -\csa{xintSgnFork}\verb+{-1|0|1}+\marg{A}\marg{B}\marg{C} expandably -chooses to execute either the \meta{A}, \meta{B} or \meta{C} code, -depending on its first argument. This first argument should be anything -expanding to either |-1|, |0| or |1| (a count register should be -prefixed by |\the| and a |\numexpr...\relax| also should be prefixed by -|\the|). This utility is provided to help construct expandable macros -choosing depending on a condition which one of the package macros to -use, or which values to confer to their arguments. +\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}{\xintiSqrt{#1}}}}% + }}% END OF THE ODD BRANCH + {\ifnumequal {#1}{2}{1}{0}}% END OF THE EVEN BRANCH +} -\subsection{\csbh{xintifSgn}}\label{xintifSgn} -{\small New with release |1.09a|.\par} +\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 + \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*} -Similar to \csa{xintSgnFork} except that the first argument may expand to a -(big) integer (or a fraction if \xintfracname is loaded), and it is its sign -which decides which of the three branches is taken. Furthermore this first -argument may be a count register, with no |\the| or |\number| prefix. +\subsection{\csbh{xintloop}, \csbh{xintbreakloop}, \csbh{xintbreakloopanddo}, \csbh{xintloopskiptonext}} +\label{xintloop} +\label{xintbreakloop} +\label{xintbreakloopanddo} +\label{xintloopskiptonext} +{\small New with release |1.09g|.\par} + +|\xintloop|\meta{stuff}|\iftest ... \repeat| is an expandable loop compatible +with nesting. If a sub-loop is to be used all the material from the start and up +to the complete subloop inclusive should be braced; these braces will be removed +and do not create a group. + +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. The loop and its various constituents are declared short, +they can not handle |\par| tokens or empty lines. + +One can abort the loop with \csbxint{breakloop}; this should not be used in 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. + +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*}. + +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 \url{http://tex.stackexchange.com/a/143035/4686} from November 11, 2013.} +\begingroup +\makeatother +\begin{verbatim} +\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 % etc... +\[\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}\] +\end{verbatim} +\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 +\setlength{\unitlength}{1cm} +% le picture de LaTeX est tout de même assez génial! +\begin{picture}(0,0) +\put(6,10){\vtop{\hsize8cm +\[\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}\]\MatrixMultiplication\C\D\E +\[\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}\]\MatrixMultiplication\C\E\F +\[\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{picture} +\endgroup -\subsection{\csbh{xintifZero}}\label{xintifZero} -{\small New with release |1.09a|.\par} +\vskip-\baselineskip + +\subsection{\csbh{xintiloop}, \csbh{xintiloopindex}, \csbh{xintouteriloopindex}, + \csbh{xintbreakiloop}, \csbh{xintbreakiloopanddo}, \csbh{xintiloopskiptonext}, +\csbh{xintiloopskipandredo}} +\label{xintiloop} +\label{xintbreakiloop} +\label{xintbreakiloopanddo} +\label{xintiloopskiptonext} +\label{xintiloopskipandredo} +\label{xintiloopindex} +\label{xintouteriloopindex} +{\small New with release |1.09g|.\par} + +\csa{xintiloop}|[start+delta]|\meta{stuff}|\iftest ... \repeat| is a completely +expandable nestable loop having access via \csbxint{iloopindex} to the integer +index of the iteration, with starting value |start| (which may be a |\count|) +and increment |delta| (\emph{id.}). Currently |[start+delta]| is a +\emph{mandatory argument}, it is an error to omit it; perhaps a future release +will make it optional with default |1+1|. 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|. + +As with \csbxint{loop}, this tool will mostly be of interest to advanced users. +As is the case for its variant, it is declared short and can not handle directly +|\par| tokens or empty lines. 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, \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|. + +As an example, let us construct an |\edef\z{...}| which will define |\z| to be a +list of prime numbers: +\dverb|@ +\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| +\begingroup%\ttfamily +\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 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|\,! +\endgroup -\csa{xintifZero}\marg{N}\marg{IsZero}\marg{IsNotZero} 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. +Let us create an alignment where each row will contain all divisors of its +first entry. +\dverb|@ +\tabskip1ex +\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 % \space is CRUCIAL + \repeat \cr }% + \ifnum\xintiloopindex<30 + \repeat }| -\subsection{\csbh{xintifNotZero}}\label{xintifNotZero} -{\small New with release |1.09a|.\par} +% +\noindent 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 is: +% +\dverb|@ \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 }| -\csa{xintifNotZero}\marg{N}\marg{IsNotZero}\marg{IsZero} 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 not zero or -is zero. It then either executes the first or the second branch. +\noindent +Here is the output, thus obtained without any count register: +\begingroup\catcode`_ 11 +\begin{multicols}2 +\tabskip1ex +\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} +\endgroup -\subsection{\csbh{xintifTrueFalse}}\label{xintifTrueFalse} -{\small New with release |1.09c|, renamed in |1.09e|.\par} +\subsection{A table of factorizations} -\csa{xintifTrueFalse}\marg{N}\marg{true branch}\marg{false branch} is a synonym -for \csbxint{ifNotZero}. It is also available as \csa{xintifTrue} but this later -name is a bit misleading as the macro must always have a |false| branch, -possibly an empty brace pair |{}|. +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. -\subsection{\csbh{xintifCmp}}\label{xintifCmp} -{\small New with release |1.09e|.\par} +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}. -\csa{xintifCmp}\marg{A}\marg{B}\marg{if AB} compares -its arguments and chooses accordingly the correct branch. +\begingroup +\def\MacroFont{\ttfamily\baselineskip12pt\relax \catcode`\" 12 } +\dverb|@ +\tabskip1ex +\halign {&\hfil\strut#\hfil\cr\noalign{\hrule} + \xintiloop ["7FFFFFE0+1] + \expandafter\bf\xintiloopindex & + \ifnum\xintiloopindex="7FFFFFED + \number"7FFFFFED\cr\noalign{\hrule} + \expandafter\xintiloopskiptonext + \fi + \expandafter\factorize\xintiloopindex.\cr\noalign{\hrule} + \ifnum\xintiloopindex<"7FFFFFFE + \repeat + \bf \number"7FFFFFFF&\number "7FFFFFFF\cr\noalign{\hrule} +}|\par\smallskip +\endgroup -\subsection{\csbh{xintifEq}}\label{xintifEq} -{\small New with release |1.09a|.\par} +The \hyperref[floatfactorize]{table} has been made into a float which appears +\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 \texttt{\char92\string@firstoftwo} and +\texttt{\char92\string@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. -\csa{xintifEq}\marg{A}\marg{B}\marg{YES}\marg{NO} checks equality of its -two first arguments (numbers, or fractions if \xintfracname is loaded) and does the |YES| or the |NO| branch. +The reason for some strange looking expressions is to avoid arithmetic overflow. -\subsection{\csbh{xintifGt}}\label{xintifGt} -{\small New with release |1.09a|.\par} +\begingroup +\def\MacroFont{\ttfamily\baselineskip12pt\relax \catcode`\" 12 } +\dverb|@ +\catcode`_ 11 +\def\abortfactorize #1\xint_secondoftwo\fi #2#3{\fi} + +\def\factorize #1.{\ifnum#1=1 \abortfactorize\fi + % avoid overflow if #1="7FFFFFFF + \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.}}% + +\def\factorize_b #1.#2.{\ifnum#1=1 \abortfactorize\fi + % this will avoid overflow which could result from #2*#2 + \ifnum\numexpr #1-(#2-1)*#2<#2 + #1\abortfactorize % this #1 is prime + \fi + % again, avoiding overflow as \numexpr integer division + % rounds rather than truncates. + \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| +\endgroup -% attention dans la doc du 9 octobre j'avais écrit \geq au lieu de < -\csa{xintifGt}\marg{A}\marg{B}\marg{YES}\marg{NO} checks if $A>B$ and in that -case executes the |YES| branch. Extended to fractions (in particular decimal -numbers) by \xintfracname. +\catcode`_ 11 +\def\abortfactorize #1\xint_secondoftwo\fi #2#3{\fi} -\subsection{\csbh{xintifLt}}\label{xintifLt} -{\small New with release |1.09a|.\par} +\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.}}% + +\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} +\tabskip1ex +\centeredline{\vbox{\halign {&\hfil\strut#\hfil\cr\noalign{\hrule} + \xintiloop ["7FFFFFE0+1] + \expandafter\bf\xintiloopindex & + \ifnum\xintiloopindex="7FFFFFED + \number"7FFFFFED\cr\noalign{\hrule} + \expandafter\xintiloopskiptonext + \fi + \expandafter\factorize\xintiloopindex.\cr\noalign{\hrule} + \ifnum\xintiloopindex<"7FFFFFFE + \repeat + \bf \number"7FFFFFFF&\number "7FFFFFFF\cr\noalign{\hrule} +}}} +\centeredline{A table of factorizations} +\end{figure*} -% attention dans la doc du 9 octobre j'avais écrit \leq au lieu de < -\csa{xintifLt}\marg{A}\marg{B}\marg{YES}\marg{NO} checks if $A0|, |M^2-d=N| and |M| -smallest (hence |=1+|\csa{xint\-iSqrt}|{N}|). -\centeredline{|\xintAssign\xintiSquareRoot - {17000000000000000000000000}\to\A\B|}% -\centeredline{|\xintiSub{\xintiSqr\A}\B=\A^2-\B|}% -\centeredline{\digitstt{\xintiSub{\xintiSqr\A}\B=\A\string^2-\B}} -A rational approximation to -$\sqrt{|N|}$ is $|M|-\frac{|d|}{|2M|}$ (this is a majorant and the error is at -most |1/2M|; if |N| is a perfect square |k^2| then |M=k+1| and this gives -|k+1/(2k+2)|, not |k|). +The spaces between the various declarative elements are all optional; +furthermore spaces around the commas or at the start and end of the list +argument are allowed, they will be removed. If an item must contain itself +commas, it should be braced to prevent these commas from being misinterpreted as +list separator. The braces will be removed during processing. The list +argument may be a macro |\MyList| which then does not need to be braced (except +if it has some arguments, as then the whole thing \emph{must} be braced). It +will be expanded (only once) to reveal its comma separated items for processing. -Package \xintfracname has \csbxint{FloatSqrt} for square -roots of floating point numbers. +A starred variant \csbxint{For*} deals with lists of braced items, rather than +comma separated items. It has also a distinct expansion policy, which is +detailed below. +Contrarily to what happens in loops where the item is represented by a macro, +here it is truly exactly as when defining (in \LaTeX{}) a ``command'' with +parameters |#1|, etc... This may avoid the user quite a few troubles with +|\expandafter|s or other |\edef/\noexpand|s which one encounters at times when +trying to do things with \LaTeX's {\makeatother|\@for|} or other loops +which encapsulate the item in a macro expanding to that item. \begin{framed} - The macros described next are strictly for integer-only arguments. These - arguments are \emph{not} filtered via \csbxint{Num}. + The non-starred variant \csbxint{For} deals with comma separated values + (\emph{spaces before and after the commas are removed}) and the comma + separated list may be a macro which is only expanded once (to prevent + expansion of the first item |\x| in a list directly input as |\x,\y,...| it + should be input as |{\x},\y,..| or |\x,\y,..|, naturally all of that + within the mandatory braces of the \csa{xintFor \#n in \{list\}} syntax). The + items are not expanded, if the input is |,\x,| then |#1| will be + at some point |\x| not its expansion (and not either a macro with |\x| as + replacement text, just the token |\x|). Input such as |,,| + creates an empty |#1|, the iteration is not skipped. An empty list does lead + to the use of the replacement text, once, with an empty |#1| (or |#n|). Except + if the entire list is represented as a single macro with no parameters, + \fbox{it must be braced.} \end{framed} -\subsection{\csbh{xintInc}, \csbh{xintDec}} -\label{xintInc} -\label{xintDec} -{\small New with |1.08|.\par} - -\csa{xintInc\n} is |N+1| and \csa{xintDec\n} is |N-1|. These macros remain -integer-only, even with \xintfracname loaded. - -\subsection{\csbh{xintDouble}, \csbh{xintHalf}} -\label{xintDouble} -\label{xintHalf} -{\small New with |1.08|.\par} - -\csa{xintDouble\n} returns |2N| and \csa{xintHalf\n} is |N/2| rounded -towards zero. These macros remain integer-only, even with \xintfracname loaded. +\begin{framed} + The starred variant \csbxint{For*} deals with token lists (\emph{spaces + between braced items or single tokens are not significant}) and + \hyperref[fn:expansions]{\fexpan ds} each \emph{unbraced} list item. This + makes it easy to simulate concatenation of various list macros |\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}}|% + \stepcounter{footnote}% + \makeatletter\hbox {\@textsuperscript {\normalfont \thefootnote + }}\makeatother. Spaces at the start, end, or in-between items are gobbled + (but naturally not the spaces which may be inside \emph{braced} items). Except + if the list argument is a single macro with no parameters, \fbox{it must be + braced.} Each item which is not braced will be fully expanded (as the |\x| + and |\y| in the example above). An empty list leads to an empty result. +\end{framed} +\begingroup\makeatletter +\def\@footnotetext #1{\insert\footins {\reset@font \footnotesize \interlinepenalty \interfootnotelinepenalty \splittopskip \footnotesep \splitmaxdepth \dp \strutbox \floatingpenalty \@MM \hsize \columnwidth \@parboxrestore \color@begingroup \@makefntext {\rule \z@ \footnotesep \ignorespaces #1\@finalstrut \strutbox }\color@endgroup }} +\addtocounter{footnote}{-1} +\edef\@thefnmark {\thefootnote} +\@footnotetext{braces around single token items + are optional so this is the same as \texttt{\{123456\}}.} +% \stepcounter{footnote} +% \edef\@thefnmark {\thefootnote} +% \@footnotetext{the \csa{space} will stop the \TeX{} scanning of a number and be +% gobbled in the process; the \csa{relax} stops the scanning but is not +% gobbled. Or one may do \csa{numexpr}\texttt{\#1}\csa{relax}, and then the +% \csa{relax} is gobbled.} +\endgroup +%\addtocounter{Hfootnote}{2} +\addtocounter{Hfootnote}{1} + +The macro \csbxint{Seq} which generates arithmetic sequences may only be used +with \csbxint{For*} (numbers from output of |\xintSeq| are braced, not separated +by commas). \centeredline{|\xintFor* #1 in {\xintSeq [+2]{-7}{+2}}\do {stuff + with #1}|} will have |#1=-7,-5,-3,-1, and 1|. The |#1| as issued from the +list produced by \csbxint{Seq} is the litteral representation as would be +produced by |\arabic| on a \LaTeX{} counter, it is not a count register. When +used in |\ifnum| tests or other contexts where \TeX{} looks for a number it is +recommended to use |#1\space|\footnote{the \csa{space} will stop the \TeX{} + scanning of a number and be gobbled in the process; the \csa{relax} stops the + scanning but is not gobbled. Or one may do + \csa{numexpr}\texttt{\#1}\csa{relax}, and then the \csa{relax} is gobbled.}, +or |#1\relax| if expandability of the process is not an issue (for example if +the iterated commands do an |\edef| using such a test, |\relax| is not a good +choice as it will be kept in the complete expansion if it is in the true branch +of the conditional, whereas |\space| will disappear). + +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: +% +\dverb|@ + \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 .. }| -\subsection{\csbh{xintDSL}}\label{xintDSL} +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. +However, in the example above, if the |.. some other macros ..| part +closes a group which was opened before the |\edef\innersequence|, then +this definition will be lost. An alternative to |\edef|, also efficient, +exists when dealing with arithmetic sequences: it is to use the +\csbxint{integers} keyword (described later) which simulates infinite +arithmetic sequences; the loops will then be terminated via a test |#1| +(or |#2| etc\dots) and subsequent use of \csbxint{BreakFor}. -\csa{xintDSL\n} is decimal shift left, \emph{i.e.} multiplication -by ten. -\subsection{\csbh{xintDSR}}\label{xintDSR} -\csa{xintDSR\n} is decimal shift right, \emph{i.e.} it removes the last digit -(keeping the sign), equivalently it is the closest integer to |N/10| when -starting at zero. +The \csbxint{For} loops are not completely expandable; but they may be nested +and used inside alignments or other contexts where the replacement text closes +groups. Here is an example (still using \LaTeX's tabular): -\subsection{\csbh{xintDSH}}\label{xintDSH} +\begingroup +\centeredline{\begin{tabular}{rccccc} + \xintFor #7 in {A,B,C} \do {% + #7:\xintFor* #3 in {abcde} \do {&($ #3 \to #7 $)}\\ }% +\end{tabular}} +\endgroup -\csa{xintDSH\x\n} is parametrized decimal shift. When |x| is -negative, it is like iterating \csa{xintDSL} \verb+|x|+ times -(\emph{i.e.} multiplication by @10^{-@|x|@}@). When |x| positive, -it is like iterating \csa{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|. +\dverb|@ +\begin{tabular}{rccccc} + \xintFor #7 in {A,B,C} \do {% + #7:\xintFor* #3 in {abcde} \do {&($ #3 \to #7 $)}\\ }% +\end{tabular}| -\subsection{\csbh{xintDSHr}, \csbh{xintDSx}}\label{xintDSHr}\label{xintDSx} -{\small New in release |1.01|.\par} - -\csa{xintDSHr\x\n} expects |x| to be zero or positive and it returns -then a value |R| which is correlated to the value |Q| returned by -\csa{xintDSH\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{xintDivision}), -\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|. +When +inserted 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: +% +\dverb|@ +\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 |% +\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)} }% + }}% +\centeredline{\T\def\sep {\def\sep{, }}\z} Similarly when the replacement text +of |\xintFor| defines a macro with parameters, the macro character |#| must be +doubled. +It is licit to use inside an \csbxint{For} a |\macro| which itself has +been defined to use internally some other \csbxint{For}. The same macro +parameter |#1| can be used with no conflict (as mentioned above, in the +definition of |\macro| the |#| used in the \csbxint{For} declaration must be +doubled, as is the general rule in \TeX{} with things defined inside other +things). -\csa{xintDSx\x\n} for |x| negative is exactly as -\csa{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 -\csa{xintDSH\x\n}, and |R| is \csa{xintDSHr\x\n}, but computed -simultaneously. +The iterated commands as well as the list items are allowed to contain explicit +|\par| tokens. Neither \csbxint{For} nor \csbxint{For*} create groups. The +effect is like piling up the iterated commands with each time |#1| (or |#2| ...) +replaced by an item of the list. However, contrarily to the completely +expandable \csbxint{ApplyUnbraced}, but similarly to the non completely +expandable \csbxint{ApplyInline} each iteration is executed first before looking +at the next |#1|\footnote{to be completely honest, both \csbxint{For} and + \csbxint{For*} intially scoop up both the list and the iterated commands; + \csbxint{For} scoops up a second time the entire comma separated list in order + to feed it to \csbxint{CSVtoList}. The starred variant \csbxint{For*} which + does not need this step will thus be a bit faster on equivalent inputs.} (and +the starred variant \csbxint{For*} keeps on expanding each unbraced item it +finds, gobbling spaces). -\begin{flushleft} - \xintAssign\xintDSx {-1}{-123456789}\to\M - \noindent{|\xintAssign\xintDSx {-1}{-123456789}\to\M|}\\ - |\meaning\M: |\digitstt{\meaning\M}.\\ - \xintAssign\xintDSx {-20}{1234567689}\to\M - {|\xintAssign\xintDSx {-20}{123456789}\to\M|}\\ - |\meaning\M: |\digitstt{\meaning\M}.\\ - \xintAssign\xintDSx{0}{-123004321}\to\Q\R - {|\xintAssign\xintDSx {0}{-123004321}\to\Q\R|}\\ - \noindent|\meaning\Q: |\digitstt{\meaning\Q}, |\meaning\R: - |\digitstt{\meaning\R.}\\ - |\xintDSH {0}{-123004321}|\digitstt{=\xintDSH {0}{-123004321}}, - |\xintDSHr {0}{-123004321}|\digitstt{=\xintDSHr {0}{-123004321}}\\ - \xintAssign\xintDSx {6}{-123004321}\to\Q\R - {|\xintAssign\xintDSx {6}{-123004321}\to\Q\R|}\\ - |\meaning\Q: |\digitstt{\meaning\Q}, - |\meaning\R: |\digitstt{\meaning\R.}\\ - |\xintDSH {6}{-123004321}|\digitstt{=\xintDSH {6}{-123004321}}, - |\xintDSHr {6}{-123004321}|\digitstt{=\xintDSHr {6}{-123004321}}\\ - \xintAssign\xintDSx {8}{-123004321}\to\Q\R - {|\xintAssign\xintDSx {8}{-123004321}\to\Q\R|}\\ - |\meaning\Q: |\digitstt{\meaning\Q}, - |\meaning\R: |\digitstt{\meaning\R.} \\ - |\xintDSH {8}{-123004321}|\digitstt{=\xintDSH {8}{-123004321}}, - |\xintDSHr {8}{-123004321}|\digitstt{=\xintDSHr {8}{-123004321}}\\ - \xintAssign\xintDSx {9}{-123004321}\to\Q\R - {|\xintAssign\xintDSx {9}{-123004321}\to\Q\R|}\\ - |\meaning\Q: |\digitstt{\meaning\Q}, - |\meaning\R: |\digitstt{\meaning\R.}\\ - |\xintDSH {9}{-123004321}|\digitstt{=\xintDSH {9}{-123004321}}, - |\xintDSHr {9}{-123004321}|\digitstt{=\xintDSHr {9}{-123004321}}\\ -\end{flushleft} +\subsection{\csbh{xintifForFirst}, \csbh{xintifForLast}} +\label{xintifForFirst}\label{xintifForLast} +{\small New in |1.09e|.\par} -\subsection{\csbh{xintDecSplit}}\label{xintDecSplit} -{\small This has been modified in release |1.01|.\par} +\csbxint{ifForFirst}\,\texttt{\{YES branch\}\{NO branch\}} + and \csbxint{ifForLast}\,\texttt{\{YES + branch\}\hskip 0pt plus 0.2em \{NO branch\}} execute the |YES| or |NO| branch +if the +\csbxint{For} +or \csbxint{For*} loop is currently in its first, respectively last, iteration. -\csa{xintDecSplit\x\n} cuts the number into two pieces (each one within a -pair of enclosing braces). First the sign if present is \emph{removed}. -Then, for |x| positive or null, the second piece contains the |x| least -significant digits (\emph{empty} if |x=0|) and the first piece the remaining -digits (\emph{empty} when |x| equals or exceeds the length of |N|). -Leading zeros in the second piece are not removed. When |x| is negative -the first piece contains the \verb+|x|+ most significant digits and the -second piece the remaining digits (\emph{empty} if @|x|@ equals or exceeds -the length of |N|). Leading zeros in this second piece are not removed. -So the absolute value of the original number is always the concatenation -of the first and second piece. +Designed to work as expected under nesting. 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. -{\footnotesize This macro's behavior for |N| non-negative is final and will not - change. I am still hesitant about what to do with the sign of a - negative |N|.\par} +There is no such thing as an iteration counter provided by the \csa{xintFor} +loops; the user is invited to define if needed his own count register or +\LaTeX{} counter, for example with a suitable |\stepcounter| inside the +replacement text of the loop to update it. +\subsection{ \csbh{xintBreakFor}, \csbh{xintBreakForAndDo}} +\label{xintBreakFor}\label{xintBreakForAndDo} +{\small New in |1.09e|.\par} -\xintAssign\xintDecSplit {0}{-123004321}\to\L\R -\centeredline{|\xintAssign\xintDecSplit {0}{-123004321}\to\L\R|} -\noindent|\meaning\L: |\digitstt{\meaning\L}, |\meaning\R: |\digitstt{\meaning\R.} -\xintAssign\xintDecSplit {5}{-123004321}\to\L\R -\centeredline{|\xintAssign\xintDecSplit {5}{-123004321}\to\L\R|} -|\meaning\L: |\digitstt{\meaning\L}, |\meaning\R: |\digitstt{\meaning\R.} -\xintAssign\xintDecSplit {9}{-123004321}\to\L\R -\centeredline{|\xintAssign\xintDecSplit {9}{-123004321}\to\L\R|} -|\meaning\L: |\digitstt{\meaning\L}, |\meaning\R: |\digitstt{\meaning\R.} -\xintAssign\xintDecSplit {10}{-123004321}\to\L\R -\centeredline{|\xintAssign\xintDecSplit {10}{-123004321}\to\L\R|} -|\meaning\L: |\digitstt{\meaning\L}, |\meaning\R: |\digitstt{\meaning\R.} -\xintAssign\xintDecSplit {-5}{-12300004321}\to\L\R -\centeredline{|\xintAssign\xintDecSplit {-5}{-12300004321}\to\L\R|} -|\meaning\L: |\digitstt{\meaning\L}, |\meaning\R: |\digitstt{\meaning\R.} -\xintAssign\xintDecSplit {-11}{-12300004321}\to\L\R -\centeredline{|\xintAssign\xintDecSplit {-11}{-12300004321}\to\L\R|} -|\meaning\L: |\digitstt{\meaning\L}, |\meaning\R: |\digitstt{\meaning\R.} -\xintAssign\xintDecSplit {-15}{-12300004321}\to\L\R -\centeredline{|\xintAssign\xintDecSplit {-15}{-12300004321}\to\L\R|} -|\meaning\L: |\digitstt{\meaning\L}, |\meaning\R: |\digitstt{\meaning\R.} +One may immediately terminate an \csbxint{For} or \csbxint{For*} loop with +\csbxint{BreakFor}. As the criterion for breaking will be decided on a +basis of some test, it is recommended to use for this test the syntax of +\href{http://ctan.org/pkg/ifthen}{ifthen}\footnote{\url{http://ctan.org/pkg/ifthen}} +or +\href{http://ctan.org/pkg/etoolbox}{etoolbox}\footnote{\url{http://ctan.org/pkg/etoolbox}} +or the \xintname own conditionals, rather than one of the various +|\if...\fi| of \TeX{}. Else (and this is without even mentioning all the various +pecularities of the +|\if...\fi| constructs), one has to carefully move the break after the closing +of +the conditional, typically with |\expandafter\xintBreakFor\fi|.\footnote{the + difficulties here are similar to those mentioned in \autoref{sec:ifcase}, + although less severe, as complete expandability is not to be maintained; hence + the allowed use of \href{http://ctan.org/pkg/ifthen}{ifthen}.} -\subsection{\csbh{xintDecSplitL}}\label{xintDecSplitL} +There is also \csbxint{BreakForAndDo}. Both are illustrated by various examples +in the next section which is devoted to ``forever'' loops. -\csa{xintDecSplitL\x\n} returns the first piece after the action -of \csa{xintDecSplit}. -\subsection{\csbh{xintDecSplitR}}\label{xintDecSplitR} +\subsection{\csbh{xintintegers}, \csbh{xintdimensions}, \csbh{xintrationals}} +\label{xintegers}\label{xintintegers} +\label{xintdimensions}\label{xintrationals} +{\small New in |1.09e|.\par} -\csa{xintDecSplitR\x\n} returns the second piece after the action -of \csa{xintDecSplit}. +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. +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 commands +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. -\section{Commands (utilities) of the \xintname package} -\label{sec:utilsxint} -The completely expandable utilities come first, up to and including -\csbxint{Seq} (which is listed here because it generates sequences of short -integers using |\numexpr|, thus does not make use of the big integers macros of -\xintname). +% original definitions, a bit slow. -This section contains various concrete examples of use of these utilities (such -as \csbxint{ApplyUnbraced}, \csbxint{ApplyInline} and \csbxint{For*}), and ends with a -\hyperref[ssec:quicksort]{completely expandable implementation of the Quick Sort - algorithm} together with a graphical illustration of its action. +% \def\DimToNum #1{\number\dimexpr #1\relax } +% % cube +% \xintNewNumExpr \FA [2] {{_DimToNum {$2}}^3/{_DimToNum {$1}}^2} %$ +% % square root +% \xintNewNumExpr \FB [2] {sqrt ({_DimToNum {$2}}*{_DimToNum {$1}})} +% \xintNewExpr \Ratio [2] {trunc({_DimToNum {$2}}/{_DimToNum{$1}},3)} -\localtableofcontents +% improved faster code (4 four times faster) -\subsection{\csbh{xintReverseOrder}}\label{xintReverseOrder} +\def\DimToNum #1{\the\numexpr \dimexpr#1\relax/10000\relax } +\def\FA #1#2{\xintDSH{-4}{\xintQuo {\xintiPow {\DimToNum {#2}}{3}}{\xintiSqr +{\DimToNum{#1}}}}} +\def\FB #1#2{\xintDSH {-4}{\xintiSqrt + {\xintiMul {\DimToNum {#2}}{\DimToNum{#1}}}}} +\def\Ratio #1#2{\xintTrunc {2}{\DimToNum {#2}/\DimToNum{#1}}} -\csa{xintReverseOrder}\marg{list} does not do any -expansion of its argument and just reverses the order of the -tokens in the \meta{list}.\footnote{the argument is not a token list variable, - just a - \meta{list} of tokens.} Brace pairs encountered are removed once and the -enclosed -material does not get reverted. Spaces are gobbled. -\centeredline{|\xintReverseOrder{\xintDigitsOf\xintiPow {2}{100}\to\Stuff}|} -\centeredline{gives: - \ttfamily{\string\Stuff\string\to1002\string\xintiPow\string\xintDigitsOf}} +% a further 2.5 gain is made through using .25pt as horizontal step. +\begin{figure*}[ht!] +\phantomsection\hypertarget{graphic}{}% +\centeredline{% +\begingroup +\raisebox{-1cm}{\xintFor #1 in {\xintdimensions [0pt+.25pt]} \do + {\ifdim #1>2cm \expandafter\xintBreakFor\fi + \color [rgb]{\Ratio {2cm}{#1},0,0}% + \vrule width .25pt height \FB {2cm}{#1}sp depth -\FA {2cm}{#1}sp + }% end of For iterated text +}% +\endgroup +\hspace{1cm}% +\scriptsize\def\MacroFont {\ttfamily\baselineskip8pt\relax} +\begin{minipage}{\dimexpr\linewidth-3cm-\parindent\relax} +\dverb|@ +\def\DimToNum #1{\number\dimexpr #1\relax } +\xintNewNumExpr \FA [2] {{_DimToNum {$2}}^3/{_DimToNum {$1}}^2} % cube +\xintNewNumExpr \FB [2] {sqrt ({_DimToNum {$2}}*{_DimToNum {$1}})} % sqrt +\xintNewExpr \Ratio [2] {trunc({_DimToNum {$2}}/{_DimToNum{$1}},3)} +\begingroup % to limit the scope of color changes +\xintFor #1 in {\xintdimensions [0pt+.1pt]} \do + {\ifdim #1>2cm \expandafter\xintBreakFor\fi + \color [rgb]{\Ratio {2cm}{#1},0,0}% + \vrule width .1pt height \FB {2cm}{#1}sp depth -\FA {2cm}{#1}sp + }% end of For iterated text +\endgroup|\par +\end{minipage}} +\end{figure*} -\subsection{\csbh{xintRevWithBraces}}\label{xintRevWithBraces} +% attention, pour le \meaning dans cette note de base de page -{\small New in release |1.06|.\par} -\edef\X{\xintRevWithBraces{12345}} -\edef\y{\xintRevWithBraces\X} -\expandafter\def\expandafter\w\expandafter - {\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}} - - -\csa{xintRevWithBraces}\marg{list} first does the expansion of its argument -(which thus may be macro), then it reverses the order of the tokens, or braced -material, it encounters, adding a pair of braces to each (thus, maintaining -brace pairs already existing). Spaces (in-between external brace pairs) 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 expansion 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. \centeredline{|\edef\x{\xintRevWithBraces{12345}}|} -\centeredline{|\meaning\x:|\ttfamily{\meaning\X}} -\centeredline{|\edef\y{\xintRevWithBraces\x}|}% -\centeredline{|\meaning\y:|\ttfamily{\meaning\y}} The examples above could be -defined with |\edef|'s because the braced material did not contain macros. -Alternatively: \centeredline{|\expandafter\def\expandafter\w\expandafter|}% -\centeredline{|{\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}}|} -\centeredline{|\meaning\w:|\ttfamily{\meaning\w}} The macro -\csa{xintReverseWithBracesNoExpand} -does the same job without the initial expansion of its argument. - -\subsection{\csbh{xintLength}}\label{xintLength} - -\csa{xintLength}\marg{list} does not do \emph{any} expansion of its argument and just -counts how many tokens there are (possibly none). So to use it to count things -in the replacement text of a macro one should do -|\expandafter\xintLength\expandafter{\x}|. One may also use it inside macros -as |\xintLength{#1}|. Things enclosed in braces -count as one. Blanks between tokens are not counted. See \csbxint{NthElt}|{0}| -for a variant which first \fexpan ds its argument. -\centeredline{|\xintLength {\xintiPow - {2}{100}}|\digitstt{=\xintLength {\xintiPow{2}{100}}}} -\centeredline{${}\neq{}$|\xintLen {\xintiPow {2}{100}}|\digitstt{=\xintLen - {\xintiPow{2}{100}}}} - -\subsection{\csbh{xintZapFirstSpaces}, \csbh{xintZapLastSpaces}, \csbh{xintZapSpaces}, \csbh{xintZapSpacesB}} -\label{xintZapFirstSpaces} -\label{xintZapLastSpaces} -\label{xintZapSpaces} -\label{xintZapSpacesB} -{\small New with release |1.09f|.\par} +The\xintNewNumExpr \FA [2] {{_DimToNum {$2}}^3/{_DimToNum {$1}}^2} %$ +\hyperlink{graphic}{graphic}, with the code on its right\footnote{the somewhat + peculiar use of |\_| and |\$| is explained in \autoref{xintNewExpr}; they are + made necessary from the fact that the parameters are passed to a \emph{macro} + (\csa{DimToNum}) and not only to \emph{functions}, as are known to + \hyperref[sec:exprsummary]{\csa{xintexpr}}. But one can also define directly + the desired function, for example the constructed \csa{FA} turns out to have + meaning \texttt{\meaning\FA}, where the \csa{romannumeral} part is only to + ensure it expands in only two steps, and could be removed. A handwritten macro + would use here \csa{xintiPow} and not \csa{xintPow}, as we know it has to deal + with integers only. See the next footnote.}, is for illustration only, not +only because of pdf rendering artefacts when displaying adjacent rules (which do +\emph{not} show in |dvi| output as rendered by |xdvi|, and depend from your +viewer), but because not using anything but rules it is quite inefficient and +must do lots of computations to not confer a too ragged look to the borders. +With a width of |.5pt| rather than |.1pt| for the rules, one speeds up the +drawing by a factor of five, but the boundary is then visibly ragged. +\newbox\codebox +\begingroup\makeatletter +\def\x{% + \parindent0pt + \def\par{\@@par\leavevmode\null}% + \let\do\do@noligs \verbatim@nolig@list + \let\do\@makeother \dospecials + \catcode`\@ 14 \makestarlowast + \ttfamily \scriptsize\baselineskip 8pt \obeylines \@vobeyspaces + \catcode`\|\active + \lccode`\~`\|\lowercase{\let~\egroup}}% +\global\setbox\codebox \vbox\bgroup\x +\def\DimToNum #1{\the\numexpr \dimexpr#1\relax/10000\relax } % no need to be more precise! +\def\FA #1#2{\xintDSH {-4}{\xintQuo {\xintiPow {\DimToNum {#2}}{3}}{\xintiSqr {\DimToNum{#1}}}}} +\def\FB #1#2{\xintDSH {-4}{\xintiSqrt {\xintiMul {\DimToNum {#2}}{\DimToNum{#1}}}}} +\def\Ratio #1#2{\xintTrunc {2}{\DimToNum {#2}/\DimToNum{#1}}} +\begingroup +\xintFor #1 in {\xintdimensions [0pt+.25pt]} \do + {\ifdim #1>2cm \expandafter\xintBreakFor\fi + \color [rgb]{\Ratio {2cm}{#1},0,0}% + \vrule width .25pt height \FB {2cm}{#1}sp depth -\FA {2cm}{#1}sp + }% end of For iterated text +\endgroup +|% +\endgroup +\footnote{to tell the whole truth we cheated and divided by |10| the + computation time through using the following definitions, together with a + horizontal step of |.25pt| rather than |.1pt|. The displayed original code + would make the slowest computation of all those done in this document using + the \xintname bundle macros!\par\smallskip + \noindent\box \codebox\par } -\csa{xintZapFirstSpaces}\marg{stuff} 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. +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). -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 or any other alteration is - done to the input.} +\begingroup\small +\noindent\dverb|@ +\xintFor #1 in {\xintrationals [10/21+1/21]} \do +{#1=\xintifInt {#1} + {\textcolor{blue}{\xintTrunc{10}{#1}}} + {\xintTrunc{10}{#1}}% in blue if an integer + \xintifGt {#1}{1.123}{\xintBreakFor}{, }% +}| -\TeX's input scanner already converts consecutive blanks into single space -tokens, but \csa{xintZapFirstSpaces} handles successfully also inputs with -consecutive multiple space tokens. -However, it is assumed that \meta{stuff} does not contain (except in braced -sub-material) space tokens of character code distinct from @32@. +\smallskip +\centeredline{\parbox{\dimexpr\linewidth-3em}{\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 -It expands in two steps, and if the goal is to apply it to the -expansion text of |\x| to define |\y|, then one should do: -|\expandafter\def\expandafter\y\expandafter - {\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}|. +\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 zeros. -Other use case: inside a macro as |\edef\x{\xintZapFirstSpaces {#1}}| assuming -naturally that |#1| is compatible with such an |\edef| once the leading spaces -have been stripped. +\begingroup\footnotesize \def\MacroFont {\ttfamily\relax} +\noindent\dverb|@ +\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 -\begingroup -\def\x { \a { \X } { \b \Y } } -\centeredline{|\xintZapFirstSpaces { \a { \X } { \b \Y } }->|% -\digitstt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}}+++} -\endgroup +\centeredline{\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}{, }% + }}} -\medskip +\smallskip -\noindent\csbxint{ZapLastSpaces}\marg{stuff} 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. +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 behavior 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 +\endgroup -% ATTENTION à l'\ignorespaces fait par \color! -\begingroup -\def\x { \a { \X } { \b \Y } } -\centeredline{|\xintZapLastSpaces { \a { \X } { \b \Y } }->|% -\digitstt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzaplastspaces\expandafter{\x}}}+++} -\endgroup -\medskip +\subsection{Another table of primes}\label{ssec:primesII} -\noindent\csbxint{ZapSpaces}\marg{stuff} 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. +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{xintSeq}, 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. -\begingroup -\def\x { \a { \X } { \b \Y } } -\centeredline{|\xintZapSpaces { \a { \X } { \b \Y } }->|% -\digitstt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapspaces\expandafter{\x}}}+++} -\endgroup +\def\IsPrime #1#2% +{\edef\TheNumber {\the\numexpr #2}% positive integer + \ifnumodd {\TheNumber} + {\ifnumgreater {\TheNumber}{1} + {\edef\ItsSquareRoot{\xintiSqrt \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}}}% +}% -\medskip +\dverb|@ +\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{\xintiSqrt \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}}}% +}| -\noindent\csbxint{ZapSpacesB}\marg{stuff} 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. +%\newcounter{primecount} +%\newcounter{cellcount} +\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*} -\begingroup -\def\x { \a { \X } { \b \Y } } -\centeredline{|\xintZapSpacesB { \a { \X } { \b \Y } }->|% -\digitstt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++} -\def\x { { \a { \X } { \b \Y } } } -\centeredline{|\xintZapSpacesB { { \a { \X } { \b \Y } } }->|% -\digitstt{\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). +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 appears +\vpageref[above]{primes}): +\dverb?@ +\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*}? -\subsection{\csbh{xintCSVtoList}} -\label{xintCSVtoList} -\label{xintCSVtoListNoExpand} +\subsection{\csbh{xintForpair}, \csbh{xintForthree}, \csbh{xintForfour}}\label{xintForpair}\label{xintForthree}\label{xintForfour} +{\small New in |1.09c|. The \csa{xintifForFirst} + |1.09e| mechanism was missing and has been added for |1.09f|. The |1.09f| + version handles better spaces and admits all (consecutive) macro + parameters.\par} -{\small New with release |1.06|. Starting with |1.09f|, \fbox{\emph{removes - spaces around commas}!}\par} +The syntax 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. +% +\dverb|@ +\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}|% +\centeredline{\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}} -\csa{xintCSVtoList}|{a,b,c...,z}| 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 command 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. +\smallskip Only |#1#2|, |#2#3|, |#3#4|, \dots, |#8#9| are valid (no error check +is done on the input syntax, |#1#3| or similar all end up in errors). +One can nest with \csbxint{For}, for disjoint sets of macro parameters. There is +also \csa{xintForthree} (from |#1#2#3| to |#7#8#9|) and \csa{xintForfour} (from +|#1#2#3#4| to |#6#7#8#9|). -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[sec: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 disappear). The macro \csbxint{CSVtoListNoExpand} does the same job without -the initial expansion of the list argument. +% These three macros |\xintForpair|, |\xintForthree| and |\xintForfour| are to +% be considered in experimental status, and may be removed, replaced or +% substantially modified at some later stage. -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). +\subsection{\csbh{xintAssign}}\label{xintAssign} -Contiguous spaces, tab characters, or other blanc spaces (empty lines not -allowed) 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.} +\csa{xintAssign}\meta{braced things}\csa{to}% +\meta{as many cs as they are things} defines (without checking if +something gets overwritten) the control sequences on the right of +\csa{to} to be the complete expansions of the successive braced things found on +the left of \csa{to}. -\begingroup +A `full' expansion is first applied first to the +material in front of \csa{xintAssign}, which may thus be a macro expanding to a +list of braced items. -\edef\X{\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , { {x , - y} } }} +\xintAssign\xintiPow {7}{13}\to\SevenToThePowerThirteen +\xintAssign\xintDivision{1000000000000}{133333333}\to\Q\R -\centeredline{|\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , - { {x , y} } }|} -\centeredline{|->|% -{\makeatletter\digitstt{\expandafter\strip@prefix\meaning\X}}} +Special case: 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 |\edef| as the +complete expansion of the material between \csa{xintAssign} and \csa{to}. +\centeredline{|\xintAssign\xintDivision{1000000000000}{133333333}\to\Q\R|} +\centeredline{|\meaning\Q: |\digitstt{\meaning\Q}, |\meaning\R:| + \digitstt{\meaning\R}} \centeredline{|\xintAssign\xintiPow + {7}{13}\to\SevenToThePowerThirteen|} +\centeredline{|\SevenToThePowerThirteen|\digitstt{=\SevenToThePowerThirteen}} +\centeredline{(same as |\edef\SevenToThePowerThirteen{\xintiPow {7}{13}}|)} This +macro uses various \csa{edef}'s, thus is incompatible with expansion-only +contexts. -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{\csbh{xintAssignArray}}\label{xintAssignArray} -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. +{\small Changed in release |1.06| to let the defined macro pass its + argument through a |\numexpr...\relax|.\par} -From the rules above: for an empty argument (only spaces, no braces, no comma) -the output is -\digitstt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist { }}} -(a list with one empty item), -for ``|{}|'' the output is -\digitstt{\expandafter\detokenize\expandafter - {\romannumeral0\xintcsvtolist { {} }}} -(again a list with one empty item, the braces were removed), -for ``|{ }|'' the output is -\digitstt{\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 -\digitstt{\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 -\digitstt{\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 -\digitstt{\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). +\xintAssignArray\xintBezout {1000}{113}\to\Bez -\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}} +\csa{xintAssignArray}\meta{braced things}\csa{to}\csa{myArray} 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 +completely expanded |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}|. +\centeredline{|\xintAssignArray\xintBezout {1000}{113}\to\Bez|} will set +|\Bez{0}| to \digitstt{\Bez0}, |\Bez{1}| to \digitstt{\Bez1}, |\Bez{2}| to +\digitstt{\Bez2}, |\Bez{3}| to \digitstt{\Bez3}, |\Bez{4}| to \digitstt{\Bez4}, +and |\Bez{5}| to \digitstt{\Bez5}: +\digitstt{(\Bez3)${}\times{}$\Bez1${}-{}$(\Bez4)${}\times{}$\Bez2${}={}$\Bez5.} +This macro is incompatible with expansion-only contexts. -\centeredline{|\def\y{ \a,\b,\c,\d,\e} \xintCSVtoList\y->|% - {\makeatletter\digitstt{\expandafter\strip@prefix\meaning\Y}}} -\centeredline{|\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} \centeredline -{|\xintCSVtoList\t->|\makeatletter\digitstt{\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: -\centeredline{|\expandafter\xintCSVtoListNoExpand\expandafter {\y}|} Else, we -may have direct use: \centeredline{|\xintCSVtoListNoExpand - {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} -\centeredline{|->|\digitstt{\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). The original non-stripping -macro is available as \csa{xintCSVtoListNonStripped}. There is also -\csa{xintCSVtoListNonStrippedNoExpand}. -\endgroup +\subsection{\csbh{xintRelaxArray}}\label{xintRelaxArray} -\subsection{\csbh{xintNthElt}}\label{xintNthElt} +\csa{xintRelaxArray}\csa{myArray} sets to \csa{relax} all +macros which were defined by the previous \csa{xintAssignArray} +with \csa{myArray} as array name. -{\small New in release |1.06|. With |1.09b| negative indices count from the tail.\par} - -\def\macro #1{\the\numexpr 9-#1\relax} - -\csa{xintNthElt\x}\marg{list} gets (expandably) the |x|th element of the -\meta{list}, which may be a macro: the list argument is first expanded. The -seeked element is returned with one pair of braces removed (if initially -present). -\centeredline{|\xintNthElt {3}{{agh}\u{zzz}\v{Z}}| is - \texttt{\xintNthElt {3}{{agh}\u{zzz}\v{Z}}}}\centeredline{|\xintNthElt - {37}{\xintFac {100}}|\digitstt{=\xintNthElt {37}{\xintFac {100}}} is the - thirty-seventh digit of @100!@.} \centeredline{|\xintNthElt {10}{\xintFtoCv - {566827/208524}}|\digitstt{=\xintNthElt {10}{\xintFtoCv {566827/208524}}}} -is the tenth convergent of @566827/208524@ (uses \xintcfracname package). -\centeredline{|\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% - \digitstt{=\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}}% -\centeredline{|\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% - \digitstt{=\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} -\centeredline{|\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% - \digitstt{=\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} 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. - -If |x<0|, the macro returns the \texttt{|x|}th element from the end of the list. - \centeredline{|\xintNthElt - {-5}{{{agh}}\u{zzz}\v{Z}}| is \texttt{\expandafter\expandafter\expandafter - \detokenize - \expandafter\expandafter\expandafter{\xintNthElt - {-5}{{{agh}}\u{zzz}\v{Z}}}}} - - -The macro -\csa{xintNthEltNoExpand} 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{The Quick Sort algorithm illustrated}\label{ssec:quicksort} -In cases where |x| is larger (in absolute value) than the length of the list -then |\xintNthElt| returns nothing. +First a completely expandable macro which sorts a list of numbers. The |\QSfull| +macro expands its list argument, which may thus be a macro; its items must +expand to possibly big integers (or also decimal numbers or fractions if using +\xintfracname), but if an item is expressed as a computation, this computation +will be redone each time the item is considered! If the numbers have many digits +(i.e. hundreds of digits...), the expansion of |\QSfull| is fastest if each +number, rather than being explicitely given, is represented as a single token +which expands to it in one step. -\subsection{\csbh{xintListWithSep}}\label{xintListWithSep} +If the interest is only in \TeX{} integers, then one should replace the macros +|\QSMore|, |QSEqual|, |QSLess| with versions using the +\href{http://ctan.org/pkg/etoolbox}{etoolbox} (\LaTeX{} only) |\ifnumgreater|, +|\ifnumequal| and |\ifnumless| conditionals rather than \csbxint{ifGt}, +\csbxint{ifEq}, \csbxint{ifLt}. -{\small New with release |1.04|.\par} +\begingroup\makeatletter\let\check@percent\relax +\def\MacroFont{\small\baselineskip12pt \ttfamily } +\begin{verbatim} +% THE QUICK SORT ALGORITHM EXPANDABLY +\input xintfrac.sty +% HELPER COMPARISON MACROS +\def\QSMore #1#2{\xintifGt {#2}{#1}{{#2}}{ }} +% the spaces are there to stop the \romannumeral-`0 originating +% in \xintapplyunbraced when it applies a macro to an item +\def\QSEqual #1#2{\xintifEq {#2}{#1}{{#2}}{ }} +\def\QSLess #1#2{\xintifLt {#2}{#1}{{#2}}{ }} +% +\makeatletter +\def\QSfull {\romannumeral0\qsfull } +\def\qsfull #1{\expandafter\qsfull@a\expandafter{\romannumeral-`0#1}} +\def\qsfull@a #1{\expandafter\qsfull@b\expandafter {\xintLength {#1}}{#1}} +\def\qsfull@b #1{\ifcase #1 + \expandafter\qsfull@empty + \or\expandafter\qsfull@single + \else\expandafter\qsfull@c + \fi +}% +\def\qsfull@empty #1{ } % the space stops the \QSfull \romannumeral0 +\def\qsfull@single #1{ #1} +% for simplicity of implementation, we pick up the first item as pivot +\def\qsfull@c #1{\qsfull@ci #1\undef {#1}} +\def\qsfull@ci #1#2\undef {\qsfull@d {#1}}% #3 is the list, #1 its first item +\def\qsfull@d #1#2{\expandafter\qsfull@e\expandafter + {\romannumeral0\qsfull + {\xintApplyUnbraced {\QSMore {#1}}{#2}}}% + {\romannumeral0\xintapplyunbraced {\QSEqual {#1}}{#2}}% + {\romannumeral0\qsfull + {\xintApplyUnbraced {\QSLess {#1}}{#2}}}% +}% +\def\qsfull@e #1#2#3{\expandafter\qsfull@f\expandafter {#2}{#3}{#1}}% +\def\qsfull@f #1#2#3{\expandafter\space #2#1#3} +\makeatother +% EXAMPLE +\edef\z {\QSfull {{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}}} +\tt\meaning\z +\def\a {3.123456789123456789}\def\b {3.123456789123456788} +\def\c {3.123456789123456790}\def\d {3.123456789123456787} +\expandafter\def\expandafter\z\expandafter + {\romannumeral0\qsfull {{\a}\b\c\d}}% \a is braced to not be expanded +\meaning\z +\end{verbatim} -\def\macro #1{\the\numexpr 9-#1\relax} +% THE QUICK SORT ALGORITHM EXPANDABLY +\def\QSMore #1#2{\xintifGt {#2}{#1}{{#2}}{ }} +% the spaces stop the \romannumeral-`0 done by \xintapplyunbraced each time +% it applies its macro argument to an item +\def\QSEqual #1#2{\xintifEq {#2}{#1}{{#2}}{ }} +\def\QSLess #1#2{\xintifLt {#2}{#1}{{#2}}{ }} +% +\def\QSfull {\romannumeral0\qsfull } +\def\qsfull #1{\expandafter\qsfull@a\expandafter{\romannumeral-`0#1}} +\def\qsfull@a #1{\expandafter\qsfull@b\expandafter {\xintLength {#1}}{#1}} +\def\qsfull@b #1{\ifcase #1 + \expandafter\qsfull@empty + \or\expandafter\qsfull@single + \else\expandafter\qsfull@c + \fi +}% +\def\qsfull@empty #1{ } % the space stops the \QSfull \romannumeral0 +\def\qsfull@single #1{ #1} +\def\qsfull@c #1{\qsfull@ci #1\undef {#1}} % we pick up the first as Pivot +\def\qsfull@ci #1#2\undef {\qsfull@d {#1}} +\def\qsfull@d #1#2{\expandafter\qsfull@e\expandafter + {\romannumeral0\qsfull + {\xintApplyUnbraced {\QSMore {#1}}{#2}}}% + {\romannumeral0\xintapplyunbraced {\QSEqual {#1}}{#2}}% + {\romannumeral0\qsfull + {\xintApplyUnbraced {\QSLess {#1}}{#2}}}% +}% +\def\qsfull@e #1#2#3{\expandafter\qsfull@f\expandafter {#2}{#3}{#1}}% +\def\qsfull@f #1#2#3{\expandafter\space #2#1#3} +\makeatother +% EXAMPLE +\edef\z {\QSfull {{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}}} +\noindent Output:\par +\texttt{\printnumber{\meaning\z}} -\csa{xintListWithSep}|{sep}|\marg{list} inserts the given separator |sep| -in-between all elements of the given list: this separator may be a macro but -will not be expanded. The second argument also may be itself a macro: it is -expanded as usual, \emph{i.e.} fully for what comes first. Applying -\csa{xintListWithSep} removes one level of top braces to each list constituent. -An empty input gives an empty output, a singleton gives a singleton, the -separator is used starting with at least two elements. Using an empty separator -has the net effect of removing one-level of brace pairs from each ot the -top-level braced material constituting the \meta{list} (in such cases the new -list may thus be longer than the original). -\centeredline{|\xintListWithSep{:}{\xintFac - {20}}|\digitstt{=\xintListWithSep{:}{\xintFac {20}}}} +\def\a {3.123456789123456789}\def\b {3.123456789123456788} +\def\c {3.123456789123456790}\def\d {3.123456789123456787} +\expandafter\def\expandafter\z\expandafter + {\romannumeral0\qsfull {{\a}\b\c\d}}% \a is braced to not be expanded +\texttt{\printnumber{\meaning\z}} +\endgroup -The macro \csa{xintListWithSepNoExpand} does the same -job without the initial expansion. -\subsection{\csbh{xintApply}}\label{xintApply} -{\small New with release |1.04|.\par} +We then turn to a graphical illustration of the algorithm. For simplicity the +pivot is always chosen to be the first list item. We also show later how to +illustrate the variant which picks up the last item of each unsorted +chunk as pivot. -\def\macro #1{\the\numexpr 9-#1\relax} +\begingroup +\makeatletter +\let\check@percent\relax +% il utilise MacroFont +\def\MacroFont{\small\baselineskip 12pt \ttfamily } +\begin{verbatim} +\input xintfrac.sty % if Plain TeX +% +\definecolor{LEFT}{RGB}{216,195,88} +\definecolor{RIGHT}{RGB}{208,231,153} +\definecolor{INERT}{RGB}{199,200,194} +\definecolor{PIVOT}{RGB}{109,8,57} +% +\def\QSMore #1#2{\xintifGt {#2}{#1}{{#2}}{ }}% space will be gobbled +\def\QSEqual #1#2{\xintifEq {#2}{#1}{{#2}}{ }} +\def\QSLess #1#2{\xintifLt {#2}{#1}{{#2}}{ }} +% +\makeatletter +\def\QS@a #1{\expandafter \QS@b \expandafter {\xintLength {#1}}{#1}} +\def\QS@b #1{\ifcase #1 + \expandafter\QS@empty + \or\expandafter\QS@single + \else\expandafter\QS@c + \fi +}% +\def\QS@empty #1{} +\def\QS@single #1{\QSIr {#1}} +\def\QS@c #1{\QS@d #1!{#1}} % we pick up the first as pivot. +\def\QS@d #1#2!{\QS@e {#1}}% #1 = first element, #3 = list +\def\QS@e #1#2{\expandafter\QS@f\expandafter + {\romannumeral0\xintapplyunbraced {\QSMore {#1}}{#2}}% + {\romannumeral0\xintapplyunbraced {\QSEqual {#1}}{#2}}% + {\romannumeral0\xintapplyunbraced {\QSLess {#1}}{#2}}% +}% +\def\QS@f #1#2#3{\expandafter\QS@g\expandafter {#2}{#3}{#1}}% +% Here \QSLr, \QSIr, \QSr have been let to \relax, so expansion stops. +% #2= elements < pivot, #1 = elements = pivot, #3 = elements > pivot +\def\QS@g #1#2#3{\QSLr {#2}\QSIr {#1}\QSRr {#3}}% +% +\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{% + \xintFor* ##1 in {#1} \do + {\xintifForFirst {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}% +} +\def\DecoRIGHTwithPivot #1{% + \xintFor* ##1 in {#1} \do + {\xintifForFirst {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}% +} +% +\def\QSinitialize #1{\def\QS@list{\QSRr {#1}}% + \let\QSRr\DecoRIGHT +% \QS@list \par +\par\centerline{\QS@list} +} +\def\QSoneStep {\let\QSLr\DecoLEFTwithPivot + \let\QSIr\DecoINERT + \let\QSRr\DecoRIGHTwithPivot +% \QS@list +\centerline{\QS@list} +% \par + \def\QSLr {\noexpand\QS@a}% + \let\QSIr\relax + \def\QSRr {\noexpand\QS@a}% + \edef\QS@list{\QS@list}% + \let\QSLr\relax + \let\QSRr\relax + \edef\QS@list{\QS@list}% + \let\QSLr\DecoLEFT + \let\QSIr\DecoINERT + \let\QSRr\DecoRIGHT +% \QS@list +\centerline{\QS@list} +% \par +} +\begingroup\offinterlineskip +\small +\QSinitialize {{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}} +\QSoneStep +\QSoneStep +\QSoneStep +\QSoneStep +\QSoneStep +\endgroup +\end{verbatim} -\csa{xintApply}|{\macro}|\marg{list} expandably applies the one parameter -command |\macro| to each item in the \meta{list} given as second argument and -return a new list with these outputs: each item is given one after the other as -parameter to |\macro| which is expanded (as usual, \emph{i.e.} fully for what -comes first), and the result is braced. On output, a new list with these braced -results (if |\macro| is defined to start with a space, the space will be gobbled -and the |\macro| will not be executed; |\macro| -is allowed to have its own arguments, the list items will serve as last -arguments to the macro.). +\def\QSMore #1#2{\xintifGt {#2}{#1}{{#2}}{ }}% space will be gobbled +\def\QSEqual #1#2{\xintifEq {#2}{#1}{{#2}}{ }} +\def\QSLess #1#2{\xintifLt {#2}{#1}{{#2}}{ }} +% +\def\QS@a #1{\expandafter \QS@b \expandafter {\xintLength {#1}}{#1}} +\def\QS@b #1{\ifcase #1 + \expandafter\QS@empty + \or\expandafter\QS@single + \else\expandafter\QS@c + \fi +}% +\def\QS@empty #1{} +\def\QS@single #1{\QSIr {#1}} +\def\QS@c #1{\QS@d #1!{#1}} % we pick up the first as pivot. +\def\QS@d #1#2!{\QS@e {#1}}% #1 = first element, #3 = list +\def\QS@e #1#2{\expandafter\QS@f\expandafter + {\romannumeral0\xintapplyunbraced {\QSMore {#1}}{#2}}% + {\romannumeral0\xintapplyunbraced {\QSEqual {#1}}{#2}}% + {\romannumeral0\xintapplyunbraced {\QSLess {#1}}{#2}}% +}% +\def\QS@f #1#2#3{\expandafter\QS@g\expandafter {#2}{#3}{#1}}% +% #2= elements < pivot, #1 = elements = pivot, #3 = elements > pivot +% Here \QSLr, \QSIr, \QSr have been let to \relax, so expansion stops. +\def\QS@g #1#2#3{\QSLr {#2}\QSIr {#1}\QSRr {#3}}% +% +\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{% + \xintFor* ##1 in {#1} \do + {\xintifForFirst {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}% +} +\def\DecoRIGHTwithPivot #1{% + \xintFor* ##1 in {#1} \do + {\xintifForFirst {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}% +} +% +\def\QSinitialize #1{\def\QS@list{\QSRr {#1}}% + \let\QSRr\DecoRIGHT +% \QS@list \par +\par\centerline{\QS@list} +} +\def\QSoneStep {\let\QSLr\DecoLEFTwithPivot + \let\QSIr\DecoINERT + \let\QSRr\DecoRIGHTwithPivot +% \QS@list +\centerline{\QS@list} +% \par + \def\QSLr {\noexpand\QS@a}% + \let\QSIr\relax + \def\QSRr {\noexpand\QS@a}% + \edef\QS@list{\QS@list}% + \let\QSLr\relax + \let\QSRr\relax + \edef\QS@list{\QS@list}% + \let\QSLr\DecoLEFT + \let\QSIr\DecoINERT + \let\QSRr\DecoRIGHT +% \QS@list +\centerline{\QS@list} +% \par +} -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| is not necessarily compatible with -expansion only contexts: |\xintApply| will try to expand it, but the expansion -may remain partial. +\begingroup\offinterlineskip +\small +\QSinitialize {{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}} +\QSoneStep +\QSoneStep +\QSoneStep +\QSoneStep +\QSoneStep +\endgroup -The \meta{list} may -itself be some macro expanding (in the previously described way) to the list of -tokens to which the command |\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. \centeredline{|\def\macro #1{\the\numexpr - 9-#1\relax}|} \centeredline{|\xintApply\macro{\xintFac - {20}}|\digitstt{=\xintApply\macro{\xintFac {20}}}} -The macro -\csa{xintApplyNoExpand} does the same job without the first initial expansion -which gave the \meta{list} of braced tokens to which |\macro| is applied. +If one wants rather to have the pivot from the end of the yet to sort chunks, +then one should use the following variants: +\begin{verbatim} +\def\QS@c #1{\expandafter\QS@e\expandafter + {\romannumeral0\xintnthelt {-1}{#1}}{#1}% +}% +\def\DecoLEFTwithPivot #1{% + \xintFor* ##1 in {#1} \do + {\xintifForLast {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}% +} +\def\DecoRIGHTwithPivot #1{% + \xintFor* ##1 in {#1} \do + {\xintifForLast {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}% +} +\def\QSinitialize #1{\def\QS@list{\QSLr {#1}}% + \let\QSLr\DecoLEFT +% \QS@list \par +\par\centerline{\QS@list} +} +\end{verbatim} +\def\QS@c #1{\expandafter\QS@e\expandafter + {\romannumeral0\xintnthelt {-1}{#1}}{#1}% +}% +\def\DecoLEFTwithPivot #1{% + \xintFor* ##1 in {#1} \do + {\xintifForLast {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}% +} +\def\DecoRIGHTwithPivot #1{% + \xintFor* ##1 in {#1} \do + {\xintifForLast {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}% +} +\def\QSinitialize #1{\def\QS@list{\QSLr {#1}}% + \let\QSLr\DecoLEFT +% \QS@list \par +\par\centerline{\QS@list} +} +\begingroup\offinterlineskip +\small +\QSinitialize {{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}} +\QSoneStep +\QSoneStep +\QSoneStep +\QSoneStep +\QSoneStep +\QSoneStep +\QSoneStep +\QSoneStep +\QSoneStep +\QSoneStep +\endgroup -\subsection{\csbh{xintApplyUnbraced}}\label{xintApplyUnbraced} +\endgroup -{\small New in release |1.06b|.\par} +It is possible to modify this code to let it do \csa{QSonestep} repeatedly and +stop automatically when the sort is finished. -\def\macro #1{\expandafter\def\csname myself#1\endcsname {#1}} -\xintApplyUnbraced\macro{{elta}{eltb}{eltc}} +\section{Commands of the \xintname package} +\label{sec:xint} -\csa{xintApplyUnbraced}|{\macro}|\marg{list} 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 -\centeredline{|\xintListWithSep {}{\xintApply {\macro}|\marg{list}|}|} -This is useful for preparing a macro which will itself define some other macros -or make assignments. -\lverb|& -$ $ $ $ \def\macro #1{\expandafter\def\csname myself#1\endcsname {#1}}$\ -$null$ $ $ $ \xintApplyUnbraced\macro{{elta}{eltb}{eltc}}$\ -$null$ $ $ $ \meaning\myselfelta:$ $ $meaning$myselfelta$\ -$null$ $ $ $ \meaning\myselfeltb:$ $ $meaning$myselfeltb$\ -$null$ $ $ $ \meaning\myselfeltc:$ $ $meaning$myselfeltc -| -The macro \csa{xintApplyUnbracedNoExpand} does the same job without the first -initial expansion which gave the \meta{list} of braced tokens to which -|\macro| -is applied. +\def\n{\string{N\string}} +\def\m{\string{M\string}} +\def\x{\string{x\string}} -\subsection{\csbh{xintSeq}}\label{xintSeq} -{\small New with release |1.09c|.\par} +In the description of the macros \texttt{\n} (or also \texttt{\m}) stands +(except if mentioned otherwise) for a (long) number within braces or for a +control sequence possibly within braces and \hyperref[sec:expansions]{\fexpan + ding} to such a number +(without the braces!), or for material within braces which \fexpan ds to such +a number, as is acceptable on input by the \csbxint{Num} macro: a sequence of +plus and minus signs, followed by some string of zeros, followed by digits. -\csa{xintSeq}|[d]{x}{y}| 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|. +The letter \texttt{x} stands for something which will be inserted in-between a +|\numexpr| and a |\relax|. It will thus be completely expanded and must give an +integer obeying the \TeX{} bounds. Thus, it may be for example a count register, +or itself a \csa{numexpr} expression, or just a number written explicitely with +digits or something like |4*\count 255 + 17|, etc... +For the rules regarding direct use of count registers or \csa{numexpr} +expression, in the argument to the package macros, see the +\hyperlink{useofcount}{use of count section} in \autoref{sec:inputs}. -The current implementation is only for (short) integers; possibly, a future -variant could allow big integers and fractions, although one already has -access to similar -functionality using \csbxint{Apply} to get any arithmetic sequence of long -integers. Currently thus, |x| and |y| are expanded inside a -|\numexpr| so they may be count registers or a \LaTeX{} |\value{countername}|, -or arithmetic with such things. +Some of these macros are extended by \xintfracname to accept fractions on input, +and, generally, to output a fraction. But this means that additions, +subtractions, multiplications output fractions and not integers; to guarantee +the integer format on output when the inputs are integers, the original +integer-only macros \csa{xintAdd}, \csa{xintSub}, \csa{xintMul} remain available +under the names \csa{xintiAdd}, \csa{xintiSub}, \csa{xintiMul}. Even the +original integer-only macros may now accept fractions on input as long as they +are integers in disguise; they still produce on output integers without any +forward slash mark nor trailing |[n]|. On the other hand macros such as +|\xintAdd| will output fractions |A/B[n]|, with |B| present even if its value is +one. To remove this unit denominator and convert the |[n]| part into explicit +zeros, one has \csbxint{Num} (if one is certain to deal with an integer; see +also \csbxint{PRaw}). This is mandatory when the computation result is fetched +into a context where \TeX{} expects a number (assuming it does not exceed +@2^31@). See the also the \xintfracname \hyperref[sec:frac]{documentation} +for more information on how macros of \xintname are modified after loading +\xintfracname (or \xintexprname). -\centeredline{|\xintListWithSep{,\hskip2pt - plus 1pt minus 1pt }{\xintSeq {12}{-25}}|} -\noindent\digitstt{\xintListWithSep{,\hskip2pt plus 1pt minus 1pt }{\xintSeq - {12}{-25}}} -\centeredline{|\xintiSum{\xintSeq [3]{1}{1000}}|\digitstt{=\xintiSum{\xintSeq [3]{1}{1000}}}} -\textbf{Important:} for reasons of efficiency, this macro, when not given the -optional argument |d|, works backwards, leaving in the token stream the already -constructed integers, from the tail down (or up). But this will provoke a -failure of \IMPORTANT{} the |tex| run if the number of such items exceeds the -input stack -limit; on my installation this limit is at @5000@. +% Package \xintname also provides some general macro programming or token +% manipulation utilities (expandable as well as non-expandable), which are +% described in the next section (\autoref{sec:tools}). -However, when given the optional argument |d| (which may be @+1@ or -@-1@), the macro proceeds differently and does not put stress on the input stack -(but is significantly slower for sequences with thousands of integers, -especially if they are somewhat big). For -example: |\xintSeq [1]{0}{5000}| works and |\xintiSum{\xintSeq [1]{0}{5000}}| -returns the correct value \digitstt{\xintHalf{\xintiMul{5000}{5001}}}. +\localtableofcontents +\subsection{\csbh{xintRev}} \label{xintRev} -\subsection{Completely expandable prime test}\label{ssec:primesI} +\csa{xintRev\n} will revert the order of the digits of the number, +keeping the optional sign. Leading zeros +resulting from the operation are not removed (see the +\csa{xintNum} macro for this). This macro and all other +macros dealing with numbers first expand `fully' their arguments. +\centeredline{|\xintRev{-123000}|\digitstt{=\xintRev{-123000}}} +\centeredline{|\xintNum{\xintRev{-123000}}|% + \digitstt{=\xintNum{\xintRev{-123000}}}} -Let us now construct a completely expandable macro which returns @1@ if its -given input is prime and @0@ if not: -\dverb|@ -\def\remainder #1#2{\the\numexpr #1-(#1/#2)*#2\relax } -\def\IsPrime #1{\xintANDof - {\xintApply {\remainder {#1}}{\xintSeq {2}{\xintiSqrt{#1}}}}} -| -This uses \csbxint{iSqrt} and assumes its input is at least @5@. Rather than -\xintname's own \csbxint{Rem} 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: -\dverb|@ -\def\IsPrime #1% - {\xintifOdd {#1} - {\xintANDof % odd case - {\xintApply {\remainder {#1}} - {\xintSeq [2]{3}{\xintiSqrt{#1}}}% - }% - } - {\xintifEq {#1}{2}{1}{0}}% - } -| -We used the \xintname provided expandable tests (on big integers or fractions) -to maintain the complete expandability of |\IsPrime| in a strong -sense\footnote{\label{fn:fullexp}technically, prefixing it with - \csa{romannumeral-`0} must expand it completely; this is the case of all - \xintname expandable macros, and in turn the arguments must be of this - type.}. +\subsection{\csbh{xintLen}}\label{xintiLen} -Our integers are short, but without -|\expandafter|'s with \makeatletter|\@firstoftwo|\catcode`@ \active, 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: -\dverb|@ -\def\IsPrime #1% - {\ifnumodd {#1} - {\xintANDof % odd case - {\xintApply {\remainder {#1}}{\xintSeq [2]{3}{\xintiSqrt{#1}}}}} - {\ifnumequal {#1}{2}{1}{0}}} -| +\csa{xintLen\n} returns the length of the number, not counting the sign. +\centeredline{|\xintLen{-12345678901234567890123456789}|\digitstt + {=\xintLen{-12345678901234567890123456789}}} Extended by \xintfracname to +fractions: 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). +\centeredline{|\xintLen{-1e3/5.425}|\digitstt + {=\xintLen{-1e3/5.425}}} +The length is computed on the |A/B[n]| which would have been returned by +\csbxint{Raw}: |\xintRaw {-1e3/5.425}|\digitstt{=\xintRaw {-1e3/5.425}}. -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: -% -\dverb|@ -\def\IsNotDivisibleBy #1#2% - {\ifnum\numexpr #1-(#1/#2)*#2=0 \expandafter 0\else \expandafter1\fi} -|% -% -where the |\expandafter|'s are crucial for this macro to be completely -expandable in the restricted sense mentioned in \autoref{fn:fullexp} which we -want for applying confidently \csbxint{ANDof}. Anyhow, now that we have loaded -\href{http://ctan.org/pkg/etoolbox}{etoolbox}, we might as well use: -\dverb|@ -\newcommand{\IsNotDivisibleBy}[2]{\ifnumequal{#1-(#1/#2)*#2}{0}{0}{1}} -|% -Let us enhance our prime macro to work also on the small primes: -\dverb|@ -\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}{\xintiSqrt{#1}}}}% - }}% END OF THE ODD BRANCH - {\ifnumequal {#1}{2}{1}{0}}% END OF THE EVEN BRANCH -} -|% -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. We did generate via \csbxint{Seq} too many -divisors though; if we really wanted to optimize even further it would be -reasonable to drop the requirement of complete expandability and use the tools -provided by -the \csbxint{For} loop. +Let's point out that the whole thing should sum up to +less than circa @2^{31}@, but this is a bit theoretical. +|\xintLen| is only for numbers or fractions. See \csbxint{Length} for counting +tokens (or rather braced groups), more generally. -Let us construct 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. 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. -% -\dverb?@ -\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. -?% -% -We had to be careful to use the optional argument |[1]| to \csbxint{Seq} in -this last row to not generate a decreasing sequence from |1| to |0|, but an -empty sequence when the row turns out to already have all its cells. -% -\newcommand{\IsNotDivisibleBy}[2]{\ifnumequal{#1-(#1/#2)*#2}{0}{0}{1}} +\subsection{\csbh{xintDigitsOf}}\label{xintDigitsOf} -\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}{\xintiSqrt{#1}}}}% - }}% END OF THE ODD BRANCH - {\ifnumequal {#1}{2}{1}{0}}% END OF THE EVEN BRANCH -} +This is a synonym for \csbxint{AssignArray}, 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\xintiPow {7}{500}\to\digits +\centeredline{|\xintDigitsOf\xintiPow {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 -\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 - \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{\csbh{xintNum}}\label{xintiNum} +\csa{xintNum\n} removes chains of plus or minus signs, followed by zeros. +\centeredline{|\xintNum{+---++----+--000000000367941789479}|\digitstt + {=\xintNum{+---++----+--000000000367941789479}}} Extended by \xintfracname to +accept also a fraction on input, as long as it reduces to an integer after +division of the numerator by the denominator. +\centeredline{|\xintNum{123.48/-0.03}|\digitstt{=\xintNum{123.48/-0.03}}} -\begin{framed} - The next utilities are not compatible with expansion-only context. -\end{framed} -\subsection{\csbh{xintApplyInline}}\label{xintApplyInline} +\subsection{\csbh{xintSgn}}\label{xintiSgn} -{\small |1.09a|, enhanced in |1.09c| to be usable within alignments, and - corrected in |1.09d| for a problem related to spaces at the very end of the - list parameter.\par} +\csa{xintSgn\n} returns 1 if the number is positive, 0 if it is +zero and -1 if it is negative. Extended by \xintfracname to fractions. -\csa{xintApplyInline}|{\macro}|\marg{list} 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. +\subsection{\csbh{xintOpp}}\label{xintiOpp} -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. +\csa{xintOpp\n} returns the opposite |-N| of the number |N|. +Extended by \xintfracname to fractions. -\dverb|@ -\def\Macro #1{\advance\cnta #1 , \the\cnta} -\cnta 0 -0\xintApplyInline\Macro {3141592653}. -| -\def\Macro #1{\advance\cnta #1 , \the\cnta} -\cnta 0 -Output: 0\xintApplyInline\Macro {3141592653}. +\subsection{\csbh{xintAbs}}\label{xintiAbs} -The first argument |\macro| does not have to be an expandable macro. +\csa{xintAbs\n} returns the absolute value of the number. Extended +by \xintfracname to fractions. -\csa{xintApplyInline} submits its second, token list parameter to an -\hyperref[sec: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. +\subsection{\csbh{xintAdd}}\label{xintiAdd} -\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 for example:\par -\smallskip -\centeredline - {\begin{tabular}{ccc} - $N$ & $N^2$ & $N^3$ \\ \hline - \def\Row #1{ #1 & \xintiSqr {#1} & \xintiPow {#1}{3} \\ \hline }% - \xintApplyInline \Row {\xintCSVtoList{17,28,39,50,61}} - \end{tabular}} -\smallskip -% 38 = &, 43 = +, 36=$, 45 = - -was obtained from the following input: -\dverb|@ -\begin{tabular}{ccc} - $N$ & $N^2$ & $N^3$ \\ \hline - \def\Row #1{ #1 & \xintiSqr {#1} & \xintiPow {#1}{3} \\ \hline }% - \xintApplyInline \Row {\xintCSVtoList{17,28,39,50,61}} -\end{tabular} -|% -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. +\csa{xintAdd\n\m} returns the sum of the two numbers. Extended by +\xintfracname to fractions. -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). +\subsection{\csbh{xintSub}}\label{xintiSub} -One may nest various |\xintApplyInline|'s. For example (see the -\hyperref[float]{table} \vpageref{float}):\par -\dverb|@ -\def\Row #1{#1:\xintApplyInline {\Item {#1}}{0123456789}\\ }% -\def\Item #1#2{&\xintiPow {#1}{#2}}% -\begin{tabular}{ccccccccccc} - &0&1&2&3&4&5&6&7&8&9\\ \hline - \xintApplyInline \Row {0123456789} -\end{tabular} -| -\begin{figure*}[ht!] - \centering\phantomsection\label{float} - \def\Row #1{#1:\xintApplyInline {\Item {#1}}{0123456789}\\ }% - \def\Item #1#2{&\xintiPow {#1}{#2}}% - \centeredline {\begin{tabular}{ccccccccccc} &0&1&2&3&4&5&6&7&8&9\\ \hline - \xintApplyInline \Row {0123456789} - \end{tabular}} -\end{figure*} -\smallskip -One could not move the definition of |\Item| inside the tabular, -as it would get lost after the first |&|. But this -works: -\dverb|@ -\begin{tabular}{ccccccccccc} - &0&1&2&3&4&5&6&7&8&9\\ \hline - \def\Row #1{#1:\xintApplyInline {&\xintiPow {#1}}{0123456789}\\ }% - \xintApplyInline \Row {0123456789} -\end{tabular}| +\csa{xintSub\n\m} returns the difference |N-M|. Extended by +\xintfracname to fractions. -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 -\dverb|@ - \def\Row #1{#1:\def\Item ##1{&\xintiPow {#1}{##1}}% - \xintApplyInline \Item {0123456789}\\ }% - \xintApplyInline \Row {0123456789} % does not work -|% -But see \csbxint{For}. +\subsection{\csbh{xintCmp}}\label{xintiCmp} -\subsection{\csbh{xintFor}, \csbh{xintFor*}}\label{xintFor}\label{xintFor*} -{\small New with |1.09c|. Extended in |1.09e| (\csbxint{BreakFor}, - \csbxint{integers}, \dots). |1.09f| version handles all macro parameters up to - |#9| and removes spaces around commas.\par} +\csa{xintCmp\n\m} returns 1 if |N>M|, 0 if |N=M|, and -1 if |N -Contrarily to what happens in loops where the item is represented by a macro, -here it is truly exactly as when defining (in \LaTeX{}) a ``command'' with -parameters |#1|, etc... This may avoid the user quite a few troubles with -|\expandafter|s or other |\edef/\noexpand|s which one encounters at times when -trying to do things with \LaTeX's {\makeatother|\@for|} or other loops -which encapsulate the item in a macro expanding to that item. +\csa{xintGt\n\m} returns 1 if |N|$>$|M|, 0 otherwise. +Extended by \xintfracname to fractions. -\begin{framed} - The non-starred variant \csbxint{For} deals with comma separated values - (\emph{spaces before and after the commas are removed}) and the comma - separated list may be a macro which is only expanded once (to prevent - expansion of the first item |\x| in a list directly input as |\x,\y,...| it - should be input as |{\x},\y,..| or |\x,\y,..|, naturally all of that - within the mandatory braces of the \csa{xintFor \#n in \{list\}} syntax). The - items are not expanded, if the input is |,\x,| then |#1| will be - at some point |\x| not its expansion (and not either a macro with |\x| as - replacement text, just the token |\x|). Input such as |,,| - creates an empty |#1|, the iteration is not skipped. An empty list does lead - to the use of the replacement text, once, with an empty |#1| (or |#n|). Except - if the entire list is represented as a single macro (with no parameters), - \fbox{it must be braced.} -\end{framed} +\subsection{\csbh{xintLt}}\label{xintLt} +{\small New with release |1.09a|.\par} -\begin{framed} - The starred variant \csbxint{For*} deals with token lists (\emph{spaces - between braced items or single tokens are not significant}) and - \hyperref[fn:expansions]{\fexpan ds} each \emph{unbraced} list item. This - makes it easy to simulate concatenation of various list macros |\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}}|% - \stepcounter{footnote}% - \makeatletter\hbox {\@textsuperscript {\normalfont \thefootnote - }}\makeatother. Spaces at the start, end, or in-between items are gobbled - (but naturally not the spaces which may be inside \emph{braced} items). Except - if the list argument is a single macro (with no parameters), \fbox{it must be - braced.} Each item which is not braced will be fully expanded (as the |\x| - and |\y| in the example above). An empty list leads to an empty result. +% attention dans la doc du 9 octobre j'avais écrit \leq au lieu de < - The macro \csbxint{Seq} which generates arithmetic sequences may only be used - with \csbxint{For*} (numbers from output of |\xintSeq| are braced, not - separated by commas). \centeredline{|\xintFor* #1 in {\xintSeq - [+2]{-7}{+2}}\do {stuff with #1}|} will have |#1=-7,-5,-3,-1, and 1|. The - |#1| as issued from the list produced by \csbxint{Seq} is the litteral - representation as would be produced by |\arabic| on a \LaTeX{} counter, it is - not a count register. When used in |\ifnum| tests or other contexts where - \TeX{} looks for a number it is recommended to use - |#1\space|\stepcounter{footnote}% - \makeatletter\hbox {\@textsuperscript {\normalfont \thefootnote - }}\makeatother, or |#1\relax| if expandability of the process is not an - issue (for example if the iterated commands do an |\edef| using such a test, - |\relax| is not a good choice as it will be kept in the complete expansion if - it is in the true branch of the conditional, whereas |\space| will disappear). -\end{framed} -\begingroup\makeatletter -\def\@footnotetext #1{\insert\footins {\reset@font \footnotesize \interlinepenalty \interfootnotelinepenalty \splittopskip \footnotesep \splitmaxdepth \dp \strutbox \floatingpenalty \@MM \hsize \columnwidth \@parboxrestore \color@begingroup \@makefntext {\rule \z@ \footnotesep \ignorespaces #1\@finalstrut \strutbox }\color@endgroup }} -\addtocounter{footnote}{-1} -\edef\@thefnmark {\thefootnote} -\@footnotetext{braces around single token items - are optional so this is the same as \texttt{\{123456\}}.} -\stepcounter{footnote} -\edef\@thefnmark {\thefootnote} -\@footnotetext{the \csa{space} will stop the \TeX{} scanning of a number and be - gobbled in the process; the \csa{relax} stops the scanning but is not - gobbled. Or one may do \csa{numexpr}\texttt{\#1}\csa{relax}, and then the - \csa{relax} is gobbled.} -\endgroup -\addtocounter{Hfootnote}{2} +\csa{xintLt\n\m} returns 1 if |N|$<$|M|, 0 otherwise. +Extended by \xintfracname to fractions. -The \csbxint{For} loops are not completely expandable; but they may be nested -and used inside alignments or other contexts where the replacement text closes -groups. Here is an example (still using \LaTeX's tabular): +\subsection{\csbh{xintIsZero}}\label{xintIsZero} +{\small New with release |1.09a|.\par} -\begingroup -\centeredline{\begin{tabular}{rccccc} - \xintFor #7 in {A,B,C} \do {% - #7:\xintFor* #3 in {abcde} \do {&($ #3 \to #7 $)}\\ }% -\end{tabular}} -\endgroup +\csa{xintIsZero\n} returns 1 if |N=0|, 0 otherwise. +Extended by \xintfracname to fractions. -\dverb|@ -\begin{tabular}{rccccc} - \xintFor #7 in {A,B,C} \do {% - #7:\xintFor* #3 in {abcde} \do {&($ #3 \to #7 $)}\\ }% -\end{tabular}| +\subsection{\csbh{xintNot}}\label{xintNot} +{\small New with release |1.09c|.\par} -When -inserted 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: -% -\dverb|@ -\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 |% -\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)} }% - }}% -\centeredline{\T\def\sep {\def\sep{, }}\z} Similarly when the replacement text -of |\xintFor| defines a macro with parameters, the macro character |#| must be -doubled. +\csa{xintNot} is a synonym for \csa{xintIsZero}. -It is licit to use inside an \csbxint{For} a |\macro| which itself has -been defined to use internally some other \csbxint{For}. The same macro -parameter |#1| can be used with no conflict (as mentioned above, in the -definition of |\macro| the |#| used in the \csbxint{For} declaration must be -doubled, as is the general rule in \TeX{} with things defined inside other -things). +\subsection{\csbh{xintIsNotZero}}\label{xintIsNotZero} +{\small New with release |1.09a|.\par} -The iterated commands as well as the list items are allowed to contain explicit -|\par| tokens. Neither \csbxint{For} nor \csbxint{For*} create groups. The -effect is like piling up the iterated commands with each time |#1| (or |#2| ...) -replaced by an item of the list. However, contrarily to the completely -expandable \csbxint{ApplyUnbraced}, but similarly to the non completely -expandable \csbxint{ApplyInline} each iteration is executed first before looking -at the next |#1|\footnote{to be completely honest, both \csbxint{For} and - \csbxint{For*} intially scoop up both the list and the iterated commands; - \csbxint{For} scoops up a second time the entire comma separated list in order - to feed it to \csbxint{CSVtoList}. The starred variant \csbxint{For*} which - does not need this step will thus be a bit faster on equivalent inputs.} (and -the starred variant \csbxint{For*} keeps on expanding each unbraced item it -finds, gobbling spaces). +\csa{xintIsNotZero\n} returns 1 if |N<>0|, 0 otherwise. +Extended by \xintfracname to fractions. -\subsection{\csbh{xintifForFirst}, \csbh{xintifForLast}} -\label{xintifForFirst}\label{xintifForLast} -{\small New in |1.09e|.\par} +\subsection{\csbh{xintIsOne}}\label{xintIsOne} +{\small New with release |1.09a|.\par} +\csa{xintIsOne\n} returns 1 if |N=1|, 0 otherwise. +Extended by \xintfracname to fractions. -\csbxint{ifForFirst}\,\texttt{\{YES branch\}\{NO branch\}} - and \csbxint{ifForLast}\,\texttt{\{YES - branch\}\hskip 0pt plus 0.2em \{NO branch\}} execute the |YES| or |NO| branch -if the -\csbxint{For} -or \csbxint{For*} loop is currently in its first, respectively last, iteration. +\subsection{\csbh{xintAND}}\label{xintAND} +{\small New with release |1.09a|.\par} -Designed to work as expected under nesting. 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. +\csa{xintAND\n\m} returns 1 if |N<>0| and |M<>0| and zero otherwise. + Extended by \xintfracname to fractions. -\subsection{ \csbh{xintBreakFor}, \csbh{xintBreakForAndDo}} -\label{xintBreakFor}\label{xintBreakForAndDo} -{\small New in |1.09e|.\par} +\subsection{\csbh{xintOR}}\label{xintOR} +{\small New with release |1.09a|.\par} -One may immediately terminate an \csbxint{For} or \csbxint{For*} loop with -\csbxint{BreakFor}. As the criterion for breaking will be decided on a -basis of some test, it is recommended to use for this test the syntax of -\href{http://ctan.org/pkg/ifthen}{ifthen}\footnote{\url{http://ctan.org/pkg/ifthen}} -or -\href{http://ctan.org/pkg/etoolbox}{etoolbox}\footnote{\url{http://ctan.org/pkg/etoolbox}} -or the \xintname own conditionals, rather than one of the various -|\if...\fi| of \TeX{}. Else (and this is without even mentioning all the various -pecularities of the -|\if...\fi| constructs), one has to carefully move the break after the closing -of -the conditional, typically with |\expandafter\xintBreakFor\fi|.\footnote{the - difficulties here are similar to those mentioned in \autoref{sec:ifcase}, - although less severe, as complete expandability is not to be maintained; hence - the allowed use of \href{http://ctan.org/pkg/ifthen}{ifthen}.} +\csa{xintOR\n\m} returns 1 if |N<>0| or |M<>0| and zero otherwise. + Extended by \xintfracname to fractions. -There is also \csbxint{BreakForAndDo}. Both are illustrated by various examples -in the next section which is devoted to ``forever'' loops. +\subsection{\csbh{xintXOR}}\label{xintXOR} +{\small New with release |1.09a|.\par} -\subsection{\csbh{xintintegers}, \csbh{xintdimensions}, \csbh{xintrationals}} -\label{xintegers}\label{xintintegers} -\label{xintdimensions}\label{xintrationals} -{\small New in |1.09e|.\par} +\csa{xintXOR\n\m} returns 1 if exactly one of |N| or |M| is true (i.e. +non-zero). + Extended by \xintfracname to fractions. -If the list argument to \csbxint{For} (or \csbxint{For*}, the two are here -completely equivalent) 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. +\subsection{\csbh{xintANDof}}\label{xintANDof} +{\small New with release |1.09a|.\par} -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 commands -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. +\csa{xintANDof}|{{a}{b}{c}...}| returns 1 if all are true (i.e. non +zero) and zero otherwise. The list argument +may be a macro, it (or rather its first token) is \fexpan ded first (each +item also is \fexpan ded). Extended by \xintfracname to fractions. -% original definitions, a bit slow. +\subsection{\csbh{xintORof}}\label{xintORof} +{\small New with release |1.09a|.\par} -% \def\DimToNum #1{\number\dimexpr #1\relax } -% % cube -% \xintNewNumExpr \FA [2] {{_DimToNum {$2}}^3/{_DimToNum {$1}}^2} %$ -% % square root -% \xintNewNumExpr \FB [2] {sqrt ({_DimToNum {$2}}*{_DimToNum {$1}})} -% \xintNewExpr \Ratio [2] {trunc({_DimToNum {$2}}/{_DimToNum{$1}},3)} +\csa{xintORof}|{{a}{b}{c}...}| returns 1 if at least one is true +(i.e. does not vanish). The list argument +may be a macro, it is \fexpan ded first. Extended by \xintfracname to fractions. -% improved faster code (4 four times faster) -\def\DimToNum #1{\the\numexpr \dimexpr#1\relax/10000\relax } -\def\FA #1#2{\xintDSH{-4}{\xintQuo {\xintiPow {\DimToNum {#2}}{3}}{\xintiSqr -{\DimToNum{#1}}}}} -\def\FB #1#2{\xintDSH {-4}{\xintiSqrt - {\xintiMul {\DimToNum {#2}}{\DimToNum{#1}}}}} -\def\Ratio #1#2{\xintTrunc {2}{\DimToNum {#2}/\DimToNum{#1}}} +\subsection{\csbh{xintXORof}}\label{xintXORof} +{\small New with release |1.09a|.\par} -% a further 2.5 gain is made through using .25pt as horizontal step. -\begin{figure*}[ht!] -\phantomsection\hypertarget{graphic}{}% -\centeredline{% -\begingroup -\raisebox{-1cm}{\xintFor #1 in {\xintdimensions [0pt+.25pt]} \do - {\ifdim #1>2cm \expandafter\xintBreakFor\fi - \color [rgb]{\Ratio {2cm}{#1},0,0}% - \vrule width .25pt height \FB {2cm}{#1}sp depth -\FA {2cm}{#1}sp - }% end of For iterated text -}% -\endgroup -\hspace{1cm}% -\scriptsize\def\MacroFont {\ttfamily\baselineskip8pt\relax} -\begin{minipage}{\dimexpr\linewidth-3cm-\parindent\relax} -\dverb|@ -\def\DimToNum #1{\number\dimexpr #1\relax } -\xintNewNumExpr \FA [2] {{_DimToNum {$2}}^3/{_DimToNum {$1}}^2} % cube -\xintNewNumExpr \FB [2] {sqrt ({_DimToNum {$2}}*{_DimToNum {$1}})} % sqrt -\xintNewExpr \Ratio [2] {trunc({_DimToNum {$2}}/{_DimToNum{$1}},3)} -\begingroup % to limit the scope of color changes -\xintFor #1 in {\xintdimensions [0pt+.1pt]} \do - {\ifdim #1>2cm \expandafter\xintBreakFor\fi - \color [rgb]{\Ratio {2cm}{#1},0,0}% - \vrule width .1pt height \FB {2cm}{#1}sp depth -\FA {2cm}{#1}sp - }% end of For iterated text -\endgroup|\par -\end{minipage}} -\end{figure*} +\csa{xintXORof}|{{a}{b}{c}...}| returns 1 if an odd number of them are +true (i.e. does not vanish). The list argument may be a macro, it is +\fexpan ded first. Extended by \xintfracname to fractions. -% attention, pour le \meaning dans cette note de base de page -The\xintNewNumExpr \FA [2] {{_DimToNum {$2}}^3/{_DimToNum {$1}}^2} %$ -\hyperlink{graphic}{graphic}, with the code on its right\footnote{the somewhat - peculiar use of |\_| and |\$| is explained in \autoref{xintNewExpr}; they are - made necessary from the fact that the parameters are passed to a \emph{macro} - (\csa{DimToNum}) and not only to \emph{functions}, as are known to - \hyperref[sec:exprsummary]{\csa{xintexpr}}. But one can also define directly - the desired function, for example the constructed \csa{FA} turns out to have - meaning \texttt{\meaning\FA}, where the \csa{romannumeral} part is only to - ensure it expands in only two steps, and could be removed. A handwritten macro - would use here \csa{xintiPow} and not \csa{xintPow}, as we know it has to deal - with integers only. See the next footnote.}, is for illustration only, not -only because of pdf rendering artefacts when displaying adjacent rules (which do -\emph{not} show in |dvi| output as rendered by |xdvi|, and depend from your -viewer), but because not using anything but rules it is quite inefficient and -must do lots of computations to not confer a too ragged look to the borders. -With a width of |.5pt| rather than |.1pt| for the rules, one speeds up the -drawing by a factor of five, but the boundary is then visibly ragged. -\newbox\codebox -\begingroup\makeatletter -\def\x{% - \parindent0pt - \def\par{\@@par\leavevmode\null}% - \let\do\do@noligs \verbatim@nolig@list - \let\do\@makeother \dospecials - \catcode`\@ 14 \makestarlowast - \ttfamily \scriptsize\baselineskip 8pt \obeylines \@vobeyspaces - \catcode`\|\active - \lccode`\~`\|\lowercase{\let~\egroup}}% -\global\setbox\codebox \vbox\bgroup\x -\def\DimToNum #1{\the\numexpr \dimexpr#1\relax/10000\relax } % no need to be more precise! -\def\FA #1#2{\xintDSH {-4}{\xintQuo {\xintiPow {\DimToNum {#2}}{3}}{\xintiSqr {\DimToNum{#1}}}}} -\def\FB #1#2{\xintDSH {-4}{\xintiSqrt {\xintiMul {\DimToNum {#2}}{\DimToNum{#1}}}}} -\def\Ratio #1#2{\xintTrunc {2}{\DimToNum {#2}/\DimToNum{#1}}} -\begingroup -\xintFor #1 in {\xintdimensions [0pt+.25pt]} \do - {\ifdim #1>2cm \expandafter\xintBreakFor\fi - \color [rgb]{\Ratio {2cm}{#1},0,0}% - \vrule width .25pt height \FB {2cm}{#1}sp depth -\FA {2cm}{#1}sp - }% end of For iterated text -\endgroup -|% -\endgroup -\footnote{to tell the whole truth we cheated and divided by |10| the - computation time through using the following definitions, together with a - horizontal step of |.25pt| rather than |.1pt|. The displayed original code - would make the slowest computation of all those done in this document using - the \xintname bundle macros!\par\smallskip - \noindent\box \codebox\par } +\subsection{\csbh{xintGeq}}\label{xintiGeq} -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). +\csa{xintGeq\n\m} 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. Extended by \xintfracname to fractions (starting with release +|1.07|). Please note that the macro compares \emph{absolute values}. -\begingroup\small -\noindent\dverb|@ -\xintFor #1 in {\xintrationals [10/21+1/21]} \do -{#1=\xintifInt {#1} - {\textcolor{blue}{\xintTrunc{10}{#1}}} - {\xintTrunc{10}{#1}}% in blue if an integer - \xintifGt {#1}{1.123}{\xintBreakFor}{, }% -}| +\subsection{\csbh{xintMax}}\label{xintiMax} -\smallskip -\centeredline{\parbox{\dimexpr\linewidth-3em}{\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 +\csa{xintMax\n\m} 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): |\xintiMax +{-5}{-6}|\digitstt{=\xintiMax{-5}{-6}}. Extended by \xintfracname to fractions. -\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 zeros. +\subsection{\csbh{xintMaxof}}\label{xintMaxof} +{\small New with release |1.09a|.\par} -\begingroup\footnotesize \def\MacroFont {\ttfamily\relax} -\noindent\dverb|@ -\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 +\csa{xintMaxof}|{{a}{b}{c}...}| returns the maximum. The list argument +may be a macro, it is \fexpan ded first. Extended by \xintfracname to +fractions. -\centeredline{\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 +\subsection{\csbh{xintMin}}\label{xintiMin} -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 behavior 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 -\endgroup +\csa{xintMin\n\m} 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): |\xintiMin +{-5}{-6}|\digitstt{=\xintiMin{-5}{-6}}. Extended by \xintfracname to fractions. +\subsection{\csbh{xintMinof}}\label{xintMinof} +{\small New with release |1.09a|.\par} -\subsection{Another table of primes}\label{ssec:primesII} +\csa{xintMinof}|{{a}{b}{c}...}| returns the minimum. The list argument +may be a macro, it is \fexpan ded first. Extended by \xintfracname to +fractions. -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{xintSeq}, 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. +\subsection{\csbh{xintSum}}\label{xintiSum} -\def\IsPrime #1#2% -{\edef\TheNumber {\the\numexpr #2}% positive integer - \ifnumodd {\TheNumber} - {\ifnumgreater {\TheNumber}{1} - {\edef\ItsSquareRoot{\xintiSqrt \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}}}% -}% - -\dverb|@ -\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{\xintiSqrt \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{xintSum}\marg{braced things} after expanding its argument +expects to find a sequence of tokens (or braced material). +Each is expanded (with the usual meaning), and the sum of all these numbers is +returned. +\centeredline{% + \csa{xintiSum}|{{123}{-98763450}{\xintFac{7}}{\xintiMul{3347}{591}}}|% + \digitstt{=\xintiSum{{123}{-98763450}{\xintFac{7}}{\xintiMul{3347}{591}}}}} +\centeredline{\csa{xintiSum}|{1234567890}|\digitstt{=\xintiSum{1234567890}}} +An empty sum is no error and returns zero: |\xintiSum +{}|\digitstt{=\xintiSum {}}. A sum with only one +term returns that number: |\xintiSum {{-1234}}|\digitstt{=\xintiSum + {{-1234}}}. Attention that |\xintiSum {-1234}| is not legal input +and will make the \TeX{} run fail. On the other hand |\xintiSum +{1234}|\digitstt{=\xintiSum{1234}}. Extended by \xintfracname +to fractions. -%\newcounter{primecount} -%\newcounter{cellcount} -\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*} +% retiré de la doc le 22 octobre 2013 -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 appears -\vpageref[above]{primes}): -\dverb?@ -\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*}? +% \subsection{\csbh{xintSumExpr}}\label{xintiSumExpr} -\subsection{\csbh{xintForpair}, \csbh{xintForthree}, \csbh{xintForfour}}\label{xintForpair}\label{xintForthree}\label{xintForfour} -{\small New in |1.09c|. The \csa{xintifForFirst} - |1.09e| mechanism was missing and has been added for |1.09f|. The |1.09f| - version handles better spaces and admits all (consecutive) macro - parameters.\par} +% \csa{xintSumExpr}\meta{braced things}\csa{relax} is to what \csa{xintSum} +% expands. The argument is then expanded (with the usual meaning) and should give +% a list of braced quantities or macros, each one will be expanded in turn. +% \centeredline{% +% \csa{xintiSumExpr}| {123}{-98763450}|% +% |{\xintFac{7}}{\xintiMul{3347}{591}}\relax|\digitstt{=% +% \xintiSumExpr {123}{-98763450}{\xintFac{7}}{\xintiMul{3347}{591}}\relax}} -The syntax 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. -% -\dverb|@ -\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}|% -\centeredline{\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}} +% Note: I am not so happy with the name which seems to suggest that the +% |+| sign should be used instead of braces. Perhaps this will change +% in the future. -\smallskip Only |#1#2|, |#2#3|, \dots, |#8#9| are valid (no error check is -done on the input syntax\dots). One can nest with -\csbxint{For}, for disjoint sets of macro parameters. There is also -\csa{xintForthree} (from |#1#2#3| to |#7#8#9|) and \csa{xintForfour} -(from |#1#2#3#4| to |#6#7#8#9|). +% Extended by \xintfracname to fractions. -% These three macros |\xintForpair|, |\xintForthree| and |\xintForfour| are to -% be considered in experimental status, and may be removed, replaced or -% substantially modified at some later stage. +\subsection{\csbh{xintMul}}\label{xintiMul} +{\small Modified in release |1.03|.\par} -\subsection{\csbh{xintAssign}}\label{xintAssign} +\csa{xintMul\n\m} returns the product of the two numbers. Starting +with release |1.03| of \xintname, the macro checks the lengths of +the two numbers and then activates its algorithm with the best (or +at least, hoped-so) choice of which one to put first. This makes +the macro a bit slower for numbers up to 50 digits, but may give +substantial speed gain when one of the number has 100 digits or more. +Extended by \xintfracname to fractions. -\csa{xintAssign}\meta{braced things}\csa{to}% -\meta{as many cs as they are things} defines (without checking if -something gets overwritten) the control sequences on the right of -\csa{to} to be the complete expansions of the successive braced things found on -the left of \csa{to}. +\subsection{\csbh{xintSqr}}\label{xintiSqr} -A `full' expansion is first applied first to the -material in front of \csa{xintAssign}, which may thus be a macro expanding to a -list of braced items. +\csa{xintSqr\n} returns the square. Extended by \xintfracname to fractions. -\xintAssign\xintiPow {7}{13}\to\SevenToThePowerThirteen -\xintAssign\xintDivision{1000000000000}{133333333}\to\Q\R +\subsection{\csbh{xintPrd}}\label{xintiPrd} -Special case: 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 |\edef| as the -complete expansion of the material between \csa{xintAssign} and \csa{to}. -\centeredline{|\xintAssign\xintDivision{1000000000000}{133333333}\to\Q\R|} -\centeredline{|\meaning\Q: |\digitstt{\meaning\Q}, |\meaning\R:| - \digitstt{\meaning\R}} \centeredline{|\xintAssign\xintiPow - {7}{13}\to\SevenToThePowerThirteen|} -\centeredline{|\SevenToThePowerThirteen|\digitstt{=\SevenToThePowerThirteen}} -\centeredline{(same as |\edef\SevenToThePowerThirteen{\xintiPow {7}{13}}|)} This -macro uses various \csa{edef}'s, thus is incompatible with expansion-only -contexts. +\csa{xintPrd}\marg{braced things} after expanding its argument expects to find a +sequence of tokens (or braced material). Each is expanded (with the usual +meaning), and the product of all these numbers is returned. +\centeredline{% + \csa{xintiPrd}|{{-9876}{\xintFac{7}}{\xintiMul{3347}{591}}}|% + \digitstt{=% + \xintiPrd{{-9876}{\xintFac{7}}{\xintiMul{3347}{591}}}}} +\centeredline{\csa{xintiPrd}|{123456789123456789}|\digitstt{=% + \xintiPrd{123456789123456789}}} An empty product is no error and returns 1: +|\xintiPrd {}|\digitstt{=\xintiPrd {}}. A product reduced to a single term returns +this number: |\xintiPrd {{-1234}}|\digitstt{=\xintiPrd {{-1234}}}. Attention that +|\xintiPrd {-1234}| is not legal input and will make the \TeX{} compilation +fail. On the other hand |\xintiPrd {1234}|\digitstt{=\xintiPrd {1234}}. +\centeredline{$\displaystyle 2^{200}3^{100}7^{100}$} \centeredline{|=\xintiPrd + {{\xintiPow {2}{200}}{\xintiPow {3}{100}}{\xintiPow {7}{100}}}|} +\digitstt{=\printnumber{\xintNum {\xinttheexpr 2^200*3^100*7^100\relax }}} -\subsection{\csbh{xintAssignArray}}\label{xintAssignArray} +Extended by \xintfracname to fractions. -{\small Changed in release |1.06| to let the defined macro pass its - argument through a |\numexpr...\relax|.\par} +With \xintexprname, the above would be coded simply as \centeredline +{|\xintthenumexpr 2^200*3^100*7^100\relax |} -\xintAssignArray\xintBezout {1000}{113}\to\Bez +% I temporarily remove mention of \xintPrdExpr from the documentation; I +% really dislike the name now. -\csa{xintAssignArray}\meta{braced things}\csa{to}\csa{myArray} 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 -completely expanded |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}|. -\centeredline{|\xintAssignArray\xintBezout {1000}{113}\to\Bez|} will set -|\Bez{0}| to \digitstt{\Bez0}, |\Bez{1}| to \digitstt{\Bez1}, |\Bez{2}| to -\digitstt{\Bez2}, |\Bez{3}| to \digitstt{\Bez3}, |\Bez{4}| to \digitstt{\Bez4}, -and |\Bez{5}| to \digitstt{\Bez5}: -\digitstt{(\Bez3)${}\times{}$\Bez1${}-{}$(\Bez4)${}\times{}$\Bez2${}={}$\Bez5.} -This macro is incompatible with expansion-only contexts. +% \subsection{\csbh{xintPrdExpr}}\label{xintiPrdExpr} +% {\small Name change in |1.06a|! I apologize, but I suddenly decided that +% \csa{xintProductExpr} was a bad choice; so I just replaced it by the current +% name. \par} -\subsection{\csbh{xintRelaxArray}}\label{xintRelaxArray} +% \csa{xintPrdExpr}\marg{argument}\csa{relax} is to what \csa{xintPrd} expands +% ; its argument is expanded (with the usual meaning) and should give a list of +% braced numbers or macros. Each will be expanded when it is its turn. +% \centeredline{\csa{xintiPrdExpr}| 123456789123456789\relax|\digitstt{=% +% \xintiPrdExpr 123456789123456789\relax}} -\csa{xintRelaxArray}\csa{myArray} sets to \csa{relax} all -macros which were defined by the previous \csa{xintAssignArray} -with \csa{myArray} as array name. +% Note: I am not so happy with the name which seems to suggest that the +% |*| sign should be used instead of braces. Perhaps this will change +% in the future. -\subsection{The Quick Sort algorithm illustrated}\label{ssec:quicksort} +% Extended by \xintfracname to fractions. -First a completely expandable macro which sorts a list of numbers. The |\QSfull| -macro expands its list argument, which may thus be a macro; its items must -expand to possibly big integers (or also decimal numbers or fractions if using -\xintfracname), but if an item is expressed as a computation, this computation -will be redone each time the item is considered! If the numbers have many digits -(i.e. hundreds of digits...), the expansion of |\QSfull| is fastest if each -number, rather than being explicitely given, is represented as a single token -which expands to it in one step. +\subsection{\csbh{xintPow}}\label{xintiPow} -If the interest is only in \TeX{} integers, then one should replace the macros -|\QSMore|, |QSEqual|, |QSLess| with versions using the -\href{http://ctan.org/pkg/etoolbox}{etoolbox} (\LaTeX{} only) |\ifnumgreater|, -|\ifnumequal| and |\ifnumless| conditionals rather than \csbxint{ifGt}, -\csbxint{ifEq}, \csbxint{ifLt}. +\csa{xintPow\n\x} returns |N^x|. When |x| is zero, this is 1. If |N| is zero and +|x<0|, if \verb+|N|>1+ and |x<0| negative, or if \verb+|N|>1+ and |x>999999999|, +then an error is raised. |2^999999999| has \np{301029996} digits; each exact +multiplication of two one thousand digits numbers already takes a few seconds, +so needless to say this bound is completely irrealistic. Already |2^9999| has +\np{3010} digits,\footnote{on my laptop |\string\xintiPow \{2\}\{9999\}| + obtains all |3010| digits in about ten or eleven seconds. In contrast, the + float versions for + |8|, |16|, |24|, or even more significant figures, do their jobs in circa one + hundredth of a second (|1.08b|). This is done without |log|/|exp| which are + not (yet?) implemented in \xintfracname. The \LaTeX3 + \href{http://www.ctan.org/tex-archive/macros/latex/contrib/l3kernel}{l3fp} + does this with |log|/|exp| and is ten times faster (|16| figures only).} so I +should perhaps lower the bound to |99999|. -\begingroup\makeatletter\let\check@percent\relax -\def\MacroFont{\small\baselineskip12pt \ttfamily } -\begin{verbatim} -% THE QUICK SORT ALGORITHM EXPANDABLY -\input xintfrac.sty -% HELPER COMPARISON MACROS -\def\QSMore #1#2{\xintifGt {#2}{#1}{{#2}}{ }} -% the spaces are there to stop the \romannumeral-`0 originating -% in \xintapplyunbraced when it applies a macro to an item -\def\QSEqual #1#2{\xintifEq {#2}{#1}{{#2}}{ }} -\def\QSLess #1#2{\xintifLt {#2}{#1}{{#2}}{ }} -% -\makeatletter -\def\QSfull {\romannumeral0\qsfull } -\def\qsfull #1{\expandafter\qsfull@a\expandafter{\romannumeral-`0#1}} -\def\qsfull@a #1{\expandafter\qsfull@b\expandafter {\xintLength {#1}}{#1}} -\def\qsfull@b #1{\ifcase #1 - \expandafter\qsfull@empty - \or\expandafter\qsfull@single - \else\expandafter\qsfull@c - \fi -}% -\def\qsfull@empty #1{ } % the space stops the \QSfull \romannumeral0 -\def\qsfull@single #1{ #1} -% for simplicity of implementation, we pick up the first item as pivot -\def\qsfull@c #1{\qsfull@ci #1\undef {#1}} -\def\qsfull@ci #1#2\undef {\qsfull@d {#1}}% #3 is the list, #1 its first item -\def\qsfull@d #1#2{\expandafter\qsfull@e\expandafter - {\romannumeral0\qsfull - {\xintApplyUnbraced {\QSMore {#1}}{#2}}}% - {\romannumeral0\xintapplyunbraced {\QSEqual {#1}}{#2}}% - {\romannumeral0\qsfull - {\xintApplyUnbraced {\QSLess {#1}}{#2}}}% -}% -\def\qsfull@e #1#2#3{\expandafter\qsfull@f\expandafter {#2}{#3}{#1}}% -\def\qsfull@f #1#2#3{\expandafter\space #2#1#3} -\makeatother -% EXAMPLE -\edef\z {\QSfull {{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}}} -\tt\meaning\z -\def\a {3.123456789123456789}\def\b {3.123456789123456788} -\def\c {3.123456789123456790}\def\d {3.123456789123456787} -\expandafter\def\expandafter\z\expandafter - {\romannumeral0\qsfull {{\a}\b\c\d}}% \a is braced to not be expanded -\meaning\z -\end{verbatim} +Extended by \xintfracname to fractions (\csbxint{Pow}) and also to floats +(\csbxint{FloatPow}). Negative +exponents do not then cause errors anymore. The float version is able to deal +with things such as +|2^999999999| without any problem. For example +|\xintFloatPow[4]{2}{9999}|\digitstt{=\xintFloatPow[4]{2}{9999}} and +|\xintFloatPow[4]{2}{999999999}| +\digitstt{=\xintFloatPow[4]{2}{999999999}}. -% THE QUICK SORT ALGORITHM EXPANDABLY -\def\QSMore #1#2{\xintifGt {#2}{#1}{{#2}}{ }} -% the spaces stop the \romannumeral-`0 done by \xintapplyunbraced each time -% it applies its macro argument to an item -\def\QSEqual #1#2{\xintifEq {#2}{#1}{{#2}}{ }} -\def\QSLess #1#2{\xintifLt {#2}{#1}{{#2}}{ }} -% -\def\QSfull {\romannumeral0\qsfull } -\def\qsfull #1{\expandafter\qsfull@a\expandafter{\romannumeral-`0#1}} -\def\qsfull@a #1{\expandafter\qsfull@b\expandafter {\xintLength {#1}}{#1}} -\def\qsfull@b #1{\ifcase #1 - \expandafter\qsfull@empty - \or\expandafter\qsfull@single - \else\expandafter\qsfull@c - \fi -}% -\def\qsfull@empty #1{ } % the space stops the \QSfull \romannumeral0 -\def\qsfull@single #1{ #1} -\def\qsfull@c #1{\qsfull@ci #1\undef {#1}} % we pick up the first as Pivot -\def\qsfull@ci #1#2\undef {\qsfull@d {#1}} -\def\qsfull@d #1#2{\expandafter\qsfull@e\expandafter - {\romannumeral0\qsfull - {\xintApplyUnbraced {\QSMore {#1}}{#2}}}% - {\romannumeral0\xintapplyunbraced {\QSEqual {#1}}{#2}}% - {\romannumeral0\qsfull - {\xintApplyUnbraced {\QSLess {#1}}{#2}}}% -}% -\def\qsfull@e #1#2#3{\expandafter\qsfull@f\expandafter {#2}{#3}{#1}}% -\def\qsfull@f #1#2#3{\expandafter\space #2#1#3} -\makeatother -% EXAMPLE -\edef\z {\QSfull {{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}}} -\noindent Output:\par -\texttt{\printnumber{\meaning\z}} +\subsection{\csbh{xintSgnFork}}\label{xintSgnFork} +{\small New with release |1.07|. See also \csbxint{ifSgn}.\par} -\def\a {3.123456789123456789}\def\b {3.123456789123456788} -\def\c {3.123456789123456790}\def\d {3.123456789123456787} -\expandafter\def\expandafter\z\expandafter - {\romannumeral0\qsfull {{\a}\b\c\d}}% \a is braced to not be expanded -\texttt{\printnumber{\meaning\z}} -\endgroup +\csa{xintSgnFork}\verb+{-1|0|1}+\marg{A}\marg{B}\marg{C} expandably +chooses to execute either the \meta{A}, \meta{B} or \meta{C} code, +depending on its first argument. This first argument should be anything +expanding to either |-1|, |0| or |1| (a count register should be +prefixed by |\the| and a |\numexpr...\relax| also should be prefixed by +|\the|). This utility is provided to help construct expandable macros +choosing depending on a condition which one of the package macros to +use, or which values to confer to their arguments. + +\subsection{\csbh{xintifSgn}}\label{xintifSgn} +{\small New with release |1.09a|.\par} + +Similar to \csa{xintSgnFork} except that the first argument may expand to a +(big) integer (or a fraction if \xintfracname is loaded), and it is its sign +which decides which of the three branches is taken. Furthermore this first +argument may be a count register, with no |\the| or |\number| prefix. + +\subsection{\csbh{xintifZero}}\label{xintifZero} +{\small New with release |1.09a|.\par} + +\csa{xintifZero}\marg{N}\marg{IsZero}\marg{IsNotZero} 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. + +\subsection{\csbh{xintifNotZero}}\label{xintifNotZero} +{\small New with release |1.09a|.\par} + +\csa{xintifNotZero}\marg{N}\marg{IsNotZero}\marg{IsZero} 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 not zero or +is zero. It then either executes the first or the second branch. + +\subsection{\csbh{xintifTrueFalse}}\label{xintifTrueFalse} +{\small New with release |1.09c|, renamed in |1.09e|.\par} + +\csa{xintifTrueFalse}\marg{N}\marg{true branch}\marg{false branch} is a synonym +for \csbxint{ifNotZero}. It is also available as \csa{xintifTrue} but this later +name is a bit misleading as the macro must always have a |false| branch, +possibly an empty brace pair |{}|. + +\subsection{\csbh{xintifCmp}}\label{xintifCmp} +{\small New with release |1.09e|.\par} + +\csa{xintifCmp}\marg{A}\marg{B}\marg{if AB} compares +its arguments and chooses accordingly the correct branch. + +\subsection{\csbh{xintifEq}}\label{xintifEq} +{\small New with release |1.09a|.\par} + +\csa{xintifEq}\marg{A}\marg{B}\marg{YES}\marg{NO} checks equality of its +two first arguments (numbers, or fractions if \xintfracname is loaded) and does the |YES| or the |NO| branch. + +\subsection{\csbh{xintifGt}}\label{xintifGt} +{\small New with release |1.09a|.\par} + +% attention dans la doc du 9 octobre j'avais écrit \geq au lieu de < +\csa{xintifGt}\marg{A}\marg{B}\marg{YES}\marg{NO} checks if $A>B$ and in that +case executes the |YES| branch. Extended to fractions (in particular decimal +numbers) by \xintfracname. + +\subsection{\csbh{xintifLt}}\label{xintifLt} +{\small New with release |1.09a|.\par} + +% attention dans la doc du 9 octobre j'avais écrit \leq au lieu de < +\csa{xintifLt}\marg{A}\marg{B}\marg{YES}\marg{NO} checks if $A0|, |M^2-d=N| and |M| +smallest (hence |=1+|\csa{xint\-iSqrt}|{N}|). +\centeredline{|\xintAssign\xintiSquareRoot + {17000000000000000000000000}\to\A\B|}% +\centeredline{|\xintiSub{\xintiSqr\A}\B=\A^2-\B|}% +\centeredline{\digitstt{\xintiSub{\xintiSqr\A}\B=\A\string^2-\B}} +A rational approximation to +$\sqrt{|N|}$ is $|M|-\frac{|d|}{|2M|}$ (this is a majorant and the error is at +most |1/2M|; if |N| is a perfect square |k^2| then |M=k+1| and this gives +|k+1/(2k+2)|, not |k|). + +Package \xintfracname has \csbxint{FloatSqrt} for square +roots of floating point numbers. + + +\begin{framed} + The macros described next are strictly for integer-only arguments. These + arguments are \emph{not} filtered via \csbxint{Num}. +\end{framed} + +\subsection{\csbh{xintInc}, \csbh{xintDec}} +\label{xintInc} +\label{xintDec} +{\small New with |1.08|.\par} + +\csa{xintInc\n} is |N+1| and \csa{xintDec\n} is |N-1|. These macros remain +integer-only, even with \xintfracname loaded. + +\subsection{\csbh{xintDouble}, \csbh{xintHalf}} +\label{xintDouble} +\label{xintHalf} +{\small New with |1.08|.\par} + +\csa{xintDouble\n} returns |2N| and \csa{xintHalf\n} is |N/2| rounded +towards zero. These macros remain integer-only, even with \xintfracname loaded. + +\subsection{\csbh{xintDSL}}\label{xintDSL} + +\csa{xintDSL\n} is decimal shift left, \emph{i.e.} multiplication +by ten. + +\subsection{\csbh{xintDSR}}\label{xintDSR} + +\csa{xintDSR\n} is decimal shift right, \emph{i.e.} it removes the last digit +(keeping the sign), equivalently it is the closest integer to |N/10| when +starting at zero. + +\subsection{\csbh{xintDSH}}\label{xintDSH} + +\csa{xintDSH\x\n} is parametrized decimal shift. When |x| is +negative, it is like iterating \csa{xintDSL} \verb+|x|+ times +(\emph{i.e.} multiplication by @10^{-@|x|@}@). When |x| positive, +it is like iterating \csa{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|. + +\subsection{\csbh{xintDSHr}, \csbh{xintDSx}}\label{xintDSHr}\label{xintDSx} +{\small New in release |1.01|.\par} + +\csa{xintDSHr\x\n} expects |x| to be zero or positive and it returns +then a value |R| which is correlated to the value |Q| returned by +\csa{xintDSH\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{xintDivision}), +\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|. + + +\csa{xintDSx\x\n} for |x| negative is exactly as +\csa{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 +\csa{xintDSH\x\n}, and |R| is \csa{xintDSHr\x\n}, but computed +simultaneously. + +\begin{flushleft} + \xintAssign\xintDSx {-1}{-123456789}\to\M + \noindent{|\xintAssign\xintDSx {-1}{-123456789}\to\M|}\\ + |\meaning\M: |\digitstt{\meaning\M}.\\ + \xintAssign\xintDSx {-20}{1234567689}\to\M + {|\xintAssign\xintDSx {-20}{123456789}\to\M|}\\ + |\meaning\M: |\digitstt{\meaning\M}.\\ + \xintAssign\xintDSx{0}{-123004321}\to\Q\R + {|\xintAssign\xintDSx {0}{-123004321}\to\Q\R|}\\ + \noindent|\meaning\Q: |\digitstt{\meaning\Q}, |\meaning\R: + |\digitstt{\meaning\R.}\\ + |\xintDSH {0}{-123004321}|\digitstt{=\xintDSH {0}{-123004321}}, + |\xintDSHr {0}{-123004321}|\digitstt{=\xintDSHr {0}{-123004321}}\\ + \xintAssign\xintDSx {6}{-123004321}\to\Q\R + {|\xintAssign\xintDSx {6}{-123004321}\to\Q\R|}\\ + |\meaning\Q: |\digitstt{\meaning\Q}, + |\meaning\R: |\digitstt{\meaning\R.}\\ + |\xintDSH {6}{-123004321}|\digitstt{=\xintDSH {6}{-123004321}}, + |\xintDSHr {6}{-123004321}|\digitstt{=\xintDSHr {6}{-123004321}}\\ + \xintAssign\xintDSx {8}{-123004321}\to\Q\R + {|\xintAssign\xintDSx {8}{-123004321}\to\Q\R|}\\ + |\meaning\Q: |\digitstt{\meaning\Q}, + |\meaning\R: |\digitstt{\meaning\R.} \\ + |\xintDSH {8}{-123004321}|\digitstt{=\xintDSH {8}{-123004321}}, + |\xintDSHr {8}{-123004321}|\digitstt{=\xintDSHr {8}{-123004321}}\\ + \xintAssign\xintDSx {9}{-123004321}\to\Q\R + {|\xintAssign\xintDSx {9}{-123004321}\to\Q\R|}\\ + |\meaning\Q: |\digitstt{\meaning\Q}, + |\meaning\R: |\digitstt{\meaning\R.}\\ + |\xintDSH {9}{-123004321}|\digitstt{=\xintDSH {9}{-123004321}}, + |\xintDSHr {9}{-123004321}|\digitstt{=\xintDSHr {9}{-123004321}}\\ +\end{flushleft} +\subsection{\csbh{xintDecSplit}}\label{xintDecSplit} -We then turn to a graphical illustration of the algorithm. For simplicity the -pivot is always chosen to be the first list item. We also show later how to -illustrate the variant which picks up the last item of each unsorted -chunk as pivot. +{\small This has been modified in release |1.01|.\par} -\begingroup -\makeatletter -\let\check@percent\relax -% il utilise MacroFont -\def\MacroFont{\small\baselineskip 12pt \ttfamily } -\begin{verbatim} -\input xintfrac.sty % if Plain TeX -% -\definecolor{LEFT}{RGB}{216,195,88} -\definecolor{RIGHT}{RGB}{208,231,153} -\definecolor{INERT}{RGB}{199,200,194} -\definecolor{PIVOT}{RGB}{109,8,57} -% -\def\QSMore #1#2{\xintifGt {#2}{#1}{{#2}}{ }}% space will be gobbled -\def\QSEqual #1#2{\xintifEq {#2}{#1}{{#2}}{ }} -\def\QSLess #1#2{\xintifLt {#2}{#1}{{#2}}{ }} -% -\makeatletter -\def\QS@a #1{\expandafter \QS@b \expandafter {\xintLength {#1}}{#1}} -\def\QS@b #1{\ifcase #1 - \expandafter\QS@empty - \or\expandafter\QS@single - \else\expandafter\QS@c - \fi -}% -\def\QS@empty #1{} -\def\QS@single #1{\QSIr {#1}} -\def\QS@c #1{\QS@d #1!{#1}} % we pick up the first as pivot. -\def\QS@d #1#2!{\QS@e {#1}}% #1 = first element, #3 = list -\def\QS@e #1#2{\expandafter\QS@f\expandafter - {\romannumeral0\xintapplyunbraced {\QSMore {#1}}{#2}}% - {\romannumeral0\xintapplyunbraced {\QSEqual {#1}}{#2}}% - {\romannumeral0\xintapplyunbraced {\QSLess {#1}}{#2}}% -}% -\def\QS@f #1#2#3{\expandafter\QS@g\expandafter {#2}{#3}{#1}}% -% Here \QSLr, \QSIr, \QSr have been let to \relax, so expansion stops. -% #2= elements < pivot, #1 = elements = pivot, #3 = elements > pivot -\def\QS@g #1#2#3{\QSLr {#2}\QSIr {#1}\QSRr {#3}}% -% -\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{% - \xintFor* ##1 in {#1} \do - {\xintifForFirst {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}% -} -\def\DecoRIGHTwithPivot #1{% - \xintFor* ##1 in {#1} \do - {\xintifForFirst {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}% -} -% -\def\QSinitialize #1{\def\QS@list{\QSRr {#1}}% - \let\QSRr\DecoRIGHT -% \QS@list \par -\par\centerline{\QS@list} -} -\def\QSoneStep {\let\QSLr\DecoLEFTwithPivot - \let\QSIr\DecoINERT - \let\QSRr\DecoRIGHTwithPivot -% \QS@list -\centerline{\QS@list} -% \par - \def\QSLr {\noexpand\QS@a}% - \let\QSIr\relax - \def\QSRr {\noexpand\QS@a}% - \edef\QS@list{\QS@list}% - \let\QSLr\relax - \let\QSRr\relax - \edef\QS@list{\QS@list}% - \let\QSLr\DecoLEFT - \let\QSIr\DecoINERT - \let\QSRr\DecoRIGHT -% \QS@list -\centerline{\QS@list} -% \par -} -\begingroup\offinterlineskip -\small -\QSinitialize {{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}} -\QSoneStep -\QSoneStep -\QSoneStep -\QSoneStep -\QSoneStep -\endgroup -\end{verbatim} +\csa{xintDecSplit\x\n} cuts the number into two pieces (each one within a +pair of enclosing braces). First the sign if present is \emph{removed}. +Then, for |x| positive or null, the second piece contains the |x| least +significant digits (\emph{empty} if |x=0|) and the first piece the remaining +digits (\emph{empty} when |x| equals or exceeds the length of |N|). +Leading zeros in the second piece are not removed. When |x| is negative +the first piece contains the \verb+|x|+ most significant digits and the +second piece the remaining digits (\emph{empty} if @|x|@ equals or exceeds +the length of |N|). Leading zeros in this second piece are not removed. +So the absolute value of the original number is always the concatenation +of the first and second piece. -\def\QSMore #1#2{\xintifGt {#2}{#1}{{#2}}{ }}% space will be gobbled -\def\QSEqual #1#2{\xintifEq {#2}{#1}{{#2}}{ }} -\def\QSLess #1#2{\xintifLt {#2}{#1}{{#2}}{ }} -% -\def\QS@a #1{\expandafter \QS@b \expandafter {\xintLength {#1}}{#1}} -\def\QS@b #1{\ifcase #1 - \expandafter\QS@empty - \or\expandafter\QS@single - \else\expandafter\QS@c - \fi -}% -\def\QS@empty #1{} -\def\QS@single #1{\QSIr {#1}} -\def\QS@c #1{\QS@d #1!{#1}} % we pick up the first as pivot. -\def\QS@d #1#2!{\QS@e {#1}}% #1 = first element, #3 = list -\def\QS@e #1#2{\expandafter\QS@f\expandafter - {\romannumeral0\xintapplyunbraced {\QSMore {#1}}{#2}}% - {\romannumeral0\xintapplyunbraced {\QSEqual {#1}}{#2}}% - {\romannumeral0\xintapplyunbraced {\QSLess {#1}}{#2}}% -}% -\def\QS@f #1#2#3{\expandafter\QS@g\expandafter {#2}{#3}{#1}}% -% #2= elements < pivot, #1 = elements = pivot, #3 = elements > pivot -% Here \QSLr, \QSIr, \QSr have been let to \relax, so expansion stops. -\def\QS@g #1#2#3{\QSLr {#2}\QSIr {#1}\QSRr {#3}}% -% -\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{% - \xintFor* ##1 in {#1} \do - {\xintifForFirst {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}% -} -\def\DecoRIGHTwithPivot #1{% - \xintFor* ##1 in {#1} \do - {\xintifForFirst {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}% -} -% -\def\QSinitialize #1{\def\QS@list{\QSRr {#1}}% - \let\QSRr\DecoRIGHT -% \QS@list \par -\par\centerline{\QS@list} -} -\def\QSoneStep {\let\QSLr\DecoLEFTwithPivot - \let\QSIr\DecoINERT - \let\QSRr\DecoRIGHTwithPivot -% \QS@list -\centerline{\QS@list} -% \par - \def\QSLr {\noexpand\QS@a}% - \let\QSIr\relax - \def\QSRr {\noexpand\QS@a}% - \edef\QS@list{\QS@list}% - \let\QSLr\relax - \let\QSRr\relax - \edef\QS@list{\QS@list}% - \let\QSLr\DecoLEFT - \let\QSIr\DecoINERT - \let\QSRr\DecoRIGHT -% \QS@list -\centerline{\QS@list} -% \par -} +{\footnotesize This macro's behavior for |N| non-negative is final and will not + change. I am still hesitant about what to do with the sign of a + negative |N|.\par} -\begingroup\offinterlineskip -\small -\QSinitialize {{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}} -\QSoneStep -\QSoneStep -\QSoneStep -\QSoneStep -\QSoneStep -\endgroup +\xintAssign\xintDecSplit {0}{-123004321}\to\L\R +\centeredline{|\xintAssign\xintDecSplit {0}{-123004321}\to\L\R|} +\noindent|\meaning\L: |\digitstt{\meaning\L}, |\meaning\R: |\digitstt{\meaning\R.} +\xintAssign\xintDecSplit {5}{-123004321}\to\L\R +\centeredline{|\xintAssign\xintDecSplit {5}{-123004321}\to\L\R|} +|\meaning\L: |\digitstt{\meaning\L}, |\meaning\R: |\digitstt{\meaning\R.} +\xintAssign\xintDecSplit {9}{-123004321}\to\L\R +\centeredline{|\xintAssign\xintDecSplit {9}{-123004321}\to\L\R|} +|\meaning\L: |\digitstt{\meaning\L}, |\meaning\R: |\digitstt{\meaning\R.} +\xintAssign\xintDecSplit {10}{-123004321}\to\L\R +\centeredline{|\xintAssign\xintDecSplit {10}{-123004321}\to\L\R|} +|\meaning\L: |\digitstt{\meaning\L}, |\meaning\R: |\digitstt{\meaning\R.} +\xintAssign\xintDecSplit {-5}{-12300004321}\to\L\R +\centeredline{|\xintAssign\xintDecSplit {-5}{-12300004321}\to\L\R|} +|\meaning\L: |\digitstt{\meaning\L}, |\meaning\R: |\digitstt{\meaning\R.} +\xintAssign\xintDecSplit {-11}{-12300004321}\to\L\R +\centeredline{|\xintAssign\xintDecSplit {-11}{-12300004321}\to\L\R|} +|\meaning\L: |\digitstt{\meaning\L}, |\meaning\R: |\digitstt{\meaning\R.} +\xintAssign\xintDecSplit {-15}{-12300004321}\to\L\R +\centeredline{|\xintAssign\xintDecSplit {-15}{-12300004321}\to\L\R|} +|\meaning\L: |\digitstt{\meaning\L}, |\meaning\R: |\digitstt{\meaning\R.} -If one wants rather to have the pivot from the end of the yet to sort chunks, -then one should use the following variants: -\begin{verbatim} -\def\QS@c #1{\expandafter\QS@e\expandafter - {\romannumeral0\xintnthelt {-1}{#1}}{#1}% -}% -\def\DecoLEFTwithPivot #1{% - \xintFor* ##1 in {#1} \do - {\xintifForLast {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}% -} -\def\DecoRIGHTwithPivot #1{% - \xintFor* ##1 in {#1} \do - {\xintifForLast {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}% -} -\def\QSinitialize #1{\def\QS@list{\QSLr {#1}}% - \let\QSLr\DecoLEFT -% \QS@list \par -\par\centerline{\QS@list} -} -\end{verbatim} -\def\QS@c #1{\expandafter\QS@e\expandafter - {\romannumeral0\xintnthelt {-1}{#1}}{#1}% -}% -\def\DecoLEFTwithPivot #1{% - \xintFor* ##1 in {#1} \do - {\xintifForLast {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}% -} -\def\DecoRIGHTwithPivot #1{% - \xintFor* ##1 in {#1} \do - {\xintifForLast {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}% -} -\def\QSinitialize #1{\def\QS@list{\QSLr {#1}}% - \let\QSLr\DecoLEFT -% \QS@list \par -\par\centerline{\QS@list} -} -\begingroup\offinterlineskip -\small -\QSinitialize {{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}} -\QSoneStep -\QSoneStep -\QSoneStep -\QSoneStep -\QSoneStep -\QSoneStep -\QSoneStep -\QSoneStep -\QSoneStep -\QSoneStep -\endgroup +\subsection{\csbh{xintDecSplitL}}\label{xintDecSplitL} + +\csa{xintDecSplitL\x\n} returns the first piece after the action +of \csa{xintDecSplit}. + +\subsection{\csbh{xintDecSplitR}}\label{xintDecSplitR} + +\csa{xintDecSplitR\x\n} returns the second piece after the action +of \csa{xintDecSplit}. -\endgroup -It is possible to modify this code to let it do \csa{QSonestep} repeatedly and -stop automatically when the sort is finished. -\section{Commands of the \xintfracname package}\label{sec:comfrac} +\section{Commands of the \xintfracname package} +\label{sec:frac} \def\x{\string{x\string}} @@ -5014,7 +5604,7 @@ registers and even expressions with infix arithmetic operators, under some rules which are explained in the previous \hyperlink{useofcount}{Use of count registers} section. -As in the \hyperref[sec:comxint]{xint.sty} documentation, |x| +As in the \hyperref[sec:xint]{xint.sty} documentation, |x| stands for something which will internally be embedded in a \csa{numexpr}. It may thus be a count register or something like |4*\count 255 + 17|, etc..., but @@ -5675,7 +6265,7 @@ with (big) integers. \etocdepthtag.toc {xintexpr} \section{Expandable expressions with the \xintexprname package}% -\label{sec:comexpr} +\label{sec:expr} @@ -6325,7 +6915,8 @@ principles are necessarily different due to the aim of achieving expandability. \etocdepthtag.toc {commandsB} -\section{Commands of the \xintbinhexname package}\label{sec:combinhex} +\section{Commands of the \xintbinhexname package} +\label{sec:binhex} This package was first included in the |1.08| release of \xintname. It provides expandable conversions of arbitrarily long numbers @@ -6403,7 +6994,7 @@ one hundred hexadecimal digits. \section{Commands of the \xintgcdname package} - +\label{sec:gcd} This package was included in the original release |1.0| of the \xintname bundle. @@ -6549,7 +7140,8 @@ and modify it to what is needed. \xintTypesetBezoutAlgorithm {10000}{1113} -\section{Commands of the \xintseriesname package}\label{sec:series} +\section{Commands of the \xintseriesname package} +\label{sec:series} Some arguments to the package commands are macros which are expanded only later, when given their parameters. The arguments serving as indices are systematically @@ -7694,7 +8286,8 @@ always do it on a value computed with |D+1| truncation. % \clearpage -\section{Commands of the \xintcfracname package} +\section{Commands of the \xintcfracname package} +\label{sec:cfrac} This package was first included in release |1.04| of the \xintname bundle. @@ -8299,7 +8892,8 @@ first place. \StopEventually{\end{document}\endinput} \def\storedlinecounts {} -\def\StoreCodelineNo #1{\edef\storedlinecounts{\storedlinecounts +\def\StoreCodelineNo #1{\edef\storedlinecounts{% + \unexpanded\expandafter{\storedlinecounts}% {{#1}{\the\c@CodelineNo}}}\c@CodelineNo\z@ } \makeatother @@ -8323,45 +8917,40 @@ first place. % % \catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 % \let\relax -% \def<*xint>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } -% +% \def<*xinttools>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } % -%<*xint> -% \section {Package \xintname implementation} -% -% With release |1.09a| all macros doing arithmetic operations and a few more -% apply systematically |\xintnum| to their arguments; this adds a little -% overhead but this is more convenient for using count registers even with infix -% notation; also this is what |xintfrac.sty| did all along. Simplifies the -% discussion in the documentation too. +%<*xinttools> % \def\MARGEPAGENO{2.5em} +% \section {Package \xinttoolsnameimp implementation} +% \label{sec:toolsimp} +% +% Release |1.09g| splits off |xinttools.sty| from |xint.sty| % % \localtableofcontents +% % \subsection{Catcodes, \protect\eTeX{} and reload detection} % % The method for package identification and reload detection is copied verbatim % from the packages by \textsc{Heiko Oberdiek} (with some modifications starting -% with -% release |1.09b|). +% with release |1.09b|). % % The method for catcodes was also inspired by these packages, we proceed -% slightly differently. +% slightly differently. % % Starting with version |1.06| of the package, also |`| must be -% catcode-protected, -% because we replace everywhere in the code the twice-expansion done with -% |\expandafter| by the systematic use of |\romannumeral-`0|. +% catcode-protected, because we replace everywhere in the code the +% twice-expansion done with |\expandafter| by the systematic use of +% |\romannumeral-`0|. % % Starting with version |1.06b| I decide that I suffer from an indigestion of @ % signs, so I replace them all with underscores |_|, \`a la \LaTeX 3. % % Release |1.09b| is more economical: some macros are defined already in -% |xint.sty| and re-used in other modules. All catcode changes have been unified -% and \csa{XINT_storecatcodes} will be used by each module -% to redefine |\XINT_restorecatcodes_endinput| in case catcodes have changed -% in-between the loading of |xint.sty| and the module (not very probable -% anyhow...). -% +% |xint.sty| (now |xinttools.sty|) and re-used in other modules. All catcode +% changes have been unified and \csa{XINT_storecatcodes} will be used by each +% module to redefine |\XINT_restorecatcodes_endinput| in case catcodes have +% changed in-between the loading of |xint.sty| (now |xinttools.sty|) and the +% module (not very probable but...). % \begin{macrocode} \begingroup\catcode61\catcode48\catcode32=10\relax% \catcode13=5 % ^^M @@ -8384,7 +8973,7 @@ first place. \fi \expandafter \ifx\csname numexpr\endcsname\relax - \y{xint}{\numexpr not available, aborting input}% + \y{xinttools}{\numexpr not available, aborting input}% \aftergroup\endinput \else \ifx\x\relax % plain-TeX, first loading @@ -8393,7 +8982,7 @@ first place. \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \else - \y{xint}{I was already loaded, aborting input}% + \y{xinttools}{I was already loaded, aborting input}% \aftergroup\endinput \fi \fi @@ -8488,7 +9077,7 @@ first place. % escaping me (compatibility with LaTeX 2.09 or other things ??) seems to set % extra precautions. % -% |1.09c| uses e-\TeX{} |\ifdefined|. No |firstoftwo| etc.. yet here. +% |1.09c| uses e-\TeX{} |\ifdefined|. % \begin{macrocode} \ifdefined\ProvidesPackage \let\XINT_providespackage\relax @@ -8498,8 +9087,8 @@ first place. \expandafter\xdef\csname ver@#2.sty\endcsname{#3}}% \fi \XINT_providespackage -\ProvidesPackage {xint}% - [2013/11/04 v1.09f Expandable operations on long numbers (jfB)]% +\ProvidesPackage {xinttools}% + [2013/11/22 v1.09g Expandable and non-expandable utilities (jfB)]% % \end{macrocode} % \subsection{Token management, constants} % \lverb|In 1.09e \xint_undef replaced everywhere by \xint_bye.| @@ -8513,75 +9102,31 @@ first place. \def\xint_gobble_vi #1#2#3#4#5#6{}% \def\xint_gobble_vii #1#2#3#4#5#6#7{}% \def\xint_gobble_viii #1#2#3#4#5#6#7#8{}% -\long\def\xint_firstofone #1{#1}% becomes long in 1.09f, 2013/11/01 +\long\def\xint_firstofone #1{#1}% long since 1.09f, 2013/11/01 \xint_firstofone{\let\XINT_sptoken= } % 1.09d, 2013/10/22 -\long\def\xint_firstoftwo #1#2{#1}% made long in 1.09e, 2013/10/28 -\long\def\xint_secondoftwo #1#2{#2}% +\long\def\xint_firstoftwo #1#2{#1}% long since 1.09e, 2013/10/28 +\long\def\xint_secondoftwo #1#2{#2}% idem \def\xint_firstoftwo_andstop #1#2{ #1}% \def\xint_secondoftwo_andstop #1#2{ #2}% -\def\xint_exchangetwo_keepbraces_andstop #1#2{ {#2}{#1}}% -\def\xint_firstofthree #1#2#3{#1}% -\def\xint_secondofthree #1#2#3{#2}% -\def\xint_thirdofthree #1#2#3{#3}% \def\xint_minus_andstop { -}% -\long\def\xint_bye #1\xint_bye {}% becomes long in 1.09f \def\xint_gob_til_R #1\R {}% \def\xint_gob_til_W #1\W {}% \def\xint_gob_til_Z #1\Z {}% -\def\xint_gob_til_zero #10{}% -\def\xint_gob_til_one #11{}% -\def\xint_gob_til_G #1G{}% -\def\xint_gob_til_minus #1-{}% -\def\xint_gob_til_zeros_iii #1000{}% -\def\xint_gob_til_zeros_iv #10000{}% +\long\def\xint_bye #1\xint_bye {}% long since 1.09f \let\xint_relax\relax \def\xint_brelax {\xint_relax }% -\def\xint_gob_til_relax #1\relax {}% -\long\def\xint_gob_til_xint_relax #1\xint_relax {}% becomes long in 1.09f -\def\xint_UDzerofork #10\dummy #2#3\krof {#2}% -\def\xint_UDsignfork #1-\dummy #2#3\krof {#2}% -\def\xint_UDwfork #1\W\dummy #2#3\krof {#2}% -\def\xint_UDzerosfork #100\dummy #2#3\krof {#2}% -\def\xint_UDonezerofork #110\dummy #2#3\krof {#2}% -\def\xint_UDzerominusfork #10-\dummy #2#3\krof {#2}% -\def\xint_UDsignsfork #1--\dummy #2#3\krof {#2}% +\long\def\xint_gob_til_xint_relax #1\xint_relax {}% long since 1.09f \def\xint_afterfi #1#2\fi {\fi #1}% \chardef\xint_c_ 0 -\chardef\xint_c_i 1 -\chardef\xint_c_ii 2 -\chardef\xint_c_iii 3 -\chardef\xint_c_iv 4 -\chardef\xint_c_v 5 \chardef\xint_c_viii 8 -\chardef\xint_c_ix 9 -\chardef\xint_c_x 10 -\newcount\xint_c_x^viii \xint_c_x^viii 100000000 \newtoks\XINT_toks +\newcount\XINT_count % 1.09g: \xintFor from 1.09f modified \count 255 :-( % \end{macrocode} -% \subsection{\csh{xintRev}, \csh{xintReverseOrder}} -% \lverb|& -% \xintRev: fait l'expansion avec \romannumeral-`0, vérifie le signe.$\ -% \xintReverseOrder: ne fait PAS l'expansion, ne regarde PAS le signe.| +% \subsection{ \csh{xintReverseOrder}} +% \lverb|\xintReverseOrder: does NOT expand its argument| % \begin{macrocode} -\def\xintRev {\romannumeral0\xintrev }% -\def\xintrev #1% -{% - \expandafter\XINT_rev_fork - \romannumeral-`0#1\xint_relax % empty #1 ok, \xint_relax stops expansion - \xint_bye\xint_bye\xint_bye\xint_bye - \xint_bye\xint_bye\xint_bye\xint_bye - \xint_relax -}% -\def\XINT_rev_fork #1% -{% - \xint_UDsignfork - #1\dummy {\expandafter\xint_minus_andstop\romannumeral0\XINT_rord_main {}}% - -\dummy {\XINT_rord_main {}#1}% - \krof -}% -\def\XINT_Rev {\romannumeral0\XINT_rev }% -\def\xintReverseOrder {\romannumeral0\XINT_rev }% -\def\XINT_rev #1% +\def\xintReverseOrder {\romannumeral0\xintreverseorder }% +\def\xintreverseorder #1% {% \XINT_rord_main {}#1% \xint_relax @@ -8601,8 +9146,7 @@ first place. % \end{macrocode} % \subsection{\csh{xintRevWithBraces}} % \lverb|New with 1.06. Makes the expansion of its argument and then reverses -% the -% resulting tokens or braced tokens, adding a pair of braces to each (thus, +% the resulting tokens or braced tokens, adding a pair of braces to each (thus, % maintaining it when it was already there. % % As in some other places, 1.09e replaces \Z by \xint_bye, although here it is @@ -8652,44 +9196,22 @@ first place. \csname xint_gobble_\romannumeral #1\endcsname }% % \end{macrocode} -% \subsection{\csh{xintLen}, \csh{xintLength}} -% \lverb|& -% \xintLen -> fait l'expansion, ne compte PAS le signe.$\ -% \xintLength -> ne fait PAS l'expansion, compte le signe.$\ +% \subsection{\csh{xintLength}} +% \lverb|\xintLength does NOT expand its argument.$\ +% 1.09g adds the missing \xintlength, which was previously called \XINT_length, +% and suppresses \XINT_Length$\ % 1.06: improved code is roughly 20$% faster than the one from earlier % versions. 1.09a, \xintnum inserted. 1.09e: \Z->\xint_bye as this is called % from \xintNthElt, and there it was necessary not to use \Z. Later use of \Z % and \W perfectly safe here.| % \begin{macrocode} -\def\xintLen {\romannumeral0\xintlen }% -\def\xintlen #1% -{% - \expandafter\XINT_length_fork - \romannumeral0\xintnum{#1}\xint_relax\xint_relax\xint_relax\xint_relax - \xint_relax\xint_relax\xint_relax\xint_relax\xint_bye -}% -\def\XINT_Len #1% -{% - \romannumeral0\XINT_length_fork - #1\xint_relax\xint_relax\xint_relax\xint_relax - \xint_relax\xint_relax\xint_relax\xint_relax\xint_bye -}% -\def\XINT_length_fork #1% -{% - \expandafter\XINT_length_loop - \xint_UDsignfork - #1\dummy {{0}}% - -\dummy {{0}#1}% - \krof -}% -\def\XINT_Length {\romannumeral0\XINT_length }% -\def\XINT_length #1% +\def\xintLength {\romannumeral0\xintlength }% +\def\xintlength #1% {% \XINT_length_loop {0}#1\xint_relax\xint_relax\xint_relax\xint_relax \xint_relax\xint_relax\xint_relax\xint_relax\xint_bye }% -\let\xintLength\XINT_Length \def\XINT_length_loop #1#2#3#4#5#6#7#8#9% {% \xint_gob_til_xint_relax #9\XINT_length_finish_a\xint_relax @@ -9245,6 +9767,43 @@ first place. }% \def\XINT_seqo_nd #1#2#3#4{\XINT_seqo_nb {#1}{#2}{#3}{#4{#1}}}% % \end{macrocode} +%\subsection{\csh{xintloop}, \csh{xintbreakloop}, \csh{xintbreakloopanddo}, +% \csh{xintloopskiptonext}} +% \lverb|1.09g [2013/11/22]| +% \begin{macrocode} +\def\xintloop #1#2\repeat {#1#2\xintloop_again\fi\xint_gobble_i {#1#2}}% +\def\xintloop_again\fi\xint_gobble_i #1{\fi + #1\xintloop_again\fi\xint_gobble_i {#1}}% +\def\xintbreakloop #1\xintloop_again\fi\xint_gobble_i #2{}% +\def\xintbreakloopanddo #1#2\xintloop_again\fi\xint_gobble_i #3{#1}% +\def\xintloopskiptonext #1\xintloop_again\fi\xint_gobble_i #2{% + #2\xintloop_again\fi\xint_gobble_i {#2}}% +% \end{macrocode} +% \subsection{\csh{xintiloop}, \csh{xintiloopindex}, \csh{xintouteriloopindex}, +% \csh{xintbreakiloop}, \csh{xintbreakiloopanddo}, \csh{xintiloopskiptonext}, +% \csh{xintiloopskipandredo}} +% \lverb|1.09g [2013/11/22]| +% \begin{macrocode} +\def\xintiloop [#1+#2]{% + \expandafter\xintiloop_a\the\numexpr #1\expandafter.\the\numexpr #2.}% +\def\xintiloop_a #1.#2.#3#4\repeat{% + #3#4\xintiloop_again\fi\xint_gobble_iii {#1}{#2}{#3#4}}% +\def\xintiloop_again\fi\xint_gobble_iii #1#2{% + \fi\expandafter\xintiloop_again_b\the\numexpr#1+#2.#2.}% +\def\xintiloop_again_b #1.#2.#3{% + #3\xintiloop_again\fi\xint_gobble_iii {#1}{#2}{#3}}% +\def\xintbreakiloop #1\xintiloop_again\fi\xint_gobble_iii #2#3#4{}% +\def\xintbreakiloopanddo #1.#2\xintiloop_again\fi\xint_gobble_iii #3#4#5{#1}% +\def\xintiloopindex #1\xintiloop_again\fi\xint_gobble_iii #2% + {#2#1\xintiloop_again\fi\xint_gobble_iii {#2}}% +\def\xintouteriloopindex #1\xintiloop_again + #2\xintiloop_again\fi\xint_gobble_iii #3% + {#3#1\xintiloop_again #2\xintiloop_again\fi\xint_gobble_iii {#3}}% +\def\xintiloopskiptonext #1\xintiloop_again\fi\xint_gobble_iii #2#3{% + \expandafter\xintiloop_again_b \the\numexpr#2+#3.#3.}% +\def\xintiloopskipandredo #1\xintiloop_again\fi\xint_gobble_iii #2#3#4{% + #4\xintiloop_again\fi\xint_gobble_iii {#2}{#3}{#4}}% +% \end{macrocode} % \subsection{\csh{XINT\_xflet}} % \lverb|1.09e [2013/10/29]: we expand fully unbraced tokens and swallow arising % space tokens until the dust settles. For treating cases @@ -9314,14 +9873,15 @@ first place. % expand unbraced item elements and this is in fact convenient to simulate % insertion of lists in others. % -% 1.09e: the applied macro is allowed to be long, with items containing -% explicit \par's. +% 1.09e: the applied macro is allowed to be long, with items (or the first fixed +% arguments of he macro, passed together with it as #1 to \xintApplyInline) +% containing explicit \par's. (1.09g: some missing \long's added) % -% 1.09f: terminator used to be z, now Z (still catcode 3). +% 1.09f: terminator used to be z, now Z (still catcode 3). %| % \begin{macrocode} -\catcode`Z 3% -\def\xintApplyInline #1#2% +\catcode`Z 3 +\long\def\xintApplyInline #1#2% {% \long\expandafter\def\expandafter\XINT_inline_macro \expandafter ##\expandafter 1\expandafter {#1{##1}}% @@ -9330,24 +9890,22 @@ first place. \def\XINT_inline_b {% \ifx\XINT_token Z\expandafter\xint_gobble_i - \else\expandafter\XINT_inline_d - \fi + \else\expandafter\XINT_inline_d\fi }% -\def\XINT_inline_d #1% +\long\def\XINT_inline_d #1% {% - \def\XINT_item{{#1}}\XINT_xflet\XINT_inline_e + \long\def\XINT_item{{#1}}\XINT_xflet\XINT_inline_e }% \def\XINT_inline_e {% \ifx\XINT_token Z\expandafter\XINT_inline_w - \else\expandafter\XINT_inline_f - \fi + \else\expandafter\XINT_inline_f\fi }% \def\XINT_inline_f {% \expandafter\XINT_inline_g\expandafter{\XINT_inline_macro {##1}}% }% -\def\XINT_inline_g #1% +\long\def\XINT_inline_g #1% {% \expandafter\XINT_inline_macro\XINT_item \long\def\XINT_inline_macro ##1{#1}\XINT_inline_d @@ -9401,8 +9959,11 @@ first place. % If the \XINT_forever branch is taken, the added space will not be a problem % there. % -% [2013/11/03]: 1.09f rewrites the code to allow all macro parameters from #1 to -% #9 in \xintFor, \xintFor*, and \XINT_forever. | +% 1.09f rewrites (2013/11/03) the code which now allows all macro parameters +% from #1 to #9 in \xintFor, \xintFor*, and \XINT_forever. +% +% 1.09g \xintFor and \xintFor* modified the value of \count 255, now uses +% \XINT_count. | % \begin{macrocode} \def\XINT_tmpa #1#2{\ifnum #2<#1 \xint_afterfi {{#########2}}\fi}% \def\XINT_tmpb #1#2{\ifnum #1<#2 \xint_afterfi {{#########2}}\fi}% @@ -9440,9 +10001,9 @@ first place. }% \long\def\XINT_for #1#2in#3#4#5% {% - \count 255 #2\relax + \XINT_count #2\relax \expandafter\XINT_toks\expandafter - {\expandafter\XINT_for_d\the\count 255{#5}}% + {\expandafter\XINT_for_d\the\XINT_count{#5}}% \def\XINT_flet_macro {\expandafter\XINT_for_forever?\space}% \expandafter\XINT_flet_zapsp #3Z% }% @@ -9456,9 +10017,9 @@ first place. \def\XINT_to_forever\fi #1\xintcsvtolist #2{\fi \XINT_forever #2}% \long\def\XINT_forx *#1#2in#3#4#5% {% - \count 255 #2\relax + \XINT_count #2\relax \expandafter\XINT_toks\expandafter - {\expandafter\XINT_forx_d\the\count 255{#5}}% + {\expandafter\XINT_forx_d\the\XINT_count{#5}}% \XINT_xflet\XINT_forx_forever? #3Z% }% \def\XINT_forx_forever? @@ -9725,12 +10286,12 @@ first place. \XINT_restoreescapechar \expandafter\let\expandafter\xint_temp \csname\xint_arrayname 0\endcsname - \count 255 0 + \XINT_count 0 \loop \global\expandafter\let - \csname\xint_arrayname\the\count255\endcsname\relax - \ifnum \count 255 < \xint_temp - \advance\count 255 1 + \csname\xint_arrayname\the\XINT_count\endcsname\relax + \ifnum \XINT_count < \xint_temp + \advance\XINT_count 1 \repeat \global\expandafter\let\csname\xint_arrayname 00\endcsname\relax \global\let #1\relax @@ -9741,7 +10302,7 @@ first place. \escapechar -1 \edef\xint_arrayname {\string #2}% \XINT_restoreescapechar - \count 255 0 + \XINT_count 0 \expandafter\XINT_assignarray_loop \romannumeral-`0#1\xint_relax \csname\xint_arrayname 00\endcsname \csname\xint_arrayname 0\endcsname @@ -9752,12 +10313,12 @@ first place. {% \def\xint_temp {#1}% \ifx\xint_brelax\xint_temp - \expandafter\edef\csname\xint_arrayname 0\endcsname{\the\count 255 }% + \expandafter\edef\csname\xint_arrayname 0\endcsname{\the\XINT_count }% \expandafter\expandafter\expandafter\XINT_assignarray_end_a \else - \advance\count 255 1 + \advance\XINT_count 1 \expandafter\edef - \csname\xint_arrayname\the\count 255\endcsname{\xint_temp }% + \csname\xint_arrayname\the\XINT_count\endcsname{\xint_temp }% \expandafter\XINT_assignarray_loop \fi }% @@ -9793,6 +10354,205 @@ first place. }% }% \let\xintDigitsOf\xintAssignArray +\XINT_restorecatcodes_endinput% +% \end{macrocode} +%\catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 +%\let\relax +%\def<*xint>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } +% +%<*xint> +% +% \StoreCodelineNo {xinttools} +% +% \section{Package \xintnameimp implementation} +% \label{sec:xintimp} +% +% With release |1.09a| all macros doing arithmetic operations and a few more +% apply systematically |\xintnum| to their arguments; this adds a little +% overhead but this is more convenient for using count registers even with infix +% notation; also this is what |xintfrac.sty| did all along. Simplifies the +% discussion in the documentation too. +% +% \localtableofcontents +% +% \subsection{Catcodes, \protect\eTeX{} and reload detection} +% +% The code for reload detection is copied from \textsc{Heiko +% Oberdiek}'s packages, and adapted here to check for previous +% loading of the master \xintname package. +% +% The method for catcodes is slightly different, but still +% directly inspired by these packages. +% +% \begin{macrocode} +\begingroup\catcode61\catcode48\catcode32=10\relax% + \catcode13=5 % ^^M + \endlinechar=13 % + \catcode123=1 % { + \catcode125=2 % } + \catcode64=11 % @ + \catcode35=6 % # + \catcode44=12 % , + \catcode45=12 % - + \catcode46=12 % . + \catcode58=12 % : + \def\space { }% + \let\z\endgroup + \expandafter\let\expandafter\x\csname ver@xint.sty\endcsname + \expandafter\let\expandafter\w\csname ver@xinttools.sty\endcsname + \expandafter + \ifx\csname PackageInfo\endcsname\relax + \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \else + \def\y#1#2{\PackageInfo{#1}{#2}}% + \fi + \expandafter + \ifx\csname numexpr\endcsname\relax + \y{xint}{\numexpr not available, aborting input}% + \aftergroup\endinput + \else + \ifx\x\relax % plain-TeX, first loading of xint.sty + \ifx\w\relax % but xinttools.sty not yet loaded. + \y{xint}{Package xinttools is required}% + \y{xint}{Will try \string\input\space xinttools.sty}% + \def\z{\endgroup\input xinttools.sty\relax}% + \fi + \else + \def\empty {}% + \ifx\x\empty % LaTeX, first loading, + % variable is initialized, but \ProvidesPackage not yet seen + \ifx\w\relax % xinttools.sty not yet loaded. + \y{xint}{Package xinttools is required}% + \y{xint}{Will try \string\RequirePackage{xinttools}}% + \def\z{\endgroup\RequirePackage{xinttools}}% + \fi + \else + \y{xint}{I was already loaded, aborting input}% + \aftergroup\endinput + \fi + \fi + \fi +\z% +% \end{macrocode} +% \subsection{Confirmation of \xinttoolsname loading} +% \begin{macrocode} +\begingroup\catcode61\catcode48\catcode32=10\relax% + \catcode13=5 % ^^M + \endlinechar=13 % + \catcode123=1 % { + \catcode125=2 % } + \catcode64=11 % @ + \catcode35=6 % # + \catcode44=12 % , + \catcode45=12 % - + \catcode46=12 % . + \catcode58=12 % : + \ifdefined\PackageInfo + \def\y#1#2{\PackageInfo{#1}{#2}}% + \else + \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \fi + \def\empty {}% + \expandafter\let\expandafter\w\csname ver@xinttools.sty\endcsname + \ifx\w\relax % Plain TeX, user gave a file name at the prompt + \y{xint}{Loading of package xinttools failed, aborting input}% + \aftergroup\endinput + \fi + \ifx\w\empty % LaTeX, user gave a file name at the prompt + \y{xint}{Loading of package xinttools failed, aborting input}% + \aftergroup\endinput + \fi +\endgroup% +% \end{macrocode} +% \subsection{Catcodes} +% \begin{macrocode} +\XINTsetupcatcodes% +% \end{macrocode} +% \subsection{Package identification} +% \begin{macrocode} +\XINT_providespackage +\ProvidesPackage{xint}% + [2013/11/22 v1.09g Expandable operations on long numbers (jfB)]% +% \end{macrocode} +% \subsection{Token management, constants} +% \begin{macrocode} +\def\xint_firstofthree #1#2#3{#1}% +\def\xint_secondofthree #1#2#3{#2}% +\def\xint_thirdofthree #1#2#3{#3}% +\def\xint_gob_til_zero #10{}% +\def\xint_gob_til_zeros_iii #1000{}% +\def\xint_gob_til_zeros_iv #10000{}% +\def\xint_gob_til_one #11{}% +\def\xint_gob_til_G #1G{}% +\def\xint_gob_til_minus #1-{}% +\def\xint_gob_til_relax #1\relax {}% +\def\xint_exchangetwo_keepbraces_andstop #1#2{ {#2}{#1}}% +\def\xint_UDzerofork #10\dummy #2#3\krof {#2}% +\def\xint_UDsignfork #1-\dummy #2#3\krof {#2}% +\def\xint_UDwfork #1\W\dummy #2#3\krof {#2}% +\def\xint_UDzerosfork #100\dummy #2#3\krof {#2}% +\def\xint_UDonezerofork #110\dummy #2#3\krof {#2}% +\def\xint_UDzerominusfork #10-\dummy #2#3\krof {#2}% +\def\xint_UDsignsfork #1--\dummy #2#3\krof {#2}% +\chardef\xint_c_i 1 % 0 and 8 in xinttools +\chardef\xint_c_ii 2 +\chardef\xint_c_iii 3 +\chardef\xint_c_iv 4 +\chardef\xint_c_v 5 +\chardef\xint_c_ix 9 +\chardef\xint_c_x 10 +\newcount\xint_c_x^viii \xint_c_x^viii 100000000 +% \end{macrocode} +% \subsection{\csh{xintRev}} +% \lverb|& +% \xintRev: expands fully its argument \romannumeral-`0, and checks the sign. +% However this last aspect does not appear like a very useful thing. And despite +% the fact that a special check is made for a sign, actually the input is not +% given to \xintnum, contrarily to \xintLen. This is all a bit incoherent. +% Should be fixed.| +% \begin{macrocode} +\def\xintRev {\romannumeral0\xintrev }% +\def\xintrev #1% +{% + \expandafter\XINT_rev_fork + \romannumeral-`0#1\xint_relax % empty #1 ok, \xint_relax stops expansion + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_bye\xint_bye\xint_bye\xint_bye + \xint_relax +}% +\def\XINT_rev_fork #1% +{% + \xint_UDsignfork + #1\dummy {\expandafter\xint_minus_andstop\romannumeral0\XINT_rord_main {}}% + -\dummy {\XINT_rord_main {}#1}% + \krof +}% +% \end{macrocode} +% \subsection{\csh{xintLen}} +% \lverb|\xintLen is ONLY for (possibly long) integers. Gets extended to +% fractions by xintfrac.sty| +% \begin{macrocode} +\def\xintLen {\romannumeral0\xintlen }% +\def\xintlen #1% +{% + \expandafter\XINT_len_fork + \romannumeral0\xintnum{#1}\xint_relax\xint_relax\xint_relax\xint_relax + \xint_relax\xint_relax\xint_relax\xint_relax\xint_bye +}% +\def\XINT_Len #1% variant which does not expand via \xintnum. +{% + \romannumeral0\XINT_len_fork + #1\xint_relax\xint_relax\xint_relax\xint_relax + \xint_relax\xint_relax\xint_relax\xint_relax\xint_bye +}% +\def\XINT_len_fork #1% +{% + \expandafter\XINT_length_loop + \xint_UDsignfork + #1\dummy {{0}}% + -\dummy {{0}#1}% + \krof +}% % \end{macrocode} % \subsection{\csh{XINT\_RQ}} % \lverb|& @@ -11640,28 +12400,28 @@ first place. \def\XINT_mul_minusminus #1#2% {% \expandafter\XINT_mul_choice_a - \expandafter{\romannumeral0\XINT_length {#2}}% - {\romannumeral0\XINT_length {#1}}{#1}{#2}% + \expandafter{\romannumeral0\xintlength {#2}}% + {\romannumeral0\xintlength {#1}}{#1}{#2}% }% \def\XINT_mul_minusplus #1#2#3% {% \expandafter\xint_minus_andstop\romannumeral0\expandafter \XINT_mul_choice_a - \expandafter{\romannumeral0\XINT_length {#1#3}}% - {\romannumeral0\XINT_length {#2}}{#2}{#1#3}% + \expandafter{\romannumeral0\xintlength {#1#3}}% + {\romannumeral0\xintlength {#2}}{#2}{#1#3}% }% \def\XINT_mul_plusminus #1#2#3% {% \expandafter\xint_minus_andstop\romannumeral0\expandafter \XINT_mul_choice_a - \expandafter{\romannumeral0\XINT_length {#3}}% - {\romannumeral0\XINT_length {#1#2}}{#1#2}{#3}% + \expandafter{\romannumeral0\xintlength {#3}}% + {\romannumeral0\xintlength {#1#2}}{#1#2}{#3}% }% \def\XINT_mul_plusplus #1#2#3#4% {% \expandafter\XINT_mul_choice_a - \expandafter{\romannumeral0\XINT_length {#2#4}}% - {\romannumeral0\XINT_length {#1#3}}{#1#3}{#2#4}% + \expandafter{\romannumeral0\xintlength {#2#4}}% + {\romannumeral0\xintlength {#1#3}}{#1#3}{#2#4}% }% \def\XINT_mul_choice_a #1#2% {% @@ -11826,7 +12586,7 @@ first place. \def\XINT_mul_M_zero #1\Z\Z\Z\Z { 0}% \def\XINT_mul_M_one #1#2#3#4\Z\Z\Z\Z {% - \expandafter\xint_cleanupzeros_andstop\romannumeral0\XINT_rev{#4}% + \expandafter\xint_cleanupzeros_andstop\romannumeral0\xintreverseorder{#4}% }% \def\XINT_mul_N #1#2#3#4#5#6#7% {% @@ -11958,7 +12718,7 @@ first place. }% \def\XINT_mul_finish_c #1\XINT_mul_finish_ciii \W\W\W\W #2#3\Z\Z\Z\Z {% - \expandafter\xint_cleanupzeros_andstop\romannumeral0\XINT_rev{#2}% + \expandafter\xint_cleanupzeros_andstop\romannumeral0\xintreverseorder{#2}% }% % \end{macrocode} % \lverb|& @@ -12122,8 +12882,8 @@ first place. % Modified with 1.02 and again in 1.03 for greater efficiency. I am % tempted, % here and elsewhere, to use \ifcase\XINT_Geq {#1}{1000000000} rather than -% \ifnum\XINT_Length {#1}>9 but for the time being I leave things as they stand. -% With release 1.05, rather than using \XINT_Length I opt finally for direct use +% \ifnum\xintLength {#1}>9 but for the time being I leave things as they stand. +% With release 1.05, rather than using \xintLength I opt finally for direct use % of \numexpr (which will throw a suitable number too big message), and to raise % the \xintError:$\ FactorialOfTooBigNumber for argument larger than 1000000 % (rather than 1000000000). With 1.09a, \xintFac uses \xintnum.| @@ -12402,7 +13162,7 @@ first place. \def\XINT_pow_pprod_end\relax\XINT_pow_pprod_compute #1\Z #2% {% \expandafter\xint_cleanupzeros_andstop - \romannumeral0\XINT_rev {#2}% + \romannumeral0\xintreverseorder {#2}% }% % \end{macrocode} % \subsection{\csh{xintDivision}, \csh{xintQuo}, \csh{xintRem}} @@ -12546,7 +13306,7 @@ first place. \def\XINT_div_prepare #1% {% \expandafter \XINT_div_prepareB_aa \expandafter - {\romannumeral0\XINT_length {#1}}{#1}% B > 0 ici + {\romannumeral0\xintlength {#1}}{#1}% B > 0 ici }% \def\XINT_div_prepareB_aa #1% {% @@ -12607,7 +13367,7 @@ first place. \def\XINT_div_prepareB_f #1#2#3#4#5\Z {% \expandafter \XINT_div_prepareB_g \expandafter - {\romannumeral0\XINT_rev {#1#2#3#4#5}}{#1#2#3#4}% + {\romannumeral0\xintreverseorder {#1#2#3#4#5}}{#1#2#3#4}% }% % \end{macrocode} % \lverb|& @@ -12627,7 +13387,7 @@ first place. \def\XINT_div_prepareA_a #1% {% \expandafter \XINT_div_prepareA_b \expandafter - {\romannumeral0\XINT_length {#1}}{#1}% A >0 ici + {\romannumeral0\xintlength {#1}}{#1}% A >0 ici }% % \end{macrocode} % \lverb|& @@ -12907,7 +13667,7 @@ first place. {% \expandafter \XINT_div_body_l \expandafter {\romannumeral0\XINT_div_sub_xpxp - {\romannumeral0\XINT_mul_Mr {#1}#4\Z\Z\Z\Z }{\XINT_Rev{#2}}}% + {\romannumeral0\XINT_mul_Mr {#1}#4\Z\Z\Z\Z }{\xintReverseOrder{#2}}}% {#3+#1}% }% % \end{macrocode} @@ -13144,7 +13904,7 @@ first place. \def\XINT_LDg #1{\romannumeral0\XINT_ldg {#1}}% \def\XINT_ldg #1% {% - \expandafter\XINT_ldg_\romannumeral0\XINT_rev {#1}\Z + \expandafter\XINT_ldg_\romannumeral0\xintreverseorder {#1}\Z }% \def\XINT_ldg_ #1#2\Z{ #1}% % \end{macrocode} @@ -13246,16 +14006,16 @@ first place. \def\XINT_DSR #1{\romannumeral0\XINT_dsr_a {#1}\W\Z }% \def\XINT_dsr_a {% - \expandafter\XINT_dsr_b\romannumeral0\XINT_rev + \expandafter\XINT_dsr_b\romannumeral0\xintreverseorder }% \def\XINT_dsr_b #1#2#3\Z {% \xint_gob_til_W #2\xint_dsr_onedigit\W \xint_gob_til_minus #2\xint_dsr_onedigit-% \expandafter\XINT_dsr_removew - \romannumeral0\XINT_rev {#2#3}% + \romannumeral0\xintreverseorder {#2#3}% }% -\def\xint_dsr_onedigit #1\XINT_rev #2{ 0}% +\def\xint_dsr_onedigit #1\xintreverseorder #2{ 0}% \def\XINT_dsr_removew #1\W { }% % \end{macrocode} % \subsection{\csh{xintDSH}, \csh{xintDSHr}} @@ -13583,7 +14343,7 @@ first place. \def\XINT_split_fromright #1\Z #2% {% \expandafter \XINT_split_fromright_a \expandafter - {\romannumeral0\XINT_rev {#2}}{#1}{#2}% + {\romannumeral0\xintreverseorder {#2}}{#1}{#2}% }% \def\XINT_split_fromright_a #1#2% {% @@ -13611,7 +14371,7 @@ first place. }% \def\XINT_split_fromright_endsplit_ #1#2\W #3\Z #4% {% - \expandafter\space\expandafter {\romannumeral0\XINT_rev{#2}}{#1}% + \expandafter\space\expandafter {\romannumeral0\xintreverseorder {#2}}{#1}% }% \def\XINT_split_fromright_endsplit_i #1#2% {\XINT_split_fromright_checkiftoofar #2{#2#1}}% @@ -13853,7 +14613,7 @@ first place. \def\XINT_sqrt #1\Z {% \expandafter\XINT_sqrt_start\expandafter - {\romannumeral0\XINT_length {#1}}{#1}% + {\romannumeral0\xintlength {#1}}{#1}% }% \def\XINT_sqrt_start #1% {% @@ -14040,7 +14800,8 @@ first place. % % \StoreCodelineNo {xint} % -% \section{Package \xintbinhexname implementation} +% \section{Package \xintbinhexnameimp implementation} +% \label{sec:binheximp} % % The commenting is currently (\docdate) very sparse. % @@ -14135,11 +14896,6 @@ first place. \endgroup% % \end{macrocode} % \subsection{Catcodes} -% -% Perhaps catcodes have changed after the loading of \xintname -% and prior to the current loading of \xintbinhexname, so we redefine -% the |\XINT_restorecatcodes_endinput| in this style file. -% % \begin{macrocode} \XINTsetupcatcodes% % \end{macrocode} @@ -14147,7 +14903,7 @@ first place. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintbinhex}% - [2013/11/04 v1.09f Expandable binary and hexadecimal conversions (jfB)]% + [2013/11/22 v1.09g Expandable binary and hexadecimal conversions (jfB)]% % \end{macrocode} % \subsection{Constants, etc...} % \lverb!v1.08! @@ -14748,7 +15504,8 @@ first place. % % \StoreCodelineNo {xintbinhex} % -% \section{Package \xintgcdname implementation} +% \section{Package \xintgcdnameimp implementation} +% \label{sec:gcdimp} % % The commenting is currently (\docdate) very sparse. % @@ -14850,7 +15607,7 @@ first place. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintgcd}% - [2013/11/04 v1.09f Euclide algorithm with xint package (jfB)]% + [2013/11/22 v1.09g Euclide algorithm with xint package (jfB)]% % \end{macrocode} % \subsection{\csh{xintGCD}} % The macros of |1.09a| benefits from the |\xintnum| which has been inserted @@ -15396,15 +16153,15 @@ first place. \edef\A{\U2}\edef\B{\U4}\edef\N{\U1}% \setbox 0 \vbox{\halign {$##$\cr \A\cr \B \cr}}% \noindent - \count 255 1 + \XINT_count 1 \loop - \hbox to \wd 0 {\hfil$\U{\numexpr 2*\count 255\relax}$}% - ${} = \U{\numexpr 2*\count 255 + 3\relax} - \times \U{\numexpr 2*\count 255 + 2\relax} - + \U{\numexpr 2*\count 255 + 4\relax}$% - \ifnum \count 255 < \N + \hbox to \wd 0 {\hfil$\U{\numexpr 2*\XINT_count\relax}$}% + ${} = \U{\numexpr 2*\XINT_count + 3\relax} + \times \U{\numexpr 2*\XINT_count + 2\relax} + + \U{\numexpr 2*\XINT_count + 4\relax}$% + \ifnum \XINT_count < \N \hfill\break - \advance \count 255 1 + \advance \XINT_count 1 \repeat \par \endgroup @@ -15429,24 +16186,24 @@ first place. \xintAssignArray\xintBezoutAlgorithm {#1}{#2}\to\BEZ \edef\A{\BEZ2}\edef\B{\BEZ6}\edef\N{\BEZ1}% A = |#1|, B = |#2| \setbox 0 \vbox{\halign {$##$\cr \A\cr \B \cr}}% - \count 255 1 + \XINT_count 1 \loop \noindent - \hbox to \wd 0 {\hfil$\BEZ{4*\count 255 - 2}$}% - ${} = \BEZ{4*\count 255 + 5} - \times \BEZ{4*\count 255 + 2} - + \BEZ{4*\count 255 + 6}$\hfill\break - \hbox to \wd 0 {\hfil$\BEZ{4*\count 255 +7}$}% - ${} = \BEZ{4*\count 255 + 5} - \times \BEZ{4*\count 255 + 3} - + \BEZ{4*\count 255 - 1}$\hfill\break - \hbox to \wd 0 {\hfil$\BEZ{4*\count 255 +8}$}% - ${} = \BEZ{4*\count 255 + 5} - \times \BEZ{4*\count 255 + 4} - + \BEZ{4*\count 255 }$ + \hbox to \wd 0 {\hfil$\BEZ{4*\XINT_count - 2}$}% + ${} = \BEZ{4*\XINT_count + 5} + \times \BEZ{4*\XINT_count + 2} + + \BEZ{4*\XINT_count + 6}$\hfill\break + \hbox to \wd 0 {\hfil$\BEZ{4*\XINT_count +7}$}% + ${} = \BEZ{4*\XINT_count + 5} + \times \BEZ{4*\XINT_count + 3} + + \BEZ{4*\XINT_count - 1}$\hfill\break + \hbox to \wd 0 {\hfil$\BEZ{4*\XINT_count +8}$}% + ${} = \BEZ{4*\XINT_count + 5} + \times \BEZ{4*\XINT_count + 4} + + \BEZ{4*\XINT_count }$ \endgraf - \ifnum \count 255 < \N - \advance \count 255 1 + \ifnum \XINT_count < \N + \advance \XINT_count 1 \repeat \par \edef\U{\BEZ{4*\N + 4}}% @@ -15470,7 +16227,8 @@ first place. % % \StoreCodelineNo {xintgcd} % -% \section{Package \xintfracname implementation} +% \section{Package \xintfracnameimp implementation} +% \label{sec:fracimp} % % The commenting is currently (\docdate) very sparse. % @@ -15572,7 +16330,7 @@ first place. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintfrac}% - [2013/11/04 v1.09f Expandable operations on fractions (jfB)]% + [2013/11/22 v1.09g Expandable operations on fractions (jfB)]% \chardef\xint_c_vi 6 \chardef\xint_c_vii 7 \chardef\xint_c_xviii 18 @@ -15733,7 +16491,7 @@ first place. \def\XINT_frac_Bb #1.\W\Z #2\Z {% \expandafter \XINT_frac_T \expandafter - {\romannumeral0\XINT_length {#1}}{#2#1}% + {\romannumeral0\xintlength {#1}}{#2#1}% }% \def\XINT_frac_A e\W\Z {\XINT_frac_T {0}{1}{0}}% \def\XINT_frac_T #1#2#3#4e#5#6\Z @@ -15758,7 +16516,7 @@ first place. \def\XINT_frac_Cb #1.\W\Z #2\Z {% \expandafter\XINT_frac_D\expandafter - {\romannumeral0\XINT_length {#1}}{#2#1}% + {\romannumeral0\xintlength {#1}}{#2#1}% }% \def\XINT_frac_D #1#2#3#4#5#6% {% @@ -16440,7 +17198,7 @@ first place. {% \xint_gob_til_zero #2\XINT_trunc_zero 0% \expandafter\XINT_trunc_H\expandafter - {\the\numexpr\romannumeral0\XINT_length {#1}-#3}{#3}{#1}#2% + {\the\numexpr\romannumeral0\xintlength {#1}-#3}{#3}{#1}#2% }% \def\XINT_trunc_zero 0#10{ 0}% \def\XINT_trunc_H #1#2% @@ -16634,7 +17392,7 @@ first place. \def\XINT_float_Mc #1#2#3#4#5#6% {% \expandafter\XINT_float_N\expandafter - {\romannumeral0\XINT_length{#6}}{#2}{#5}{#6}{#1}{#3}{#4}% + {\romannumeral0\xintlength{#6}}{#2}{#5}{#6}{#1}{#3}{#4}% }% long de B, P+2, n, B, |A|, A, P \def\XINT_float_N #1#2% {% @@ -17733,12 +18491,12 @@ first place. \def\XINT_flpow_checkB_b #1#2\Z #3% {% \expandafter\XINT_flpow_checkB_c \expandafter - {\romannumeral0\XINT_length{#2}}{#3}{#2}#1% + {\romannumeral0\xintlength{#2}}{#3}{#2}#1% }% \def\XINT_flpow_checkB_c #1#2% {% \expandafter\XINT_flpow_checkB_d \expandafter - {\the\numexpr \expandafter\XINT_Length\expandafter + {\the\numexpr \expandafter\xintLength\expandafter {\the\numexpr #1*20/3}+#1+#2+1}% }% \def\XINT_flpow_checkB_d #1#2#3#4% @@ -17876,12 +18634,12 @@ first place. \def\XINT_flpower_checkB_b #1#2\Z #3% {% \expandafter\XINT_flpower_checkB_c \expandafter - {\romannumeral0\XINT_length{#2}}{#3}{#2}#1% + {\romannumeral0\xintlength{#2}}{#3}{#2}#1% }% \def\XINT_flpower_checkB_c #1#2% {% \expandafter\XINT_flpower_checkB_d \expandafter - {\the\numexpr \expandafter\XINT_Length\expandafter + {\the\numexpr \expandafter\xintLength\expandafter {\the\numexpr #1*20/3}+#1+#2+1}% }% \def\XINT_flpower_checkB_d #1#2#3#4% @@ -18000,7 +18758,7 @@ first place. \def\XINT_flsqrt #1#2% {% \expandafter\XINT_sqrt_a - \expandafter{\romannumeral0\XINT_length {#2}}\XINT_flsqrt_big_d {#2}{#1}% + \expandafter{\romannumeral0\xintlength {#2}}\XINT_flsqrt_big_d {#2}{#1}% }% \def\XINT_flsqrt_big_d #1\or #2\fi #3% {% @@ -18131,7 +18889,8 @@ first place. % % \StoreCodelineNo {xintfrac} % -% \section{Package \xintseriesname implementation} +% \section{Package \xintseriesnameimp implementation} +% \label{sec:seriesimp} % % The commenting is currently (\docdate) very sparse. % @@ -18233,7 +18992,7 @@ first place. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintseries}% - [2013/11/04 v1.09f Expandable partial sums with xint package (jfB)]% + [2013/11/22 v1.09g Expandable partial sums with xint package (jfB)]% % \end{macrocode} % \subsection{\csh{xintSeries}} % \lverb|& @@ -18667,7 +19426,8 @@ first place. % % \StoreCodelineNo {xintseries} % -% \section{Package \xintcfracname implementation} +% \section{Package \xintcfracnameimp implementation} +% \label{sec:cfracimp} % % The commenting is currently (\docdate) very sparse. % @@ -18769,7 +19529,7 @@ first place. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcfrac}% - [2013/11/04 v1.09f Expandable continued fractions with xint package (jfB)]% + [2013/11/22 v1.09g Expandable continued fractions with xint package (jfB)]% % \end{macrocode} % \subsection{\csh{xintCFrac}} % \begin{macrocode} @@ -19733,7 +20493,8 @@ first place. % % \StoreCodelineNo {xintcfrac} % -% \section{Package \xintexprname implementation} +% \section{Package \xintexprnameimp implementation} +% \label{sec:exprimp} % % The first version was released in June 2013. I was greatly helped in % this task of writing an expandable parser of infix operations by the @@ -19921,7 +20682,7 @@ first place. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintexpr}% - [2013/11/04 v1.09f Expandable expression parser (jfB)]% + [2013/11/22 v1.09g Expandable expression parser (jfB)]% % \end{macrocode} % \subsection{Helper macros} % \begin{macrocode} @@ -20921,11 +21682,11 @@ first place. \xintApplyInline\mymacro\storedlinecounts \end{tabular} \def\mymacroaux #1#2{#2}% +% \parbox[t]{10cm}{Total number of code lines: \digitstt{\xintiSum{\xintApply\mymacro\storedlinecounts}}. Each package starts - with circa \digitstt{80} lines dealing - with catcodes, package identification and reloading management, also for Plain - \TeX\strut. Version + with circa \digitstt{80} lines dealing with catcodes, package identification + and reloading management, also for Plain \TeX\strut. Version \texttt{\pkgversion} of \texttt{\pkgdate}.\par} @@ -20944,7 +21705,7 @@ first place. Right bracket \] Circumflex \^ Underscore \_ Grave accent \` Left brace \{ Vertical bar \| Right brace \} Tilde \~} -\CheckSum {19898} +\CheckSum {20159} \makeatletter\check@checksum\makeatother \Finale %% diff --git a/Master/texmf-dist/source/generic/xint/xint.ins b/Master/texmf-dist/source/generic/xint/xint.ins index 9d8b5299c2f..717d1ac7adb 100644 --- a/Master/texmf-dist/source/generic/xint/xint.ins +++ b/Master/texmf-dist/source/generic/xint/xint.ins @@ -1,13 +1,14 @@ %% %%---------------------------------------------------------------- -%% The xint bundle (version 1.09f of November 4, 2013) +%% The xint bundle (version 1.09g of November 22, 2013) %% Copyright (C) 2013 by Jean-Francois Burnol %%---------------------------------------------------------------- %% %% %% This is a generated file. Run tex or latex on this file to -%% extract xint.sty, xintfrac.sty, xintexpr.sty, xintbinhex.sty, -%% xintgcd.sty, xintseries.sty and xintcfrac.sty from xint.dtx +%% extract xinttools.sty, xint.sty, xintfrac.sty, xintexpr.sty, +%% xintbinhex.sty, xintgcd.sty, xintseries.sty and xintcfrac.sty +%% from xint.dtx %% %% See xint.dtx for the copyright and the conditions for %% distribution and/or modification of this work. @@ -15,6 +16,7 @@ \input docstrip.tex \askforoverwritefalse \generate{\usepreamble\defaultpreamble +\file{xinttools.sty}{\from{xint.dtx}{xinttools}} \file{xint.sty}{\from{xint.dtx}{xint}} \file{xintbinhex.sty}{\from{xint.dtx}{xintbinhex}} \file{xintgcd.sty}{\from{xint.dtx}{xintgcd}} -- cgit v1.2.3