From 96aac111c7824c49a05e48fdbb2a1eba6313d062 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 30 Aug 2017 23:00:58 +0000 Subject: xint (30aug17) git-svn-id: svn://tug.org/texlive/trunk@45177 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/generic/xint/xint.dtx | 14310 ++++++++++++----------- Master/texmf-dist/source/generic/xint/xint.ins | 2 +- 2 files changed, 7567 insertions(+), 6745 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 24d5b76835c..9237f390b12 100644 --- a/Master/texmf-dist/source/generic/xint/xint.dtx +++ b/Master/texmf-dist/source/generic/xint/xint.dtx @@ -3,27 +3,27 @@ % Extract all files via "etex xint.dtx" and do "make help" % or follow instructions from extracted README.md. %<*dtx> -\def\xintdtxtimestamp {Time-stamp: <06-08-2017 at 23:22:42 CEST>} +\def\xintdtxtimestamp {Time-stamp: <29-08-2017 at 22:20:23 CEST>} % %<*drv> %% --------------------------------------------------------------- -\def\xintdocdate {2017/08/06} -\def\xintbndldate{2017/08/06} -\def\xintbndlversion {1.2n} +\def\xintdocdate {2017/08/29} +\def\xintbndldate{2017/08/29} +\def\xintbndlversion {1.2o} % %% README %% CHANGE LOG -%% xint 1.2n -%% 2017/08/06 +%% xint 1.2o +%% 2017/08/29 % -% Source: xint.dtx 1.2n 2017/08/06 (doc 2017/08/06) +% Source: xint.dtx 1.2o 2017/08/29 (doc 2017/08/29) % Author: Jean-Francois Burnol % Info: Expandable operations on big integers, decimals, fractions % License: LPPL 1.3c % %<*!readme&!changes&!dohtmlsh&!dopdfsh&!makefile> %% --------------------------------------------------------------- -%% The xint bundle 1.2n 2017/08/06 +%% The xint bundle 1.2o 2017/08/29 %% Copyright (C) 2013-2017 by Jean-Francois Burnol %%% xintkernel: Paraphernalia for the xint packages %%% xinttools: Expandable and non-expandable utilities @@ -250,6 +250,56 @@ Makefile.mk. %-------------------------------------------------------- %<*changes>------------------------------------------------------- +`1.2o (2017/08/29)` +---- + +### Incompatible changes + + - **xint**: `\xintAND`, `\xintOR`, ... and similar Boolean logic macros do + not apply anymore `\xintNum` (or `\xintRaw` if **xintfrac** is loaded), to + their arguments (often, from internal usage of `\xintSgn`), but only + f-expand them (using e.g. `\xintiiSgn`). This is kept un-modified even if + loading **xintfrac**. + +### Deprecated + +Deprecated macros raise an error but, generally, then expand as in former +releases. They will all get removed at some future release. + + - **xintcore**: `\xintiOpp`, `\xintiAbs`, `\xintiAdd`, `\xintiSub`, + `\xintiMul`, `\xintiDivision`, `\xintiQuo`, `\xintiRem`, `\xintiDivRound`, + `\xintiDivTrunc`, `\xintiMod`, `\xintiSqr`, `\xintiPow`, and `\xintiFac` + are deprecated. Only the `ii`-named variants get defined. + + - **xintcore**: `\xintCmp` and `\xintSgn` are deprecated from **xintcore** + (which only defines `\xintiiCmp` and `\xintiiSgn`) as they actually belong + to **xintfrac**. + + - **xintcore**: `\xintiiFDg`, resp. `\xintiiLDg`, are renamed `\xintFDg`, + resp. `\xintLDg`. Former denominations are deprecated. + + - **xint**: `\xintMON`, `\xintMMON`, `\xintiMax`, + `\xintiMin`, `\xintiMaxof`, `\xintiMinof`, `\xintiSquareRoot`, + `\xintiSqrt`, `\xintiSqrtR`, `\xintiBinomial`, and `\xintiPFactorial` are + deprecated. Only `ii`-named variants get defined. + + - **xint**: `\xintEq`, `\xintGeq`, `\xintGt`, `\xintLt`, `\xintGtorEq`, + `\xintLtorEq`, `\xintIsZero`, `\xintIsNotZero`, `\xintIsOne`, + `\xintOdd`, `\xintEven`, `\xintifSgn`, + `\xintifCmp`, `\xintifEq`, `\xintifGt`, `\xintifLt`, `\xintifZero`, + `\xintifNotZero`, `\xintifOne`, `\xintifOdd`, are deprecated. These macros + belong to **xintfrac**. Package **xint** defines only the `ii`-named + variants. + + - **xint**: `\xintNeq` was renamed to `\xintNotEq` which however is only + provided by **xintfrac**. Package **xint** defines `\xintiiNotEq`, and + `\xintNeq` is deprecated. + + - **xint**: `\xintNot` was renamed to `\xintNOT`, former denomination is + deprecated. See also item about Boolean logic macros in the *Incompatible + Changes* section. + + `1.2n (2017/08/06)` ---- @@ -456,6 +506,7 @@ Makefile.mk. cases.) The test files existed but were not executed prior to release. Automation in progress. + `1.2i (2016/12/13)` ---- @@ -519,6 +570,7 @@ Makefile.mk. - `\xintDecSplitL` and `\xintDecSplitR` from **xint** produced their output in a spurious brace pair (bug introduced in `1.2f`). + `1.2h (2016/11/20)` ---- @@ -554,6 +606,7 @@ Makefile.mk. the dummy variable was given an empty range (or list) of values, rather than producing respectively `0` and `1` as formerly. + `1.2g (2016/03/19)` ---- @@ -595,6 +648,7 @@ Makefile.mk. Brent-Salamin algorithm for computation of Pi using `iter` in a float expression. + `1.2f (2016/03/12)` ---- @@ -660,6 +714,7 @@ Makefile.mk. - the comparison operators were not recognized by `\xintNewIIExpr` and `\xintdefiifunc` constructs. + `1.2e (2015/11/22)` ---- @@ -688,6 +743,7 @@ Makefile.mk. multiplication was not yet always done with enhanced precedence. Now yes. + `1.2d (2015/11/18)` ---- @@ -727,6 +783,7 @@ Makefile.mk. subtraction (happened when 00000001 was found under certain circumstances at certain mod 8 locations). + `1.2b (2015/10/29)` ---- @@ -758,6 +815,7 @@ Makefile.mk. parsing of decimal numbers and as a result `\xinttheexpr 0.01\relax` expanded to `0` ! (sigh...) + `1.2 (2015/10/10)` ---- @@ -816,6 +874,7 @@ Makefile.mk. - an effort at randomly shuffling around various pieces of the documentation has been done. + `1.1c (2015/09/12)` ---- @@ -827,6 +886,7 @@ Makefile.mk. regarding the source code formatting in `sourcexint.pdf`, and minor issues in `Makefile.mk`. + `1.1b (2015/08/31)` ---- @@ -838,6 +898,7 @@ Makefile.mk. - Slight enhancements to the documentation, particularly in the `Read this first` section. + `1.1a (2014/11/07)` ---- @@ -865,6 +926,7 @@ Makefile.mk. of clean up of the code comments. Improved `\Factors` example of nested `subs`, `rseq`, `iter` in `\xintiiexpr`. + `1.1 (2014/10/28)` ---- @@ -1048,6 +1110,7 @@ Makefile.mk. - the `\XINTinFloatPrd:csv` macro name had a typo, hence `prd` was non-functional in `\xintfloatexpr`. + `1.09n (2014/04/01)` ---- @@ -1060,6 +1123,7 @@ Makefile.mk. introduced in `1.09i` of `2013/12/18` and showed up when the index `N` was larger than the number of elements of the list). + `1.09m (2014/02/26)` ---- @@ -1074,6 +1138,7 @@ Makefile.mk. assume that the coefficients of the generalized continued fraction are numeric quantities. Some other minor changes. + `1.09kb (2014/02/13)` ---- @@ -1088,6 +1153,7 @@ Makefile.mk. * bug fix (**xinttools**): `\xintSeq` from `1.09k` needed a `\chardef` which was missing from `xinttools.sty`, it was in `xint.sty`. + `1.09k (2014/01/21)` ---- @@ -1105,6 +1171,7 @@ Makefile.mk. * bug fix (**xinttools**, **xint**, ...): forgotten catcode check of `"` at loading time has been added. + `1.09j (2014/01/09)` ---- @@ -1148,6 +1215,7 @@ Makefile.mk. * bug fix: the `1.09i` `xint.ins` file produced a buggy `xint.tex` file. + `1.09i (2013/12/18)` ---- @@ -1204,6 +1272,7 @@ Makefile.mk. * *deprecated*: `\xintifTrueFalse`, `\xintifTrue`; use `\xintifTrueAelseB`. + `1.09h (2013/11/28)` ---- @@ -1234,6 +1303,7 @@ Makefile.mk. * all macros of **xinttools** for which it makes sense are now declared `\long`. + `1.09g (2013/11/22)` ---- @@ -1246,6 +1316,7 @@ Makefile.mk. * bugfix: `\xintFor` and `\xintFor*` do not modify anymore the value of `\count 255`. + `1.09f (2013/11/04)` ---- @@ -1275,6 +1346,7 @@ Makefile.mk. when working only with (big) integers and not fractions or decimal numbers. + `1.09e (2013/10/29)` ---- @@ -1302,6 +1374,7 @@ Makefile.mk. * the documentation explains with more details various expansion related issues, particularly in relation to conditionals. + `1.09d (2013/10/22)` ---- @@ -1316,6 +1389,7 @@ Makefile.mk. * same bug fix for `\xintApplyInline`. + `1.09c (2013/10/09)` ---- @@ -1346,6 +1420,7 @@ Makefile.mk. * again various improvements and changes in the documentation. + `1.09b (2013/10/03)` ---- @@ -1363,6 +1438,7 @@ Makefile.mk. math mode; i.e. a `\xintRaw` which does not print the denominator if it is one. + `1.09a (2013/09/24)` ---- @@ -1408,6 +1484,7 @@ Makefile.mk. * a bug (**xintfrac**) introduced in `1.08b` made `\xintCmp` crash when one of its arguments was zero. `:-((` + `1.08b (2013/06/14)` ---- @@ -1421,6 +1498,7 @@ Makefile.mk. registers may be directly used in arguments to the macros of **xintfrac**. + `1.08a (2013/06/11)` ---- @@ -1435,6 +1513,7 @@ Makefile.mk. * Macros for floating point numbers added to the **xintseries** package. + `1.08 (2013/06/07)` ---- @@ -1445,6 +1524,7 @@ Makefile.mk. * new package **xintbinhex** providing *conversion routines* to and from binary and hexadecimal bases. + `1.07 (2013/05/25)` ---- @@ -1484,12 +1564,14 @@ Makefile.mk. [^1]: but values higher than 100 or 200 will presumably give too slow evaluations. + `1.06b (2013/05/14)` ---- * Minor code and documentation improvements. Everywhere in the source code, a more modern underscore has replaced the @ sign. + `1.06 (2013/05/07)` ---- @@ -1505,11 +1587,13 @@ evaluations. inserted inside a `\numexpr..\relax`, hence completely expanded, one may use count registers, even infix arithmetic operations, etc... + `1.05 (2013/05/01)` ---- Minor changes and additions to **xintfrac** and **xintcfrac**. + `1.04 (2013/04/25)` ---- @@ -1528,6 +1612,7 @@ deal with the *denominator buildup* plague. * `tex xint.dtx` extracts style files (no need for a `xint.ins`). + `1.03 (2013/04/14)` ---- @@ -1539,6 +1624,7 @@ ordering of the arguments is chosen automatically). * added illustration of Machin algorithm to the documentation. + `1.0 (2013/03/28)` ---- @@ -2503,6 +2589,14 @@ pdfpagemode=UseOutlines} \vtop{\noindent Changed (#1)}\ }}% \vskip\dp\strutbox }\strut\@esphack} +\def\DEPRECATED #1{\@bsphack + \vadjust{\vskip-\dp\strutbox + \smash{\hbox to 0pt {\hss\color[named]{PineGreen}% + \normalfont\small + \hsize 2cm\rightskip.5cm minus.5cm + \vtop{\noindent Deprecated! (#1)}\ }}% + \vskip\dp\strutbox }\strut\@esphack} + \def\CHANGEDf #1{\@bsphack \vadjust{\vskip-\dp\strutbox \smash{\hbox to 0pt {\hss\color[named]{PineGreen}% @@ -3002,7 +3096,11 @@ pdfpagemode=UseOutlines} \leftmarginiv \leftmarginii \parindent\dimexpr2\fontcharwd\font`X\relax \leftmargin\leftmargini % pourquoi pas 0? - \edef\everbatimindent{\the\dimexpr\leftmargini\relax\space }% +% formerly everbatim indent was set to leftmargingi, reduce it (2017/08/26) +% \edef\everbatimindent{\the\dimexpr\leftmargini\relax\space }% +% setting it to \parindent does not work with \everb construct +% \def\everbatimindent{\parindent}% + \edef\everbatimindent{\the\dimexpr2\fontcharwd\font`X\relax\space}% \cftsubsecnumwidth 2\leftmarginii \cftsubsubsecnumwidth 2\leftmargini \cftsubsecindent 0pt @@ -3607,7 +3705,7 @@ not have been obtained in reduced terms: \end{framed} Make sure to read \autoref{sec:expr}, \autoref{sec:xintexprsyntax} and -\autoref{ssec:outputformat}. +\autoref{ssec:outputs}. \subsection{Printing big numbers on the page}\label{ssec:printnumber} When producing very long numbers there is the question of printing them on @@ -3624,7 +3722,7 @@ When producing very long numbers there is the question of printing them on It may be used like this: % -\leftedline{|\printnumber {\xintiiQuo{\xintiiPow {2}{1000}}{\xintiFac{100}}}|} +\leftedline{|\printnumber {\xintiiQuo{\xintiiPow {2}{1000}}{\xintiiFac{100}}}|} % or as |\printnumber\mybiginteger| or |\printnumber{\mybiginteger}| if |\mybiginteger| was previously defined via a |\newcommand|, a |\def| or @@ -3738,14 +3836,14 @@ with floating point numbers. \everb|@ \xintAssign \xintBezout {\xinttheiiexpr 7^200-3^200\relax} {\xinttheiiexpr 2^200-1\relax}\to\A\B\U\V\D -$\U\times(7^{200}-3^{200})+\xintiOpp\V\times(2^{200}-1)=\D$ +$\U\times(7^{200}-3^{200})+\xintiiOpp\V\times(2^{200}-1)=\D$ | \xintAssign \xintBezout {\xinttheiiexpr 7^200-3^200\relax}% {\xinttheiiexpr 2^200-1\relax}\to\A\B\U\V\D \dtt {\printnumber\U$\times(7^{200}-3^{200})+{}$% - \printnumber{\xintiOpp\V}$\times(2^{200}-1)={}$\printnumber\D} + \printnumber{\xintiiOpp\V}$\times(2^{200}-1)={}$\printnumber\D} \item The Euclide algorithm applied to \np{22206980239027589097} and \np{8169486210102119257}: (with \xintgcdname)% @@ -3829,7 +3927,7 @@ We have already mentioned % is $\Temp$. -\edef\x{\xintiiQuo{\xintiiPow {2}{1000}}{\xintiFac{100}}} +\edef\x{\xintiiQuo{\xintiiPow {2}{1000}}{\xintiiFac{100}}} \edef\y{\xintLen{\x}} \item As an example of nesting package macros, let us consider the following @@ -3837,13 +3935,13 @@ code snippet within a file with filename |myfile.tex|: \everb|@ \newwrite\outstream \immediate\openout\outstream \jobname-out\relax -\immediate\write\outstream {\xintiiQuo{\xintiiPow{2}{1000}}{\xintiFac{100}}} +\immediate\write\outstream {\xintiiQuo{\xintiiPow{2}{1000}}{\xintiiFac{100}}} % \immediate\closeout\outstream | \noindent The tex run creates a file |myfile-out.tex|, and then writes to it the quotient from the euclidean division of $2^{1000}$ by $100!$. The number of -digits is |\xintLen{\xintiiQuo{\xintiiPow{2}{1000}}{\xintiFac{100}}}| which +digits is |\xintLen{\xintiiQuo{\xintiiPow{2}{1000}}{\xintiiFac{100}}}| which expands (in two steps) and tells us that $[2^{1000}/100!]$ has \dtt{\y} digits. This is not so many, let us print them here: \dtt{\printnumber\x}.% @@ -3947,10 +4045,21 @@ This is release \expandafter|\xintbndlversion| of \expandafter|\xintbndldate|. -The macros of \xintbinhexname for conversion routines between binary, decimal, -and hexadecimal bases have been entirely re-written. They are faster, the more -so for long inputs. But they have the drawback of now limiting their input to -a maximal length of a few thousands characters. +|1.2o| does mass-deprecation of those macros which were so far defined by +\xintcorename/\xintname to use automatically \csbxint{Num}; users of +\xintfracname (or a fortiori \xintexprname) will see almost nothing of this, +as \xintfracname does the proper definitions. See +\autoref{ssec:coredeprecated}, \autoref{ssec:xintdeprecated}, and +\autoref{ssec:xintdeprecatedNum} for details. + +|1.2n| removed the \xintbinhexname dependency upon \xintcorename: it now loads +only \xintkernelname. + +At |1.2m| (again at |1.2n|) the macros of \xintbinhexname for conversion +routines between binary, decimal, and hexadecimal bases have been entirely +re-written. They are faster, the more so for long inputs. But they have the +drawback of now limiting their input to a maximal length of a few thousands +characters. Since |1.2l|, the underscore |_| is accepted inside the expression parsers as an ignored digit separator\footnote{The space character has already always been accepted @@ -3966,15 +4075,13 @@ from \xintfracname or \xintname though, only in expressions from \xintexprname. Macro usage with non properly terminated inputs such as -|\xintiiAdd{\the\numexpr1}{2}| caused crashes. This has been fixed: the +|\xintiiAdd{\the\numexpr1}{2}| caused crashes. This has been fixed at |1.2l|: the arithmetic macros of \xintcorename, the macros of \xintfracname, those of \xintgcdname, have been made robust against such inputs. Some routines of \xintcorename principally destined to internal usage such as \csbxint{Inc} remain incompatible though (to avoid adding some overhead; check |sourcexint.pdf| for details). -Some refactoring took place at |1.2l| in the sources of \xintcorename for some -efficiency gains, and improvements in the code comments. See |CHANGES.html| or |CHANGES.pdf| for more information (either |texdoc --list xint| or on the internet via @@ -4145,7 +4252,7 @@ when using variables. - \myitem{9} The power operator |^|, or equvalently |**|. It is left + \myitem{9} The power operator |^|, or equivalently |**|. It is left associative: {\restoreMicroFont|\xinttheiexpr 2^2^3\relax|} evaluates to \xinttheiexpr 2^2^3\relax, not \xinttheiexpr 2^(2^3)\relax. See \csbxint{FloatPower} for additional information. @@ -5735,17 +5842,17 @@ generate the list via iterated full expansion. \vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr \xintFor* #1 in {\FibonacciSeq {30}{59}}\do {\theindex &\xintthe#1 & - \xintiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{index}\cr }}% + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{index}\cr }}% }\vrule \vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr \xintFor* #1 in {\FibonacciSeq {60}{89}}\do {\theindex &\xintthe#1 & - \xintiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{index}\cr }}% + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{index}\cr }}% }\vrule \vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr \xintFor* #1 in {\FibonacciSeq {90}{119}}\do {\theindex &\xintthe#1 & - \xintiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{index}\cr }}% + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{index}\cr }}% }}% % \centeredline{Some Fibonacci numbers together with their residues modulo @@ -5761,17 +5868,17 @@ generate the list via iterated full expansion. \vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr \xintFor* #1 in {\FibonacciSeq {30}{59}}\do {\theindex &\xintthe#1 & - \xintiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{index}\cr }}% + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{index}\cr }}% }\vrule \vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr \xintFor* #1 in {\FibonacciSeq {60}{89}}\do {\theindex &\xintthe#1 & - \xintiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{index}\cr }}% + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{index}\cr }}% }\vrule \vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr \xintFor* #1 in {\FibonacciSeq {90}{119}}\do {\theindex &\xintthe#1 & - \xintiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{index}\cr }}% + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{index}\cr }}% }% | \endgroup @@ -6130,7 +6237,7 @@ margin annotation next to the description of the arguments. will indeed absorb the \csa{else} or closing \csa{fi}, else some error will arise in further processing. Therefore it is highly recommended to use the package provided conditionals such as \csbxint{ifEq}, \csbxint{ifGt}, - \csbxint{ifSgn}, \csbxint{ifOdd}\dots, or, for \LaTeX{} users and when dealing + \csbxint{ifSgn},\dots\ or, for \LaTeX{} users and when dealing with short integers the \href{http://www.ctan.org/pkg/etoolbox}{etoolbox}% % @@ -6154,9 +6261,8 @@ margin annotation next to the description of the arguments. \item after the definition |\def\x {12}|, one can not use {\color{blue}|-\x|} as input to one of the package macros: the \fexpan sion will act only on the minus sign, hence do nothing. The only way is to use the - \csbxint{Opp} macro, or perhaps here rather \csbxint{iOpp} which does - maintains integer format on output, as they replace a number with - its opposite. + \csbxint{Opp} macro (or \csbxint{iiOpp} which is integer only) + which obtains the opposite of a given number. \begingroup\slshape Again, this is otherwise inside an \csbxint{theexpr}-ession or @@ -6224,15 +6330,28 @@ steps. \end{enumerate} -\subsection {Input formats for macros}\label{sec:inputs} +\subsection {Input formats for macros}\label{ssec:inputs} -Macros can have different types of arguments. In the description of the macro, -a margin annotation signals what is the argument type. +Macros can have different types of arguments (we do not consider here the +\csbxint{expr}-parsers but only the macros of +\xintcorename/\xintname/\xintfracname). In a macro description, a +margin annotation signals what is the argument type. \begin{enumerate} \item \TeX\ integers\ntype{\numx} are handled inside a |\numexpr..\relax| - hencee may be count registers or variables. - Beware that |-(1+1)| is not legal (but |0-(1+1)| is). Such integers must be - less than \dtt{\number "7FFFFFFF} in absolute value. + hence may be count registers or variables. Beware that |-(1+1)| is not legal + and raises an error, but |0-(1+1)| is. Also |2\cnta| with |\cnta| a |\count| + isn't legal. Integers must be kept less than \dtt{\number "7FFFFFFF} in + absolute value, although the \emph{scaling} operation |(a*b)/c| computes the + intermediate product with twice as many bits. + + The slash |/| does a \fbox{rounded} division which is a fact of life of + |\numexpr| which I have found very annoying in at least nine cases out of + ten, not to say ninety-nine cases out of one hundred. Besides, it is at odds + with \TeX's |\divide| which does a truncated division (non-expandably). + + But to follow-suit |/| also does rounded integer division in + \csbxint{iiexpr}|..\relax|, and the operator |//| does there the truncated + division. \item the strict format\ntype{f} applies to macros handling big integers but only \fexpan ding their arguments. After this \fexpan sion the input should @@ -6244,9 +6363,14 @@ a margin annotation signals what is the argument type. \item the extended integer format\ntype{\Numf} applies when the macro parses its arguments via \csbxint{Num}. The input may then have arbitrarily many leading minus and plus signs, followed by leading zeroes, and further - digits. Macros with a single |i| in their names always filter their - arguments via \csbxint{Num}. When \xintfracname is loaded \csbxint{Num} - accepts fractions and truncates them to integers. + digits. With \xintfracname loaded, \csbxint{Num} is extended to + accept fractions and its action is to truncate them to integers. + + At |1.2o|\CHANGEDf{1.2o} many macros from \xintcorename/\xintname which + use \csbxint{Num} to parse their arguments got deprecated, see + \autoref{ssec:coredeprecated}, \autoref{ssec:xintdeprecated}, and + \autoref{ssec:xintdeprecatedNum}. + \item the fraction input format\ntype{\Ff} applies to the arguments of \xintfracname macros handling genuine fractions. It allows two types @@ -6306,7 +6430,7 @@ macros, there are some cases where spaces could break havoc.% be certain of all possibilities after |1.2| release. One thing to be aware of is that \csa{numexpr} stops on spaces between digits (although it provokes an expansion to see if an infix operator follows); the exponent for - \csbxint{iiPow} or the argument of the factorial \csbxint{iFac} are only + \csbxint{iiPow} or the argument of the factorial \csbxint{iiFac} are only subjected to such a \csa{numexpr} (there are a few other macros with such input types in \xintname). If the input is given as, say |1 2\x| where \csa{x} is a macro, the macro \csa{x} will not be expanded by the @@ -6343,23 +6467,19 @@ signaled in the margin with notations \`a la \LaTeX3. \subsection{Output formats of macros} -\label{ssec:outputformat} +\label{ssec:outputs} -We do not consider here the \csbxint{expr}-parsers but only the macros as -described in the documentation of \xintname and \xintfracname. Macros of other -components of the bundle have their own output formats (for example for -continuous fractions with \xintcfracname). -There are mainly three types of output formats:% -% -\footnote{There are further cases like \csbxint{iiDivision} which outputs a - token list of two braced items.} +We do not consider here the \csbxint{expr}-parsers but only the macros from \xintcorename, \xintname and \xintfracname. Macros of other +components of the bundle may have their own output formats, for example for +continuous fractions with \xintcfracname. +There are mainly three types of outputs:% \begin{itemize}[nosep,listparindent=\leftmarginiii] -\item macros from \xintname with |i| or |ii| in their names produce on output -integers in the strict format described in the previous section. -\item fraction handling macros from \xintfracname produce on output the strict -fraction format |A/B[N]| (which stands for |(A/B)|$\times$|10^N|) where |A| -and |B| are integers, with |B| positive, and |N| is a ``short'' integer. The +\item arithmetic macros from \xintcorename/\xintname deliver integers + in the strict format as described in the previous section. +\item arithmetic macros from \xintfracname produce on output the strict +fraction format |A/B[N]|, which stands for |(A/B)|$\times$|10^N|, where |A| +and |B| are integers, |B| is positive, and |N| is a ``short'' integer. The output is not reduced to smallest terms. The |A| and |B| may end with zeroes (\emph{i.e}, |N| does not represent all powers of ten). The denominator |B| is always strictly positive. There is no |+| sign. The |-| is always first if @@ -6380,10 +6500,6 @@ trimmed. There is one exceptional case: Future versions of the package may modify this. \end{itemize} -Breaking change:\CHANGED{1.2k} releases earlier than |1.2k| used -|10.0...0eN| when the rounding went upwards to the next power of ten, thus -the output had a mantissa with |P+1| digits rather than |P| in these -exceptional cases. See the documentation of \csbxint{Float}. \subsection{Count registers and variables}\label{sec:useofcount} @@ -6659,15 +6775,13 @@ the \xintname bundle expandable macros, or when building up a completely expandable macro of one's own, one needs some \TeX nical expertise (see also \autoref{fn:expansions} on page~\pageref{fn:expansions}). -It is thus much to be recommended to opt rather for already existing expandable -branching macros, such as the ones which are provided by -\xintname/\xintfracname: among them -\csbxint{SgnFork}, \csbxint{ifSgn}, \csbxint{ifZero}, \csbxint{ifOne}, -\csbxint{ifNotZero}, \csbxint{ifTrueAelseB}, \csbxint{ifCmp}, \csbxint{ifGt}, -\csbxint{ifLt}, \csbxint{ifEq}, \csbxint{ifOdd}, and \csbxint{ifInt}. See their -respective documentations. All these conditionals always have either two or -three branches, and empty brace pairs |{}| for unused branches should not be -forgotten. +It is thus much to be recommended to use the expandable branching macros, +provided by \xintfracname succh as \csbxint{ifSgn}, \csbxint{ifZero}, +\csbxint{ifOne}, \csbxint{ifNotZero}, \csbxint{ifTrueAelseB}, \csbxint{ifCmp}, +\csbxint{ifGt}, \csbxint{ifLt}, \csbxint{ifEq}, +\csbxint{ifInt}... See their respective documentations. All these conditionals +always have either two or three branches, and empty brace pairs |{}| for +unused branches should not be forgotten. If these tests are to be applied to standard \TeX{} short integers, it is more efficient to use (under \LaTeX{}) the equivalent conditional tests from the @@ -6796,12 +6910,12 @@ I have no answer: it made definitely sense at the start of \xintname (see Here is a list of imaginable input errors. Some will cause compilation errors, others are more annoying as they may pass through unsignaled. \begin{itemize} -\item using |-| to prefix some macro: |-\xintiSqr{35}/271|.% +\item using |-| to prefix some macro: |-\xintiiSqr{35}/271|.% % \footnote{to the contrary, this \emph{is} allowed inside an |\xintexpr|-ession.} -\item using one pair of braces too many |\xintIrr{{\xintiPow {3}{13}}/243}| (the +\item using one pair of braces too many |\xintIrr{{\xintiiPow {3}{13}}/243}| (the computation goes through with no error signaled, but the result is completely wrong). \item things like |\xintiiAdd { \x}{\y}| as the space will cause \csa{x} to be @@ -6868,18 +6982,20 @@ control sequence) must be left undefined. I trust it will be |;-)|.% {\catcode`/ 11 \catcode`! 11 \catcode32 11 |\ ! /|} was chosen for its shortness.} +Deprecated macros also generate an (expandable) error message. Just hit the +|RETURN| key once to proceed.\IMPORTANT\ Most deprecated macros at |1.2o| are +listed either in \autoref{ssec:coredeprecated} or +\autoref{ssec:xintdeprecated} or \autoref{ssec:xintdeprecatedNum}. They will +get removed at some future release. Replace them with the correctly named ones +(possibly with additional usage of \csbxint{Num} if really needed); in most +cases loading \xintfracname resolves these deprecations from +\xintcorename/\xintname. The expression parsers are at |1.2l| still using a slightly less evolved method which lets \TeX{} display an undefined control sequence name giving some indication of the underlying problem (we copied this method from the |bigintcalc| package). The name of the control sequence is the message. -% The -% error is raised \emph{before} the end of the expansion so as to not disturb -% further processing of the token stream, after completion of the operation. -% Generally the problematic operation will output a zero. Possible such error -% message control sequences: - \begin{multicols}{2}\parskip0pt\relax \begin{everbatim} \xintError:ignored @@ -6892,35 +7008,6 @@ some indication of the underlying problem (we copied this method from the \end{multicols} -Some additional errors are raised when using deprecated macros (or trying to -invoke \csbxint{Add} with only \xintname.sty loaded for example.) -\begin{multicols}{2}\parskip0pt\relax -\begin{everbatim} -\Did_you_mean_iiAbs?or_load_xintfrac! -\Did_you_mean_iiOpp?or_load_xintfrac! -\Did_you_mean_iiAdd?or_load_xintfrac! -\Did_you_mean_iiSub?or_load_xintfrac! -\Did_you_mean_iiMul?or_load_xintfrac! -\Did_you_mean_iiPow?or_load_xintfrac! -\Did_you_mean_iiSqr?or_load_xintfrac! -\Did_you_mean_iiMax?or_load_xintfrac! -\Did_you_mean_iiMin?or_load_xintfrac! -\Did_you_mean_iMaxof?or_load_xintfrac! -\Did_you_mean_iMinof?or_load_xintfrac! -\Did_you_mean_iiSum?or_load_xintfrac! -\Did_you_mean_iiPrd?or_load_xintfrac! -\Removed!use_xintiQuo_or_xintiiQuo! -\Removed!use_xintiRem_or_xintiiRem! -\end{everbatim} -\end{multicols} - -For such type of error sequences one should set |\errorcontextlines| to at -least |2| to get from \LaTeX\ more context. Errors occuring during the parsing -of |\xintexpr-essions| try to provide helpful information about the offending -token. But for the newer |1.2l| type of expandable error messages it is -already ok with |\errorcontextlines| left at its \LaTeX\ default. Future -releases of \xintname will presumably use only the newer method. - Some constructs in \xintexprname-essions use delimited macros and there is thus possibility in case of an ill-formed expression to end up beyond the |\relax| end-marker. Such a situation can also occur from a non-terminated @@ -6955,7 +7042,7 @@ have any underscore in their names (for obscure legacy reasons). \xintkernelname provides \hyperref[odef]{|\odef|}, \hyperref[oodef]{|\oodef|}, \hyperref[fdef]{|\fdef|}: if macros with these names already exist -\xinttoolsname it will not overwrite them. The same meanings are independently +\xinttoolsname will not overwrite them. The same meanings are independently available under the names |\xintodef|, |\xintoodef|, etc... Apart from |\thexintexpr|, |\thexintiexpr|, ... @@ -7053,7 +7140,7 @@ the current common values of the input save stack and maximal expansion depth: $5000$ and $10000$ respectively. -\section{Some utilities from the \xinttoolsname package} +\section{Some utilities from the \xinttoolsname package}\label{sec:sometoolsutils} This is a first overview. Many examples combining these utilities with the arithmetic macros of \xintname are to be found in \autoref{sec:tools}. See @@ -7065,7 +7152,7 @@ also \autoref{sec:examples}. It might not be necessary to maintain at all times complete expandability. A devoted syntax is provided to make these things more efficient, for example when -using the \csbxint{iDivision} macro which computes both quotient and remainder +using the \csbxint{iiDivision} macro which computes both quotient and remainder at the same time: % @@ -7073,7 +7160,7 @@ the same time: |\xintiiDivision{\xintiiPow {2}{1000}}{\xintiiFac{100}}|\csbnolk{to}|\A\B|} % give: -\xintAssign\xintiiDivision{\xintiPow {2}{1000}}{\xintiiFac{100}}\to\A\B +\xintAssign\xintiiDivision{\xintiiPow {2}{1000}}{\xintiiFac{100}}\to\A\B |\meaning\A|\dtt{: \printnumber{\meaning\A}\relax} and |\meaning\B|\dtt{: \printnumber{\meaning\B}\relax}. % @@ -7086,7 +7173,7 @@ Another example (which uses \csbxint{Bezout} from the \xintgcdname package): is equivalent to setting |\A| to \dtt{\tmpA}, |\B| to \dtt{\tmpB}, |\U| to \dtt{\tmpU}, |\V| to \dtt{\tmpV}, and |\D| to \dtt{\tmpD}. And indeed \dtt{(\tmpU)$\times$\tmpA-(\tmpV)$\times$\tmpB$=$% - \xintiSub{\xintiMul\tmpU\tmpA}{\xintiMul\tmpV\tmpB}} is a Bezout Identity. + \xintiiSub{\xintiiMul\tmpU\tmpA}{\xintiiMul\tmpV\tmpB}} is a Bezout Identity. Thus, what |\xintAssign| does is to first apply an \hyperref[ssec:expansions]{\fexpan sion} to what comes next; it then defines one @@ -7106,16 +7193,14 @@ document) is not an opening brace |{|, |\xintAssign| consider that there is {\csbxint{Assign}|\xintBezout{3570902836026}{200467139463}|% \csbnolk{to}|\A\B\U\V\D|} \noindent -gives then |\U|\dtt{: - \printnumber\tmpU}, - |\V|\dtt{: - \printnumber\tmpV} and |\D|\dtt{=\tmpD}. +gives then |\U| with meaning \dtt{\tmpU}, + |\V| with meaning \dtt{\tmpV} and |\D| with meaning \dtt{\tmpD}. % In situations when one does not know in advance the number of items, one has \csbxint{AssignArray} or its synonym \csbxint{DigitsOf}: % -\leftedline{\csbxint{DigitsOf}|\xintiPow{2}{100}|\csbnolk{to}\csa{DIGITS}} +\leftedline{\csbxint{DigitsOf}|\xintiiPow{2}{100}|\csbnolk{to}\csa{DIGITS}} % This defines \csa{DIGITS} to be macro with one parameter, \csa{DIGITS}|{0}| gives the size |N| of the array and \csa{DIGITS}|{n}|, for |n| from |1| to |N| @@ -7131,16 +7216,16 @@ completely expanded and may be a count register, not necessarily prefixed by % \newcount\cnta % \newcount\cntb \begingroup -\xintDigitsOf\xintiPow{2}{100}\to\DIGITS +\xintDigitsOf\xintiiPow{2}{100}\to\DIGITS \cnta = 1 \cntb = 0 \loop -\advance \cntb \xintiSqr{\DIGITS{\cnta}} +\advance \cntb \xintiiSqr{\DIGITS{\cnta}} \ifnum \cnta < \DIGITS{0} \advance\cnta 1 \repeat -|2^{100}| (=\xintiPow {2}{100}) has \DIGITS{0} digits and the sum of their squares is \the\cntb. +|2^{100}| (=\xintiiPow {2}{100}) has \DIGITS{0} digits and the sum of their squares is \the\cntb. These digits are, from the least to the most significant: \cnta = \DIGITS{0} \loop \DIGITS{\cnta}\ifnum \cnta > 1 \advance\cnta -1 , \repeat.\endgroup \end{everbatim*} @@ -7167,16 +7252,16 @@ first release, \csbxint{Apply} and \csbxint{ListWithSep} since |1.04|, As an example the following code uses only expandable operations: \begin{everbatim*} -$2^{100}$ (=\xintiPow {2}{100}) has \xintLen{\xintiPow {2}{100}} digits and the sum of their - squares is \xintiiSum{\xintApply {\xintiSqr}{\xintiPow {2}{100}}}. These digits are, from the - least to the most significant: \xintListWithSep {, }{\xintRev{\xintiPow {2}{100}}}. The thirteenth - most significant digit is \xintNthElt{13}{\xintiPow {2}{100}}. The seventh least significant one - is \xintNthElt{7}{\xintRev{\xintiPow {2}{100}}}. +$2^{100}$ (=\xintiiPow {2}{100}) has \xintLen{\xintiiPow {2}{100}} digits and the sum of their +squares is \xintiiSum{\xintApply {\xintiiSqr}{\xintiiPow {2}{100}}}. These digits are, from the +least to the most significant: \xintListWithSep {, }{\xintRev{\xintiiPow {2}{100}}}. The thirteenth +most significant digit is \xintNthElt{13}{\xintiiPow {2}{100}}. The seventh least significant one +is \xintNthElt{7}{\xintRev{\xintiiPow {2}{100}}}. \end{everbatim*} It would be more efficient to do once and for all -|\edef\z{\xintiPow {2}{100}}|, and then use |\z| in place of - |\xintiPow {2}{100}| everywhere as this would spare the CPU some repetitions. +|\edef\z{\xintiiPow {2}{100}}|, and then use |\z| in place of + |\xintiiPow {2}{100}| everywhere as this would spare the CPU some repetitions. Expandably computing primes is done in \autoref{xintSeq}. @@ -7197,7 +7282,7 @@ expandability. Check it out (\autoref{xintiloop} and also in next section). \section {Additional examples using \xinttoolsname or \xintexprname or both} \label{sec:examples} -Actually, recall that \xintexprname.sty automatically loads \xinttoolsname.sty. +Note: \xintexprname.sty automatically loads \xinttoolsname.sty. \subsection{Completely expandable prime test} \label{ssec:primesI} @@ -7207,20 +7292,20 @@ given input is prime and $0$ if not: \everb|@ \def\remainder #1#2{\the\numexpr #1-(#1/#2)*#2\relax } \def\IsPrime #1% - {\xintANDof {\xintApply {\remainder {#1}}{\xintSeq {2}{\xintiSqrt{#1}}}}} + {\xintANDof {\xintApply {\remainder {#1}}{\xintSeq {2}{\xintiiSqrt{#1}}}}} | -This uses \csbxint{iSqrt} and assumes its input is at least $5$. Rather than -\xintname's own \csbxint{iRem} we used a quicker |\numexpr| expression as we +This uses \csbxint{iiSqrt} and assumes its input is at least $5$. Rather than +\xintname's own \csbxint{iiRem} we used a quicker |\numexpr| expression as we are dealing with short integers. Also we used \csbxint{ANDof} which will return $1$ only if all the items are non-zero. The macro is a bit silly with an even input, ok, let's enhance it to detect an even input: \everb|@ \def\IsPrime #1% - {\xintifOdd {#1} + {\xintiiifOdd {#1} {\xintANDof % odd case {\xintApply {\remainder {#1}} - {\xintSeq [2]{3}{\xintiSqrt{#1}}}% + {\xintSeq [2]{3}{\xintiiSqrt{#1}}}% }% } {\xintifEq {#1}{2}{1}{0}}% @@ -7245,7 +7330,7 @@ The macro becomes: \def\IsPrime #1% {\ifnumodd {#1} {\xintANDof % odd case - {\xintApply {\remainder {#1}}{\xintSeq [2]{3}{\xintiSqrt{#1}}}}} + {\xintApply {\remainder {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}} {\ifnumequal {#1}{2}{1}{0}}} | @@ -7275,7 +7360,7 @@ Let us enhance our prime macro to work also on the small primes: {\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes {\xintANDof {\xintApply - { \IsNotDivisibleBy {#1}}{\xintSeq [2]{3}{\xintiSqrt{#1}}}}% + { \IsNotDivisibleBy {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}% }}% END OF THE ODD BRANCH {\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH } @@ -7353,7 +7438,7 @@ $168$). {\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes {\xintANDof {\xintApply - { \IsNotDivisibleBy {#1}}{\xintSeq [2]{3}{\xintiSqrt{#1}}}}% + { \IsNotDivisibleBy {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}% }}% END OF THE ODD BRANCH {\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH } @@ -7700,7 +7785,7 @@ as they are able to deal with arbitrarily big integers. {\edef\TheNumber {\the\numexpr #2}% positive integer \ifnumodd {\TheNumber} {\ifnumgreater {\TheNumber}{1} - {\edef\ItsSquareRoot{\xintiSqrt \TheNumber}% + {\edef\ItsSquareRoot{\xintiiSqrt \TheNumber}% \xintFor ##1 in {\xintintegers [3+2]}\do {\ifnumgreater {##1}{\ItsSquareRoot} {\def#1{1}\xintBreakFor} @@ -7718,7 +7803,7 @@ as they are able to deal with arbitrarily big integers. {\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}% + {\edef\ItsSquareRoot{\xintiiSqrt \TheNumber}% \xintFor """color{red}##1;! in {"""color{red}\xintintegers;! [3+2]}\do {\ifnumgreater {"""color{red}##1;!}{\ItsSquareRoot} """color[named]{PineGreen}% "textcolor{red}{##1} is a \numexpr.;! {\def#1{1}\xintBreakFor} @@ -8062,23 +8147,26 @@ problems). 7562.6481, 8084.0163, 3481.6319, 8078.8512, 2983.7624, 3925.4026, 4931.5812, 1323.1517, 6253.0945}% -\oodef\z {\QSx \somenumbers}% -\hsize 87\fontcharwd\font`0 \setbox0\hbox{\kern\fontcharwd\font`0}% -\lccode`~=32 \lowercase{\def~}{\discretionary{}{}{\copy0}}\catcode32 13 -\noindent\ \ \ \scantokens\expandafter{\meaning\z}\par +\oodef\z {\QSx \somenumbers}% produced as a comma+space separated list +% black magic as workaround to the shrinkability of spaces in last line... +\hsize 87\fontcharwd\font`0 +\lccode`~=32 +\lowercase{\def~}{\discretionary{}{}{\kern\fontcharwd\font`0}}\catcode32 13 +\noindent\phantom{000}\scantokens\expandafter{\meaning\z}\par \endgroup \end{everbatim*} \fi % fin de si pas xetex -All these examples were with numbers which may have been handled via |\ifdim| -tests rather than \csbxint{ifCmp} from \xintfracname ; naturally that would -have been faster. For a yet faster routine (based however on the Merge Sort -and using the |\pdfescapestring| PDF\TeX{} primitive) see |code 6| at -\url{http://tex.stackexchange.com/a/273084}. + +All the previous examples were with numbers which could have been handled via +|\ifdim| tests rather than the \csbxint{ifCmp} macro from \xintfracname; using +|\ifdim| tests would naturally be faster. Even faster routine is |code 6| at +\url{http://tex.stackexchange.com/a/273084} which uses |\pdfescapestring| and a +Merge Sort algorithm. We then turn to a graphical illustration of the algorithm.% % -\footnote{I have rewritten the routine to do only once (and not thrice) the +\footnote{I have rewritten (2015/11/21) the routine to do only once (and not thrice) the needed calls to \csa{xintifCmp}, up to the price of one additional |\edef|, although due to the context execution time on our side is not an issue and moreover is anyhow overwhelmed by the TikZ's activities. Simultaneously I @@ -8236,6 +8324,10 @@ currently this is implemented by using either |\xintifForFirst| or \renewcommand{\etocaftertochook}{\addvspace{\bigskipamount}} \clearpage +\def\n{|{N}|} +\def\m{|{M}|} +\def\x{|{x}|} + \section{Macros of the \xintkernelname package} \label{sec:kernel} @@ -8294,10 +8386,10 @@ argument and just reverses the order of the tokens in the \meta{list}. Braces are removed once and the enclosed material, now unbraced, does not get reversed. Unprotected spaces (of any character code) are gobbled. % -\leftedline{|\xintReverseOrder{\xintDigitsOf\xintiPow {2}{100}\to\Stuff}|} +\leftedline{|\xintReverseOrder{\xintDigitsOf\xintiiPow {2}{100}\to\Stuff}|} % \leftedline{gives: - \ttfamily{\string\Stuff\string\to1002\string\xintiPow\string\xintDigitsOf}} + \ttfamily{\string\Stuff\string\to1002\string\xintiiPow\string\xintDigitsOf}} \subsection{\csbh{xintLength}} \label{xintLength} @@ -8309,11 +8401,11 @@ to count things in the replacement text of a macro |\x| one should do counted. See also \csbxint{NthElt}|{0}| (from \xinttoolsname) which first \fexpan ds its argument and then applies the same code. % -\leftedline{|\xintLength {\xintiPow {2}{100}}|\dtt{=\xintLength - {\xintiPow{2}{100}}}} +\leftedline{|\xintLength {\xintiiPow {2}{100}}|\dtt{=\xintLength + {\xintiiPow{2}{100}}}} % -\leftedline{${}\neq{}$|\xintLen {\xintiPow {2}{100}}|\dtt{=\xintLen - {\xintiPow{2}{100}}}} +\leftedline{${}\neq{}$|\xintLen {\xintiiPow {2}{100}}|\dtt{=\xintLen + {\xintiiPow{2}{100}}}} \subsection{\csbh{xintLastItem}} \label{xintLastItem} @@ -8370,2684 +8462,2163 @@ its salt compared to \csbxint{Length}. \clearpage -\section{Macros of the \xinttoolsname package} +\section{Macros of the \xintcorename package} +\label{sec:core} +\localtableofcontents -\label{sec:tools} +Package \xintcorename is automatically loaded by \xintname. -\localtableofcontents +\xintcorename provides for big integers the four basic arithmetic operations +(addition, subtraction, multiplication, division), as well as powers and +factorials. -\def\n{|{N}|} -\def\m{|{M}|} -\def\x{|{x}|} +In the descriptions of the macros \texttt{\n} and \texttt{\m} stand +for (big) integers or macros \hyperref[ssec:expansions]{\fexpan ding} to +such big integers in strict format as described in \autoref{ssec:inputs}. -These utilities used to be provided within the \xintname package; since |1.09g| -(|2013/11/22|) they have been moved to an independently usable package -\xinttoolsname, which has none of the \xintname facilities regarding big -numbers. Whenever relevant release |1.09h| has made the macros |\long| so they -accept |\par| tokens on input. +All macros require strict integer format on input and produce +strict integer format on output, except:\IMPORTANT +\begin{itemize}[nosep] +\item \csbxint{iNum} which converts to strict integer format an input in + \emph{extended} integer format, i.e. admitting multiple leading plus or + minus signs, then possibly leading zeroes, then digits, +\item \csbxint{Num} which is an alias for the former, which gets redefined by + \xintfracname to accept more generally also decimal numbers or fractions as + input and which truncates them to integers. +\item most macros listed in \autoref{ssec:coredeprecated}. They will get + removed at some future release. +\end{itemize} -First the completely expandable utilities up to \csbxint{iloop}, then the non -expandable utilities. +Most deprecated macros listed in \autoref{ssec:coredeprecated} were by design +applying \csbxint{Num} to their inputs. This was signaled in the macro +description by a \smash{\textcolor[named]{PineGreen}{\Numf}} sign in the +margin,\IMPORTANT and typically the macro had a single |i| in its name, for +example \csa{xintiAdd} was such a companion to \csa{xintiiAdd}. \xintfracname +redefined \csbxint{Num} to be the a macro accepting general fractional input +and truncating it to an integer. Hence a macro such as \csa{xintiAdd} was +compatible with the output format of \xintfracname macros, contrarily to +\csbxint{iiAdd} which handles only strict integer format for its inputs. Of +course, \xintfracname defined also its own \csbxint{Add} which did the +addition of its arguments without truncating them to integers... (but whose +output format is the |A/B[N]| format explained in \autoref{ssec:outputs}, +hence even if representing a small integer it can not be used directly in a +\TeX\ context such as |\ifnum|, contrarily to deprecated \csa{xintiAdd} or to +\csbxint{iiAdd}.) -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. +\begin{framed} + This situation\CHANGEDf{1.2o} was the result of some early-on design + decisions which now appear misguided and impede further development. Hence, + at |1.2o| it has been decided to deprecate \emph{all} such |i|-macros. +\end{framed} +The |ii| in the names of the macros such as \csbxint{iiAdd} serves to stress +that they accept only strict integers as input (this is signaled by the margin +annotation \textcolor[named]{PineGreen}{\emph{f}}), or macros \fexpan ding to +such strict format (big) integers and that they produce strict integers as +output. -See also \ref{xintReverseOrder} and \ref{xintLength} which come with package -\xintkernelname, automatically loaded by \xinttoolsname. +Other macros, such as \csbxint{Double}, lack the |ii|, but this is only a +legacy of the history of the package and they have the same requirements for +input and format of output as the |ii|-macros.% +% +\footnote{Regarding \csbxint{FDg} and \csbxint{LDg}, this is a breaking change + because formerly they used \csbxint{Num}.} -\subsection{\csbh{xintRevWithBraces}}\label{xintRevWithBraces} +The letter \texttt{x} (with margin annotation +\smash{\textcolor[named]{PineGreen}{\numx}}) stands for an argument which will +be handled embedded in |\numexpr..\relax|. It will thus be completely expanded +and must give an integer obeying the \TeX{} bounds. See also +\autoref{sec:useofcount}. This is the case for the argument of \csbxint{iiFac} +or the exponent argument of \csbxint{iiPow}. -%{\small New in release |1.06|.\par} +The {\color[named]{PineGreen}$\star$}'s in the margin are there to remind of +the complete expandability, even \fexpan dability of the macros, as discussed +in \autoref{ssec:expansions}. -\edef\X{\xintRevWithBraces{12345}} -\edef\y{\xintRevWithBraces\X} -\expandafter\def\expandafter\w\expandafter - {\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}} +\subsection{\csbh{xintiNum}}\label{xintiNum} -% -\csa{xintRevWithBraces}\marg{list}\etype{f} first does the \fexpan sion of its -argument then it reverses the order of the tokens, or braced material, it -encounters, maintaining existing braces and adding a brace pair around each -naked token encountered. Space tokens (in-between top level braces or naked -tokens) are gobbled. This macro is mainly thought out for use on a \meta{list} -of such braced material; with such a list as argument the \fexpan sion will only -hit against the first opening brace, hence do nothing, and the braced stuff may -thus be macros one does not want to expand. -% -\leftedline{|\edef\x{\xintRevWithBraces{12345}}|} -% -\leftedline{|\meaning\x:|\dtt{\meaning\X}} -% -\leftedline{|\edef\y{\xintRevWithBraces\x}|} -% -\leftedline{|\meaning\y:|\dtt{\meaning\y}} -% -The examples above could be defined with |\edef|'s because the braced material -did not contain macros. Alternatively: -% -\leftedline{|\expandafter\def\expandafter\w\expandafter|} -% -\leftedline{|{\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}}|} -% -\leftedline{|\meaning\w:|\dtt{\meaning\w}} -% -The macro \csa{xintReverseWithBracesNoExpand}\etype{n} does the same job -without the initial expansion of its argument. +|\xintiNum|\n\etype{f} removes chains of plus or minus signs, followed by +zeroes. +\begin{everbatim*} +\xintiNum{+---++----+--000000000367941789479} +\end{everbatim*} +\subsection{\csbh{xintDouble}}\label{xintDouble} -\subsection{\csbh{xintZapFirstSpaces}, \csbh{xintZapLastSpaces}, \csbh{xintZapSpaces}, \csbh{xintZapSpacesB}} -\label{xintZapFirstSpaces} -\label{xintZapLastSpaces} -\label{xintZapSpaces} -\label{xintZapSpacesB} -%{\small New with release |1.09f|.\par} +|\xintDouble|\n\etype{f} computes |2N|. -\csa{xintZapFirstSpaces}\marg{stuff}\etype{n} does not do \emph{any} expansion -of its argument, nor brace removal of any sort, nor does it alter \meta{stuff} -in anyway apart from stripping away all \emph{leading} spaces. +\subsection{\csbh{xintHalf}}\label{xintHalf} -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.} +|\xintHalf|\n\etype{f} computes |N/2| +truncated towards zero. -\TeX's input scanner already converts consecutive blanks into single space -tokens, but |\xintZapFirstSpaces| handles successfully also inputs with -consecutive multiple space tokens. -However, it is assumed that \meta{stuff} does not contain (except inside braced -sub-material) space tokens of character code distinct from $32$. +\subsection{\csbh{xintInc}}\label{xintInc} -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}}|. +|\xintInc|\n\etype{f} evaluates |N+1|. -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. +\subsection{\csbh{xintDec}}\label{xintDec} -\begingroup -\def\x { \a { \X } { \b \Y } } -% -\leftedline{|\xintZapFirstSpaces { \a { \X } { \b \Y } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}}+++} -\endgroup +|\xintDec|\n\etype{f} evaluates |N-1|. -\medskip +\subsection{\csbh{xintDSL}}\label{xintDSL} -\noindent\csbxint{ZapLastSpaces}\marg{stuff}\etype{n} does not do \emph{any} expansion of -its argument, nor brace removal of any sort, nor does it alter \meta{stuff} in -anyway apart from stripping away all \emph{ending} spaces. The same remarks as -for \csbxint{ZapFirstSpaces} apply. +|\xintDSL|\n\etype{f} is decimal shift left, \emph{i.e.} multiplication by +ten. -% ATTENTION à l'\ignorespaces fait par \color! -\begingroup -\def\x { \a { \X } { \b \Y } } -% -\leftedline{|\xintZapLastSpaces { \a { \X } { \b \Y } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzaplastspaces\expandafter{\x}}}+++} -\endgroup +\subsection{\csbh{xintDSR}}\label{xintDSR} -\medskip +|\xintDSR|\n\etype{f} is truncated decimal shift right, \emph{i.e.} it is the +truncation of |N/10| towards zero. -\noindent\csbxint{ZapSpaces}\marg{stuff}\etype{n} does not do \emph{any} -expansion of its -argument, nor brace removal of any sort, nor does it alter \meta{stuff} in -anyway apart from stripping away all \emph{leading} and all \emph{ending} -spaces. The same remarks as for \csbxint{ZapFirstSpaces} apply. +\subsection{\csbh{xintDSRr}}\label{xintDSRr} -\begingroup -\def\x { \a { \X } { \b \Y } } -% -\leftedline{|\xintZapSpaces { \a { \X } { \b \Y } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapspaces\expandafter{\x}}}+++} -\endgroup +|\xintDSRr|\n\etype{f} is rounded decimal shift right, \emph{i.e.} it is the +rounding of |N/10| away from zero. It is needed in \xintcorename for use by +\csbxint{iiDivRound}.\NewWith {1.2i} -\medskip +\subsection{\csbh{xintFDg}}\label{xintFDg} -\noindent\csbxint{ZapSpacesB}\marg{stuff}\etype{n} does not do \emph{any} -expansion of -its argument, nor does it alter \meta{stuff} in anyway apart from stripping away -all leading and all ending spaces and possibly removing one level of braces if -\meta{stuff} had the shape |{braced}|. The same remarks as for -\csbxint{ZapFirstSpaces} apply. +|\xintFDg|\n\etype{f} outputs the first digit (most significant) of the +number. -\begingroup -\def\x { \a { \X } { \b \Y } } -% -\leftedline{|\xintZapSpacesB { \a { \X } { \b \Y } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++} -\def\x { { \a { \X } { \b \Y } } } -% -\leftedline{|\xintZapSpacesB { { \a { \X } { \b \Y } } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++} -\endgroup - The spaces here at the start and end of the output come from the braced - material, and are not removed (one would need a second application for that; - recall though that the \xintname zapping macros do not expand their argument). +\subsection{\csbh{xintLDg}}\label{xintLDg} -\subsection{\csbh{xintCSVtoList}} -\label{xintCSVtoList} -\label{xintCSVtoListNoExpand} +|\xintLDg|\n\etype{f} outputs the least significant digit. When the number +is positive, this is the same as the remainder in the euclidean division by +ten. +\subsection{\csbh{xintiiSgn}}\label{xintiiSgn} -\csa{xintCSVtoList}|{a,b,c...,z}|\etype{f} returns |{a}{b}{c}...{z}|. A -\emph{list} is by -convention in this manual simply a succession of tokens, where each braced thing -will count as one item (``items'' are defined according to the rules of \TeX{} -for fetching undelimited parameters of a macro, which are exactly the same rules -as for \LaTeX{} and macro arguments [they are the same things]). The word -`list' in `comma separated list of items' has its usual linguistic meaning, -and then an ``item'' is what is delimited by commas. +|\xintiiSgn|\n\etype{f} returns 1 if the number is positive, 0 if it is zero +and -1 if it is negative. -So \csa{xintCSVtoList} takes on input a `comma separated list of items' and -converts it into a `\TeX{} list of braced items'. The argument to -|\xintCSVtoList| may be a macro: it will first be -\hyperref[ssec:expansions]{\fexpan ded}. Hence the item before the first comma, -if it is itself a macro, will be expanded which may or may not be a good thing. -A space inserted at the start of the first item serves to stop that expansion -(and disappears). The macro \csbxint{CSVtoListNoExpand}\etype{n} does the same -job without -the initial expansion of the list argument. +\subsection{\csbh{xintiiOpp}}\label{xintiiOpp} -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). +|\xintiiOpp|\n\etype{f} outputs the opposite |-N| of the number |N|. -Contiguous spaces and tab characters, are collapsed by \TeX{} -into single spaces. All such spaces around commas% -% -\footnote{and multiple space tokens are not a problem; but those at the - top level (not hidden inside braces) \emph{must} be of character code - |32|.} -% -\fbox{are removed}, as well as -the spaces at the start and the spaces at the end of the list.% -% -\footnote{let us recall that this is all done completely expandably... - There is absolutely no alteration of any sort of the item apart from - the stripping of initial and final space tokens (of character code - |32|) and brace removal if and only if the item apart from intial and - final spaces (or more generally multiple |char 32| space tokens) is - braced.} -% -The items may contain explicit |\par|'s or -empty lines (converted by the \TeX{} input parsing into |\par| tokens). +Important note: an input such as |-\foo| is not legal, generally speaking, as +argument to the macros of the \xintname bundle (except, naturally in +\csbxint{expr}-essions). The reason is that the minus sign stops the \fexpan +sion done during parsing of the inputs. One must use the syntax +|\xintiiOpp{\foo}| if one wants to pass |-\foo| as +argument to other macros. -\begingroup +\subsection{\csbh{xintiiAbs}}\label{xintiiAbs} -\edef\X{\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , { {x , - y} } }} +|\xintiiAbs|\n\etype{f} outputs the absolute value of the number. -% -\leftedline{|\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , - { {x , y} } }|} -% -\leftedline{|->|% -{\makeatletter\dtt{\expandafter\strip@prefix\meaning\X}}} +\subsection{\csbh{xintiiAdd}}\label{xintiiAdd} -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. +|\xintiiAdd|\n\m\etype{ff} computes the sum of the two (big) integers. -We observe also that there is a slight difference regarding the brace stripping -of an item: if the braces were not surrounded by spaces, also the initial and -final (but no other) spaces of the \emph{enclosed} material are removed. This is -the only situation where spaces protected by braces are nevertheless removed. +\subsection{\csbh{xintiiCmp}}\label{xintiiCmp} -From the rules above: for an empty argument (only spaces, no braces, no comma) -the output is -\dtt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist { }}} -(a list with one empty item), -for ``|{}|'' the output is -\dtt{\expandafter\detokenize\expandafter - {\romannumeral0\xintcsvtolist { {} }}} -(again a list with one empty item, the braces were removed), -for ``|{ }|'' the output is -\dtt{\expandafter\detokenize\expandafter - {\romannumeral0\xintcsvtolist {{ }}}} -(again a list with one empty item, the braces were removed and then -the inner space was removed), -for ``| { }|'' the output is -\dtt{\expandafter\detokenize\expandafter -{\romannumeral0\xintcsvtolist { { }}}} (again a list with one empty item, the initial space served only to stop the expansion, so this was like ``|{ }|'' as input, the braces were removed and the inner space was stripped), -for ``\texttt{\ \{\ \ \}\ }'' the output is -\dtt{\expandafter\detokenize\expandafter -{\romannumeral0\xintcsvtolist { { } }}} (this time the ending space of the first -item meant that after brace removal the inner spaces were kept; recall though -that \TeX{} collapses on input consecutive blanks into one space token), -for ``|,|'' the output consists of two consecutive -empty items -\dtt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist - {,}}}. Recall that on output everything is braced, a |{}| is an ``empty'' -item. -% -Most of the above is mainly irrelevant for every day use, apart perhaps from the -fact to be noted that an empty input does not give an empty output but a -one-empty-item list (it is as if an ending comma was always added at the end of -the input). +|\xintiiCmp|\n\m\etype{ff} produces \dtt{1} if |N>M|, \dtt{0} if |N=M|, +and \dtt{-1} if |N|% - {\makeatletter\dtt{\expandafter\strip@prefix\meaning\Y}}} -% -\leftedline{|\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} -% -\leftedline -{|\xintCSVtoList\t->|\makeatletter\dtt{\expandafter\strip@prefix\meaning\T}} -% -The results above were automatically displayed using \TeX's primitive -\csa{meaning}, which adds a space after each control sequence name. These spaces -are not in the actual braced items of the produced lists. The first items |\a| -and |\if| were either preceded by a space or braced to prevent expansion. The -macro \csa{xintCSVtoListNoExpand} would have done the same job without the -initial expansion of the list argument, hence no need for such protection but if -|\y| is defined as |\def\y{\a,\b,\c,\d,\e}| we then must do: -% -\leftedline{|\expandafter\xintCSVtoListNoExpand\expandafter {\y}|} Else, we -may have direct use: % -% -\leftedline{|\xintCSVtoListNoExpand - {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} -% -\leftedline{|->|\dtt{\expandafter\detokenize\expandafter - {\romannumeral0\xintcsvtolistnoexpand - {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}}}} -% -Again these spaces are an artefact from the use in the source of the document of -\csa{meaning} (or rather here, \csa{detokenize}) to display the result of using -\csa{xintCSVtoListNoExpand} (which is done for real in this document -source). +\subsection{\csbh{xintiiSub}}\label{xintiiSub} -For the similar conversion from comma separated list to braced items list, but -without removal of spaces around the commas, there is -\csa{xintCSVtoListNonStripped}\etype{f} and -\csa{xintCSVtoListNonStrippedNoExpand}\etype{n}. +|\xintiiSub|\n\m\etype{ff} computes the difference |N-M|. -\endgroup +\subsection{\csbh{xintiiMul}}\label{xintiiMul} -\subsection{\csbh{xintNthElt}}\label{xintNthElt} +|\xintiiMul|\n\m\etype{ff} computes the product of two (big) integers. +\subsection{\csbh{xintiiSqr}}\label{xintiiSqr} -\def\macro #1{\the\numexpr 9-#1\relax} +|\xintiiSqr|\n\etype{f} produces the square. -\csa{xintNthElt\x}\marg{list}\etype{\numx f} gets (expandably) the |x|th -item of the \meta{list}. A braced item will lose one level of brace -pairs. The token list is first \fexpan ded. +\subsection{\csbh{xintiiPow}}\label{xintiiPow} -Items are counted starting at one. +|\xintiiPow|\n\x\etype{f\numx} computes |N^x|. For |x=0|, this is 1. For |N=0| +and |x<0|, or if \verb+|N|>1+ and |x<0|, an error is raised. There will also +be an error if |x| exceeds the maximal \eTeX{} number \dtt{\number"7FFFFFFF}, +but the real limit for exponents comes from either the computation time or the +settings of some \TeX\ memory parameters. -\leftedline{|\xintNthElt {3}{{agh}\u{zzz}\v{Z}}| is - \texttt{\xintNthElt {3}{{agh}\u{zzz}\v{Z}}}} -% -\leftedline{|\xintNthElt {3}{{agh}\u{{zzz}}\v{Z}}| is - \texttt{\expandafter\expandafter\expandafter - \detokenize\expandafter\expandafter\expandafter {\xintNthElt - {3}{{agh}\u{{zzz}}\v{Z}}}}} -% -\leftedline{|\xintNthElt {2}{{agh}\u{{zzz}}\v{Z}}| is - \texttt{\expandafter\expandafter\expandafter - \detokenize\expandafter\expandafter\expandafter {\xintNthElt - {2}{{agh}\u{{zzz}}\v{Z}}}}} -% -\leftedline{|\xintNthElt {37}{\xintiiFac {100}}|\dtt{=\xintNthElt - {37}{\xintiiFac {100}}} is the thirty-seventh digit of $100!$.} -% -\leftedline{|\xintNthElt {10}{\xintFtoCv - {566827/208524}}|\dtt{=\xintNthElt {10}{\xintFtoCv - {566827/208524}}}} -\leftedline{is the tenth convergent of $566827/208524$ (uses \xintcfracname - package).} -% -\leftedline{|\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% - \dtt{=\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} -% -\leftedline{|\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% - \dtt{=\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} -% -\leftedline{|\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% - \dtt{=\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} +\begin{framed} + Indeed, the maximal power of $2$ which \xintname is able to compute + explicitely is |2^(2^17)=2^131072| which has \dtt{39457} digits. This + exceeds the maximal size on input for the \xintcorename multiplication, hence + any |2^N| with a higher |N| will fail. On the other hand |2^(2^16)| has + \dtt{19729} digits, thus it can be squared once to obtain |2^(2^17)| or + multiplied by anything smaller, thus all exponents up to and including |2^17| + are allowed (because the power operation works by squaring things and making + products). +\end{framed} -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. +% Side remark: after all it does pay to think! I almost melted my CPU trying by +% dichotomy to pin-point the exact maximal allowable |N| for |\xintiiPow 2{N}| +% before finally making the reasoning above. Indeed, each such computation with +% |N>130000| activates the fan of my laptop and results in so warm a keyboard +% that I can hardly go on working on it! And it takes about 12 minutes for each +% |\xintiiPow2{N}| with such |N|'s of the order of $130000$ (a.t.t.o.w.). -If |x<0|, the macro returns the \verb+|x|+th element from the end of the list. -Thus for example |x=-1| will fetch the last item of the list. -% -\leftedline {|\xintNthElt {-5}{{{agh}}\u{zzz}\v{Z}}| is - \texttt{\expandafter\expandafter\expandafter \detokenize - \expandafter\expandafter\expandafter{\xintNthElt {-5}{{{agh}}\u{zzz}\v{Z}}}}} +\subsection{\csbh{xintiiFac}}\label{xintiiFac} -The macro \csa{xintNthEltNoExpand}\etype{\numx n} does the same job but without -first expanding the list argument: |\xintNthEltNoExpand {-4}{\u\v\w T\x\y\z}| is -\xintNthEltNoExpand {-4}{\a\b\c\u\v\w T\x\y\z}. +|\xintiiFac|\x\etype{\numx} computes the factorial. -If |x| is strictly larger (in absolute value) than the length of the list -then |\xintNthElt| produces empty contents. +\begin{framed} + The (theoretically) allowable range is $0\leqslant x\leqslant10000$. -\subsection{\csbh{xintKeep}}\label{xintKeep} + However the maximal possible computation depends on the values of some memory + parameters of the |tex| executable: with the current default settings of + TeXLive 2015, the maximal computable factorial (a.t.t.o.w. 2015/10/06) turns + out to be $5971!$ which has $19956$ digits.%\footnotemark +\end{framed} -\csa{xintKeep\x}\marg{list}\etype{\numx f} expands the token list argument |L| -and produces a new list, depending on the value of |x|: -\begin{itemize}[nosep] -\item if |x>0|, the new list contains the first |x| items from |L| (counting - starts at one.) \emph{Each - such item will be output within a brace pair.} Use \csbxint{KeepUnbraced} is - this is not desired. This means that if the list item was braced to start - with, there is no modification, but if it was a token without braces, - then it acquires them. -\item if |x>=length(L)|, the new list is the old one with all its items now - braced. -\item if |x=0| the empty list is returned. -\item if |x<0| the last \verb+|x|+ elements compose the output in the same - order as in the initial list; as the macro proceeds by removing head items - the kept items end up in output as they were in input: no added braces. -\item if |x<=-length(L)| the output is identical with the input. -\end{itemize} -\csa{xintKeepNoExpand} does the same without first \fexpan ding its list -argument. -% + +The |factorial| function, or equivalently |!| as post-fix operator is +available in \csbxint{iiexpr}, \csbxint{expr}: \begin{everbatim*} -\fdef\test {\xintKeep {17}{\xintKeep {-69}{\xintSeq {1}{100}}}}\meaning\test\par -\noindent\fdef\test {\xintKeep {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintKeep {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintKeep {7}{123456789}}\meaning\test\par -\noindent\fdef\test {\xintKeep {-7}{123456789}}\meaning\test\par +\printnumber{\xinttheiiexpr 200!\relax}\par \end{everbatim*} +See also \csbxint{FloatFac} from package \xintfracname for the float variant, +used in \csbxint{floatexpr}. -\subsection{\csbh{xintKeepUnbraced}}\label{xintKeepUnbraced} -Same as \csbxint{Keep} but no brace pairs are added around the kept items from -the head of the list in the case |x>0|: each such item will lose one level of -braces. Thus, to remove braces from all items of the list, one can use -\csbxint{KeepUnbraced} with its first argument larger than the length of the -list; the same is obtained from \csbxint{ListWithSep}|{}|\marg{list}. But the -new list will then have generally many more items than the original ones, -corresponding to the unbraced original items. +\subsection{\csbh{xintiiDivision}}\label{xintiiDivision} -For |x<0| the macro is no different from \csbxint{Keep}. Hence the name is a -bit misleading because brace removal will happen only if |x>0|. -\csa{xintKeepUnbracedNoExpand} does the same without first \fexpan ding -its list argument. -% -\begin{everbatim*} -\fdef\test {\xintKeepUnbraced {10}{\xintSeq {1}{100}}}\meaning\test\par -\noindent\fdef\test {\xintKeepUnbraced {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintKeepUnbraced {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintKeepUnbraced {7}{123456789}}\meaning\test\par -\noindent\fdef\test {\xintKeepUnbraced {-7}{123456789}}\meaning\test\par -\end{everbatim*} +|\xintiiDivision|\n\m\etype{ff} produces |{quotient}{remainder}|, in the sense +of (mathematical) Euclidean division: |N = QM + R|, +|0|${}\leq{}$\verb+R < |M|+. So the remainder is always non-negative and the +formula |N = QM + R| always holds independently of the signs of |N| or |M|. +Division by zero is an error (even if |N| vanishes) and returns |{0}{0}|. -\subsection{\csbh{xintTrim}}\label{xintTrim} +\subsection{\csbh{xintiiQuo}}\label{xintiiQuo} -\csa{xintTrim\x}\marg{list}\etype{\numx f} expands the list argument and -gobbles its first |x| elements. -\begin{itemize}[nosep] -\item if |x>0|, the first |x| items from |L| are gobbled. The remaining items - are not modified. -\item if |x>=length(L)|, the returned list is empty. -\item if |x=0| the original list is returned (with no added braces.) -\item if |x<0| the last \verb+|x|+ items of the list are removed. \emph{The - head items end up braced in the output.} Use \csbxint{TrimUnbraced} if - this is not desired. -\item if |x<=-length(L)| the output is empty. -\end{itemize} +|\xintiiQuo|\n\m\etype{ff} computes the quotient from the euclidean division. -\csa{xintTrimNoExpand} does the same without first \fexpan ding its list -argument. +\subsection{\csbh{xintiiRem}}\label{xintiiRem} + +|\xintiiRem|\n\m\etype{ff} computes the remainder from the euclidean +division. + +\subsection{\csbh{xintiiDivRound}}\label{xintiiDivRound} + +|\xintiiDivRound|\n\m\etype{ff} returns the rounded value of the algebraic +quotient $N/M$ of two big integers. The rounding is ``away from zero.'' \begin{everbatim*} -\fdef\test {\xintTrim {17}{\xintTrim {-69}{\xintSeq {1}{100}}}}\meaning\test\par -\noindent\fdef\test {\xintTrim {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintTrim {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintTrim {7}{123456789}}\meaning\test\par -\noindent\fdef\test {\xintTrim {-7}{123456789}}\meaning\test\par +\xintiiDivRound {100}{3}, \xintiiDivRound {101}{3} \end{everbatim*} -\subsection{\csbh{xintTrimUnbraced}}\label{xintTrimUnbraced} +\subsection{\csbh{xintiiDivTrunc}}\label{xintiiDivTrunc} -Same as \csbxint{Trim} but in case of a negative |x| (cutting items from -the tail), the kept items from the head are not enclosed in brace pairs. They -will lose one level of braces. The name is a bit misleading -because when |x>0| there is no brace-stripping done on the kept items, because -the macro works simply by gobbling the head ones. +|\xintiiDivTrunc|\n\m\etype{ff} computes the truncation towards zero of the +algebraic quotient $N/M$. For $M>0$ it is the same as \csbxint{iiQuo}. +\begin{everbatim*} +$\xintiiQuo {1000}{-57}, \xintiiDivRound {1000}{-57}, \xintiiDivTrunc {1000}{-57}$ +\end{everbatim*} -\csa{xintTrimUnbracedNoExpand} does the same without first \fexpan ding its list -argument. +\subsection{\csbh{xintiiMod}}\label{xintiiMod} +|\xintiiMod|\n\m\etype{ff} computes $N - M*t(N/M)$, where $t(N/M)$ is the +algebraic quotient truncated towards zero. For $M>0$ it is the same as +\csbxint{iiRem}. \begin{everbatim*} -\fdef\test {\xintTrimUnbraced {-90}{\xintSeq {1}{100}}}\meaning\test\par -\noindent\fdef\test {\xintTrimUnbraced {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintTrimUnbraced {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintTrimUnbraced {7}{123456789}}\meaning\test\par -\noindent\fdef\test {\xintTrimUnbraced {-7}{123456789}}\meaning\test\par +$\xintiiRem {1000}{-57}, \xintiiMod {1000}{-57}, + \xintiiRem {-1000}{57}, \xintiiMod {-1000}{57}$ \end{everbatim*} -\subsection{\csbh{xintListWithSep}}\label{xintListWithSep} +\subsection{\csbh{xintNum}}\label{xintNum} +|\xintNum|\etype{f} is originally an alias for \csbxint{iNum}. But with +\xintfracname loaded its meaning is \hyperref[xintNumFrac]{modified} to accept +more general inputs. It then becomes an alias to \csbxint{TTrunc} which +truncates the general input to an integer in strict format. + +\subsection{Deprecated macros}\label{ssec:coredeprecated} + +These macros work as in earlier releases but will also generate an error (in +interactive mode, just hit the return key to proceed). They will get removed +at some future release:\DEPRECATED{1.2o} +|\xintiiFDg| (renamed to \csbxint{FDg}), +|\xintiiLDg| (renamed to \csbxint{LDg}), +|\xintiOpp|, +|\xintiAbs|, +|\xintiAdd|, +|\xintCmp| (it gets defined by \xintfracname, so deprecation will usually not be +seen; the macro with this name from former \xintcorename should have been +called |\xintiCmp| actually), +|\xintSgn| (it also gets its proper definition from \xintfracname), +|\xintiSub|, +|\xintiMul|, +|\xintiDivision|, +|\xintiQuo|, +|\xintiRem|, +|\xintiDivRound|, +|\xintiDivTrunc|, +|\xintiMod|, +|\xintiSqr|, +|\xintiPow|, +|\xintiFac|. -\def\macro #1{\the\numexpr 9-#1\relax} -\csa{xintListWithSep}|{sep}|\marg{list}\etype{nf} inserts the separator |sep| -in-between all items of the given list. The items will be unbraced. The -separator may be a macro but will not be pre-expanded. The list argument is -\fexpan ded. -\begin{everbatim*} -\edef\foo {\xintListWithSep{,}{{1}{2}{3}}}\meaning\foo\newline -\edef\foo {\xintListWithSep{:}{\xintiiFac{20}}}\meaning\foo\par -\end{everbatim*} -An empty input gives an empty output, a singleton gives a singleton, and the -separator is used starting with at least two elements. Using an empty -separator has the net effect of unbracing the braced items constituting the -\meta{list} (then the new list will generally have many more ``items'' than -the original one). -% +\clearpage +\section{Macros of the \xintname package} +\label{sec:xint} -The macro \csa{xintListWithSepNoExpand}\etype{nn} does the same -job without the initial expansion. +This package loads automatically \xintcorename (and \xintkernelname) hence +all macros described in \autoref{sec:core} are still available. -\subsection{\csbh{xintApply}}\label{xintApply} +\etocsetnexttocdepth{subsubsection} +\localtableofcontents +This is \texttt{\xintbndlversion} of +\texttt{\xintbndldate}. -\def\macro #1{\the\numexpr 9-#1\relax} +Version |1.0| was released |2013/03/28|. +Since |1.1 2014/10/28| the core arithmetic macros have been moved to a separate +package \xintcorename, which is automatically loaded by \xintname. +Only the \csbxint{iiSum}, \csbxint{iiPrd}, \csbxint{iiSquareRoot}, +\csbxint{iiPFactorial}, \csbxint{iiBinomial} genuinely add to the arithmetic +macros from \xintcorename. (\csbxint{iiFac} which computes factorials is +already in \xintcorename.) + +With the exception of \csbxint{Len}, of the «Boolean logic macros» (see +next paragraph) all macros require inputs being integers in strict format, see \autoref{ssec:inputs}.% +% +\footnote{of +course for conditionals such as \csbxint{iiifCmp} this constraint applies only +to the first two arguments.} +% +The |ii| in the macro names is here as a reminder of that fact. The output is +an integer in strict format, or a pair of two braced such integers for +\csbxint{iiSquareRoot}, with the exception of \csbxint{iiE} which may produce +strings of zero's if its first argument is zero. + +Macros \csbxint{DecSplit} and \csbxint{ReverseDigits} are non-arithmetic and +have their own specific rules. + +For all macros described here for which it makes sense, package \xintfracname +defines a similar one without |ii| in its name. This will handle more general +inputs: decimal, scientific numbers, fractions. The |ii| macros provided here +by \xintname can be nested inside macros of \xintfracname but the opposite +does not apply, because the output format of the \xintfracname macros, even +for representing integers, is not understood by the |ii| macros. The «Boolean +macros» \csbxint{AND} etc... are exceptions though, they work fine if served +as inputs some \xintfracname output, despite doing only \fexpan +sion.\CHANGED{1.2o} Prior to |1.2o|, these macros did apply the \csbxint{Num} +or the more general \xintfracname general parsing, but this overhead was +deemed superfluous as it serves only to handle hand-written input and is not +needed if the input is obtained as a nested chain of \xintfracname macros for +example. -\csa{xintApply}|{\macro}|\marg{list}\etype{ff} expandably applies the one -parameter macro |\macro| to each item in the \meta{list} given as second -argument and returns a new list with these outputs: each item is given one after -the other as parameter to |\macro| which is expanded at that time (as usual, -\emph{i.e.} fully for what comes first), the results are braced and output -together as a succession of braced items (if |\macro| is defined to start with a -space, the space will be gobbled and the |\macro| will not be expanded; it is -allowed to have its own arguments, the list items serve as last arguments to -|\macro|). Hence |\xintApply{\macro}{{1}{2}{3}}| returns -|{\macro{1}}{\macro{2}}{\macro{3}}| where all instances of |\macro| have been -already \fexpan ded. +Prior to release |1.2o|, \xintname defined additional macros which applied +\csbxint{Num} to their input arguments. All these macros are now deprecated +and they will get removed at some future release.\CHANGED{1.2o} -Being expandable, |\xintApply| is useful for example inside alignments where -implicit groups make standard loops constructs usually fail. In such situation -it is often not wished that the new list elements be braced, see -\csbxint{ApplyUnbraced}. The |\macro| does not have to be expandable: -|\xintApply| will try to expand it, the expansion may remain partial. +See \autoref{ssec:expansions} for the significance of the +\textcolor[named]{PineGreen}{\Numf}, \textcolor[named]{PineGreen}{\emph{f}}, +\textcolor[named]{PineGreen}{\numx} and \textcolor[named]{PineGreen}{$\star$} +margin annotations. -The \meta{list} may -itself be some macro expanding (in the previously described way) to the list of -tokens to which the macro |\macro| will be applied. For example, if the -\meta{list} expands to some positive number, then each digit will be replaced by -the result of applying |\macro| on it. % -% -\leftedline{|\def\macro #1{\the\numexpr - 9-#1\relax}|} % -% -\leftedline{|\xintApply\macro{\xintiiFac - {20}}|\dtt{=\xintApply\macro{\xintiiFac {20}}}} -The macro \csa{xintApplyNoExpand}\etype{fn} does the same job without the first -initial expansion which gave the \meta{list} of braced tokens to which |\macro| -is applied. -\subsection{\csbh{xintApplyUnbraced}}\label{xintApplyUnbraced} -\csa{xintApplyUnbraced}|{\macro}|\marg{list}\etype{ff} is like \csbxint{Apply}. -The difference is that after having expanded its list argument, and applied -|\macro| in turn to each item from the list, it reassembles the outputs without -enclosing them in braces. The net effect is the same as doing -% -\leftedline{|\xintListWithSep {}{\xintApply {\macro}|\marg{list}|}|} This is -useful for preparing a macro which will itself define some other macros or make -assignments, as the scope will not be limited by brace pairs. -% +\subsection{\csbh{xintiLen}}\label{xintiLen} + +|\xintiLen|\n\etype{\Numf} returns the length of the number, after its parsing +via \csbxint{iNum}. The count does not include the sign.\NewWith{1.2o} \begin{everbatim*} -\def\macro #1{\expandafter\def\csname myself#1\endcsname {#1}} -\xintApplyUnbraced\macro{{elta}{eltb}{eltc}} -\begin{enumerate}[nosep,label=(\arabic{*})] -\item \meaning\myselfelta -\item \meaning\myselfeltb -\item \meaning\myselfeltc -\end{enumerate} +\xintiLen{-12345678901234567890123456789} \end{everbatim*} -% -The macro \csa{xintApplyUnbracedNoExpand}\etype{fn} does the same job without -the first initial expansion which gave the \meta{list} of braced tokens to which -|\macro| is applied. - -\subsection{\csbh{xintSeq}}\label{xintSeq} - -\csa{xintSeq}|[d]{x}{y}|\etype{{{\upshape[\numx]}}\numx\numx} generates -expandably |{x}{x+d}...| up to and possibly including |{y}| if |d>0| or down -to and including |{y}| if |d<0|. Naturally |{y}| is omitted if |y-x| is not a -multiple of |d|. If |d=0| the macro returns |{x}|. If |y-x| and |d| have -opposite signs, the macro returns nothing. If the optional argument |d| is -omitted it is taken to be the sign of |y-x|. Hence |\xintSeq {1}{0}| is not -empty but |{1}{0}|. But |\xintSeq [1]{1}{0}| is empty. +Prior to |1.2o|, the package defined only \csbxint{Len}, which is extended by +\xintfracname to fractions or decimal numbers, hence acquires a bit more +overhead then. +\subsection{\csbh{xintReverseDigits}} \label{xintReverseDigits} -The arguments |x| and |y| are expanded inside a |\numexpr| so they may be -count registers or a \LaTeX{} |\value{countername}|, or arithmetic with such -things. +|\xintReverseDigits|\n\etype{f} will reverse the order of the digits of the +number. \csa{xintRev} is the former denomination and is kept as an alias. +Leading zeroes resulting from the operation are not removed. Contrarily to +\csbxint{ReverseOrder} this macro \fexpan ds its argument; it is only usable +with digit tokens. It does \emph{not} apply \csbxint{Num} to its argument (so +this must be done explicitely if the argument is an integer produced from some +\xintfracname macros). It does accept a leading minus sign which will be left +upfront in the output. -% +\begingroup \begin{everbatim*} -\xintListWithSep{,\hskip2pt plus 1pt minus 1pt }{\xintSeq {12}{-25}} +\oodef\x{\xintReverseDigits + {98765432109876543210987654321098765432109876543210}}\meaning\x\par +\noindent\oodef\x{\xintReverseDigits {\xintReverseDigits + {98765432109876543210987654321098765432109876543210}}}\meaning\x\par \end{everbatim*} -% +\endgroup + +\subsection{\csbh{xintDecSplit}} +\label{xintDecSplit} + +|\xintDecSplit|\x\n\etype{\numx f} cuts the |N| (a list of digits) into two +pieces |L| and |R|: it outputs |{L}{R}| where the original |N| +is the concatenation |LR|. These two pieces are decided according to |x|: +\begin{itemize}[nosep] +\item for |x>0|, |R| coincides with the |x| least significant digits. If |x| + equals or exceeds the length of |N| the first piece |L| will thus be + \emph{empty}, +\item for |x=0|, |R| is empty, and |L| is all of |N|, +\item for |x<0|, the first piece |L| consists of the \verb+|x|+ most + significant digits and the second piece |R| gets the remaining ones. If |x| + equals or exceeds the length of |N| the second piece |R| will thus be + \emph{empty}. +\end{itemize} + +This macro provides public interface to some functionality which is primarily +of internal interest. It operates only (after \fexpan sion) on ``strings'' of +digits tokens: leading zeroes are allowed but a leading sign (even a minus +sign) will provoke an error. + +Breaking change with |1.2i|:\CHANGED{1.2i} formerly |N<0| was replaced by its + absolute value. Now, a sign (positive or negative) will create an error. + + +\subsection{\csbh{xintDecSplitL}, \csbh{xintDecSplitR}} +\label{xintDecSplitL} +\label{xintDecSplitR} + +|\xintDecSplitL|\x\n\etype{\numx f} returns the first piece (unbraced) from +the \csa{xintDecSplit} output. + +\noindent|\xintDecSplitR|\x\n\etype{\numx f} returns the second piece +(unbraced) from the \csa{xintDecSplit} output. + +\subsection{\csbh{xintiiE}}\label{xintiiE} + +|\xintiiE|\n\x\etype{f\numx } serves to extend |N| with |x| zeroes. The +parameter |x| must be non-negative. The same output would be obtained via +\csbxint{DSH}|{-x}{N}|, except for |N=0|, as |\xintDSH{-x}{N}| multiplies |N| +by |10^x| hence produces |0| if |N=0| whereas +|\xintiiE{0}{x}| produces |x+1| zeros. \begin{everbatim*} -\xintiiSum{\xintSeq [3]{1}{1000}} +\xintiiE {0}{91}\par \end{everbatim*} -When the macro is used without the optional argument |d|, it can only generate -up to about $5000$ numbers\IMPORTANT, the precise value depends upon some -\TeX{} memory parameter (input save stack). +\subsection{\csbh{xintDSH}}\label{xintDSH} -With the optional argument |d| the macro proceeds differently (but less -efficiently) and does not stress the input save stack. +|\xintDSH|\x\n\etype{\numx f} is parametrized decimal shift. When |x| is +negative, it is like iterating \csbxint{DSL} \verb+|x|+ times (\emph{i.e.} +multiplication by $10^{-x}$). When |x| positive, it is like iterating +\csbxint{DSR} |x| times (and is more efficient), and for a non-negative |N| +this is thus the same as the quotient from the euclidean division by |10^x|. +\subsection{\csbh{xintDSHr}, \csbh{xintDSx}}\label{xintDSHr}\label{xintDSx} +|\xintDSHr|\x\n\etype{\numx f} expects |x| to be zero or positive and it +returns then a value |R| which is correlated to the value |Q| returned by +\csbxint{DSH}\x\n{} in the following manner: +\begin{itemize} +\item if |N| is + positive or zero, |Q| and |R| are the quotient and remainder in + the euclidean division by |10^x| (obtained in a more efficient + manner than using \csa{xintiDivision}), +\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|. -\subsection{\csbh{xintloop}, \csbh{xintbreakloop}, \csbh{xintbreakloopanddo}, \csbh{xintloopskiptonext}} -\label{xintloop} -\label{xintbreakloop} -\label{xintbreakloopanddo} -\label{xintloopskiptonext} +|\xintDSx|\x\n\etype{\numx f} for |x| negative is exactly as +|\xintDSH|\x\n, \emph{i.e.} multiplication by $10^{-|x|}$. For |x| zero or +positive it returns the two numbers |{Q}{R}| described above, each one within +braces. So |Q| is |\xintDSH|\x\n, and |R| is |\xintDSHr|\x\n, but computed +simultaneously. -|\xintloop|\meta{stuff}|\if...\repeat|\retype{} is an expandable loop -compatible with nesting. However to break out of the loop one almost always need -some un-expandable step. The cousin \csbxint{iloop} is \csbxint{loop} with an -embedded expandable mechanism allowing to exit from the loop. The iterated -macros may contain |\par| tokens or empty lines. +\subsection{\csbh{xintiiEq}}\label{xintiiEq} -If a sub-loop is to be used all the material from the start of the main loop and -up to the end of the entire subloop should be braced; these braces will be -removed and do not create a group. The simplest to allow the nesting of one or -more sub-loops is to brace everything between \csa{xintloop} and \csa{repeat}, -being careful not to leave a space between the closing brace and |\repeat|. +|\xintiiEq|\n\m\etype{ff} returns 1 if |N=M|, 0 otherwise. -As this loop and \csbxint{iloop} will primarily be of interest to experienced -\TeX{} macro programmers, my description will assume that the user is -knowledgeable enough. Some examples in this document will be perhaps more -illustrative than my attemps at explanation of use. +\subsection{\csbh{xintiiNotEq}}\label{xintiiNotEq} -One can abort the loop with \csbxint{breakloop}; this should not be used inside -the final test, and one should expand the |\fi| from the corresponding test -before. One has also \csbxint{breakloopanddo} whose first argument will be -inserted in the token stream after the loop; one may need a macro such as -|\xint_afterfi| to move the whole thing after the |\fi|, as a simple -|\expandafter| will not be enough. +|\xintiiNotEq|\n\m\etype{ff} returns 0 if |N=M|, 1 otherwise. -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*}. +Former denomination \csa{xintiiNeq} is deprecated. -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.} -% +\subsection{\csbh{xintiiGeq}}\label{xintiiGeq} +|\xintiiGeq|\n\m\etype{ff} returns 1 if the \emph{absolute value} +of the first number is at least equal to the absolute value of the second +number. If \verb+|N|<|M|+ it returns 0. -\begin{everbatim*} -\newcount\rowmax \newcount\colmax \newcount\summax -\newcount\rowindex \newcount\colindex \newcount\sumindex -\newcount\tmpcount -\makeatletter -\def\MatrixMultiplication #1#2#3{% - \rowmax #1[I]\relax - \colmax #2[J]\relax - \summax #1[J]\relax - \rowindex 1 - \xintloop % loop over row index i - {\colindex 1 - \xintloop % loop over col index k - {\tmpcount 0 - \sumindex 1 - \xintloop % loop over intermediate index j - \advance\tmpcount \numexpr #1\rowindex\sumindex*#2\sumindex\colindex\relax - \ifnum\sumindex<\summax - \advance\sumindex 1 - \repeat }% - \expandafter\edef\csname\string#3{\the\rowindex.\the\colindex}\endcsname - {\the\tmpcount}% - \ifnum\colindex<\colmax - \advance\colindex 1 - \repeat }% - \ifnum\rowindex<\rowmax - \advance\rowindex 1 - \repeat - \expandafter\edef\csname\string#3{I}\endcsname{\the\rowmax}% - \expandafter\edef\csname\string#3{J}\endcsname{\the\colmax}% - \def #3##1{\ifx[##1\expandafter\Matrix@helper@size - \else\expandafter\Matrix@helper@entry\fi #3{##1}}% -}% -\def\Matrix@helper@size #1#2#3]{\csname\string#1{#3}\endcsname }% -\def\Matrix@helper@entry #1#2#3% - {\csname\string#1{\the\numexpr#2.\the\numexpr#3}\endcsname }% -\def\A #1{\ifx[#1\expandafter\A@size - \else\expandafter\A@entry\fi {#1}}% -\def\A@size #1#2]{\ifx I#23\else4\fi}% 3rows, 4columns -\def\A@entry #1#2{\the\numexpr #1+#2-1\relax}% not pre-computed... -\def\B #1{\ifx[#1\expandafter\B@size - \else\expandafter\B@entry\fi {#1}}% -\def\B@size #1#2]{\ifx I#24\else3\fi}% 4rows, 3columns -\def\B@entry #1#2{\the\numexpr #1-#2\relax}% not pre-computed... -\makeatother -\MatrixMultiplication\A\B\C \MatrixMultiplication\C\C\D -\MatrixMultiplication\C\D\E \MatrixMultiplication\C\E\F -\begin{multicols}2 - \[\begin{pmatrix} - \A11&\A12&\A13&\A14\\ - \A21&\A22&\A23&\A24\\ - \A31&\A32&\A33&\A34 - \end{pmatrix} - \times - \begin{pmatrix} - \B11&\B12&\B13\\ - \B21&\B22&\B23\\ - \B31&\B32&\B33\\ - \B41&\B42&\B43 - \end{pmatrix} - = - \begin{pmatrix} - \C11&\C12&\C13\\ - \C21&\C22&\C23\\ - \C31&\C32&\C33 - \end{pmatrix}\] - \[\begin{pmatrix} - \C11&\C12&\C13\\ - \C21&\C22&\C23\\ - \C31&\C32&\C33 - \end{pmatrix}^2 = \begin{pmatrix} - \D11&\D12&\D13\\ - \D21&\D22&\D23\\ - \D31&\D32&\D33 - \end{pmatrix}\] - \[\begin{pmatrix} - \C11&\C12&\C13\\ - \C21&\C22&\C23\\ - \C31&\C32&\C33 - \end{pmatrix}^3 = \begin{pmatrix} - \E11&\E12&\E13\\ - \E21&\E22&\E23\\ - \E31&\E32&\E33 - \end{pmatrix}\] - \[\begin{pmatrix} - \C11&\C12&\C13\\ - \C21&\C22&\C23\\ - \C31&\C32&\C33 - \end{pmatrix}^4 = \begin{pmatrix} - \F11&\F12&\F13\\ - \F21&\F22&\F23\\ - \F31&\F32&\F33 - \end{pmatrix}\] -\end{multicols} -\end{everbatim*} +Important: the macro compares \emph{absolute values}. +\subsection{\csbh{xintiiGt}}\label{xintiiGt} -\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} +|\xintiiGt|\n\m\etype{ff} returns 1 if |N|$>$|M|, 0 otherwise. -\csa{xintiloop}|[start+delta]|\meta{stuff}|\if ... \repeat|\retype{} is a -completely expandable nestable loop. complete expandability depends naturally on -the actual iterated contents, and complete expansion will not be achievable -under a sole \fexpan sion, as is indicated by the hollow star in the margin; -thus the loop can be used inside an |\edef| but not inside arguments to the -package macros. It can be used inside an |\xintexpr..\relax|. The -|[start+delta]| is mandatory, not optional. +\subsection{\csbh{xintiiLt}}\label{xintiiLt} -This loop benefits via \csbxint{iloopindex} to (a limited access to) the integer -index of the iteration. The starting value |start| (which may be a |\count|) and -increment |delta| (\emph{id.}) are mandatory arguments. A space after the -closing square bracket is not significant, it will be ignored. Spaces inside the -square brackets will also be ignored as the two arguments are first given to a -|\numexpr...\relax|. Empty lines and explicit |\par| tokens are accepted. +|\xintiiLt|\n\m\etype{ff} returns 1 if |N|$<$|M|, 0 otherwise. -As with \csbxint{loop}, this tool will mostly be of interest to advanced users. -For nesting, one puts inside braces all the -material from the start (immediately after |[start+delta]|) and up to and -inclusive of the inner loop, these braces will be removed and do not create a -loop. In case of nesting, \csbxint{outeriloopindex} gives access to the index of -the outer loop. If needed one could write on its model a macro giving access to -the index of the outer outer loop (or even to the |nth| outer loop). +\subsection{\csbh{xintiiGtorEq}}\label{xintiiGxstorEq} -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|. +|\xintiiGtorEq|\n\m\etype{ff} returns 1 if |N|$\geqslant$|M|, 0 otherwise. +Extended by \xintfracname to fractions. -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|. +\subsection{\csbh{xintiiLtorEq}}\label{xintiiLtorEq} -One has \csbxint{breakiloop} and \csbxint{breakiloopanddo} to abort the loop. -The syntax of |\xintbreakiloopanddo| is a bit surprising, the sequence of tokens -to be executed after breaking the loop is not within braces but is delimited by -a dot as in: -% -\leftedline{|\xintbreakiloopanddo .etc.. etc... \repeat|} -% -The reason is that one may wish to use the then current value of -|\xintiloopindex| in || but it can't be within braces at the time it -is evaluated. However, it is not that easy as |\xintiloopindex| must be expanded -before, so one ends up with code like this: -% -\leftedline -{|\expandafter\xintbreakiloopanddo\expandafter\macro\xintiloopindex.%|} -% -\leftedline{|etc.. etc.. \repeat|} -% -As moreover the |\fi| from the test leading to the decision of breaking out of -the loop must be cleared out of the way, the above should be -a branch of an expandable conditional test, else one needs something such -as: -% -\leftedline -{|\xint_afterfi{\expandafter\xintbreakiloopanddo\expandafter\macro\xintiloopindex.}%|} -% -\leftedline{|\fi etc..etc.. \repeat|} +|\xintiiLtorEq|\n\m\etype{ff} returns 1 if |N|$\leqslant$|M|, 0 otherwise. -There is \csbxint{iloopskiptonext} to abort the current iteration and skip to -the next, \hyperref[xintiloopskipandredo]{\ttfamily\hyphenchar\font45 \char92 - xintiloopskip\-and\-redo} to skip to the end of the current iteration and redo -it with the same value of the index (something else will have to change for this -not to become an eternal loop\dots ). +\subsection{\csbh{xintiiIsZero}}\label{xintiiIsZero} -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|. +|\xintiiIsZero|\n\etype{f} returns 1 if |N=0|, 0 otherwise. -\phantomsection\label{edefprimes} -As an example, let us construct an |\edef\z{...}| which will define |\z| to be a -list of prime numbers: -\begin{everbatim*} -\begingroup -\edef\z -{\xintiloop [10001+2] - {\xintiloop [3+2] - \ifnum\xintouteriloopindex<\numexpr\xintiloopindex*\xintiloopindex\relax - \xintouteriloopindex, - \expandafter\xintbreakiloop - \fi - \ifnum\xintouteriloopindex=\numexpr - (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax - \else - \repeat - }% no space here - \ifnum \xintiloopindex < 10999 \repeat }% -\meaning\z\endgroup -\end{everbatim*}and we should have taken -some steps to not have a trailing comma, but -the point was to show that one can do that in an |\edef|\,! See also -\autoref{ssec:primesII} which extracts from this code its way of testing -primality. +\subsection{\csbh{xintiiIsNotZero}}\label{xintiiIsNotZero} -Let us create an alignment where each row will contain all divisors of its -first entry. -Here is the output, thus obtained without any count register: -\begin{everbatim*} -\begin{multicols}2 -\tabskip1ex \normalcolor -\halign{&\hfil#\hfil\cr - \xintiloop [1+1] - {\expandafter\bfseries\xintiloopindex & - \xintiloop [1+1] - \ifnum\xintouteriloopindex=\numexpr - (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax - \xintiloopindex&\fi - \ifnum\xintiloopindex<\xintouteriloopindex\space % CRUCIAL \space HERE - \repeat \cr }% - \ifnum\xintiloopindex<30 - \repeat -} -\end{multicols} -\end{everbatim*} -We wanted this first entry in bold face, but |\bfseries| leads to -unexpandable tokens, so the |\expandafter| was necessary for |\xintiloopindex| -and |\xintouteriloopindex| not to be confronted with a hard to digest -|\endtemplate|. An alternative way of coding: -% -\begin{everbatim} -\tabskip1ex -\def\firstofone #1{#1}% -\halign{&\hfil#\hfil\cr - \xintiloop [1+1] - {\bfseries\xintiloopindex\firstofone{&}% - \xintiloop [1+1] \ifnum\xintouteriloopindex=\numexpr - (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax - \xintiloopindex\firstofone{&}\fi - \ifnum\xintiloopindex<\xintouteriloopindex\space % \space is CRUCIAL - \repeat \firstofone{\cr}}% - \ifnum\xintiloopindex<30 \repeat } -\end{everbatim} +|\xintiiIsNotZero|\n\etype{f} returns 1 if |N!=0|, 0 otherwise. -\begin{framed} - The next utilities are not compatible with expansion-only context. -\end{framed} +\subsection{\csbh{xintiiIsOne}}\label{xintiiIsOne} -\subsection{\csbh{xintApplyInline}}\label{xintApplyInline} +|\xintiiIsOne|\n\etype{f} returns 1 if |N=1|, 0 otherwise. +\subsection{\csbh{xintiiOdd}}\label{xintiiOdd} -\csa{xintApplyInline}|{\macro}|\marg{list}\ntype{o{\lowast f}} works non -expandably. It applies the one-parameter |\macro| to the first element of the -expanded list (|\macro| may have itself some arguments, the list item will be -appended as last argument), and is then re-inserted in the input stream after -the tokens resulting from this first expansion of |\macro|. The next item is -then handled. +|\xintiiOdd|\n\etype{f} is 1 if the number is odd and 0 otherwise. -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. +\subsection{\csbh{xintiiEven}}\label{xintiiEven} + +|\xintiiEven|\n\etype{f} is 1 if the number is even and 0 otherwise. +\subsection{\csbh{xintiiMON}}\label{xintiiMON} + +|\xintiiMON|\n\etype{f} computes |(-1)^N|. \begin{everbatim*} -\def\Macro #1{\advance\cnta #1 , \the\cnta} -\cnta 0 -0\xintApplyInline\Macro {3141592653}. +\xintiiMON {-280914019374101929} \end{everbatim*} -The first argument |\macro| does not have to be an expandable macro. -\csa{xintApplyInline} submits its second, token list parameter to an -\hyperref[ssec:expansions]{\fexpan -sion}. Then, each \emph{unbraced} item will also be \fexpan ded. This provides -an easy way to insert one list inside another. \emph{Braced} items are not -expanded. Spaces in-between items are gobbled (as well as those at the start -or the end of the list), but not the spaces \emph{inside} the braced items. +\subsection{\csbh{xintiiMMON}}\label{xintiiMMON} -\csa{xintApplyInline}, despite being non-expandable, does survive to -contexts where the executed |\macro| closes groups, as happens inside -alignments with the tabulation character |&|. -This tabular provides an example:\par +|\xintiiMMON|\n\etype{f} computes |(-1)^{N-1}|. \begin{everbatim*} -\centerline{\normalcolor\begin{tabular}{ccc} - $N$ & $N^2$ & $N^3$ \\ \hline - \def\Row #1{ #1 & \xintiiSqr {#1} & \xintiiPow {#1}{3} \\ \hline }% - \xintApplyInline \Row {\xintCSVtoList{17,28,39,50,61}} -\end{tabular}}\medskip +\xintiiMMON {280914019374101929} \end{everbatim*} -We see that despite the fact that the first encountered tabulation character in -the first row close a group and thus erases |\Row| from \TeX's memory, -|\xintApplyInline| knows how to deal with this. +\subsection{\csbh{xintiiifSgn}}\label{xintiiifSgn} -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). +\csbh{xintiiifSgn}\marg{N}\marg{A}\marg{B}\marg{C}\etype{fnnn} executes either +the \meta{A}, \meta{B} or \meta{C} code, depending on its first argument being +respectively negative, zero, or positive. -One may nest various |\xintApplyInline|'s. For example (see the -\hyperref[float]{table} \vpageref{float}):\par -\begin{everbatim*} -\begin{figure*}[ht!] - \centering\phantomsection\label{float} - \def\Row #1{#1:\xintApplyInline {\Item {#1}}{0123456789}\\ }% - \def\Item #1#2{&\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*} -\end{everbatim*} +\subsection{\csbh{xintiiifZero}}\label{xintiiifZero} -One could not move the definition of |\Item| inside the tabular, -as it would get lost after the first |&|. But this -works: -\everb|@ -\begin{tabular}{ccccccccccc} - &0&1&2&3&4&5&6&7&8&9\\ \hline - \def\Row #1{#1:\xintApplyInline {&\xintiPow {#1}}{0123456789}\\ }% - \xintApplyInline \Row {0123456789} -\end{tabular} -| +\csa{xintiiifZero}\marg{N}\marg{IsZero}\marg{IsNotZero}\etype{fnn} expandably +checks if the first mandatory argument |N| (a number, possibly a fraction if +\xintfracname is loaded, or a macro expanding to one such) is zero or not. It +then either executes the first or the second branch. -A limitation is that, contrarily to what one may have expected, the -|\macro| for an |\xintApplyInline| can not be used to define -the |\macro| for a nested sub-|\xintApplyInline|. For example, -this does not work:\par -\everb|@ - \def\Row #1{#1:\def\Item ##1{&\xintiPow {#1}{##1}}% - \xintApplyInline \Item {0123456789}\\ }% - \xintApplyInline \Row {0123456789} % does not work -| -\noindent But see \csbxint{For}. +Beware that both branches must be present. -\subsection{\csbh{xintFor}, \csbh{xintFor*}}\label{xintFor}\label{xintFor*} +\subsection{\csbh{xintiiifNotZero}}\label{xintiiifNotZero} -\csbxint{For}\ntype{on} is a new kind of for loop.\footnote{first introduced - with \xintname |1.09c| of |2013/10/09|.} Rather than using macros -for encapsulating list items, its behavior is like a macro with parameters: -|#1|, |#2|, \dots, |#9| are used to represent the items for up to nine levels of -nested loops. Here is an example: -% -\everb|@ -\xintFor #9 in {1,2,3} \do {% - \xintFor #1 in {4,5,6} \do {% - \xintFor #3 in {7,8,9} \do {% - \xintFor #2 in {10,11,12} \do {% - $$#9\times#1\times#3\times#2=\xintiiPrd{{#1}{#2}{#3}{#9}}$$}}}} -| -\noindent This example illustrates that one does not have to use |#1| as the -first one: -the order is arbitrary. But each level of nesting should have its specific macro -parameter. Nine levels of nesting is presumably overkill, but I did not know -where it was reasonable to stop. |\par| tokens are accepted in both the comma -separated list and the replacement text. +\csa{xintiiifNotZero}\marg{N}\marg{IsNotZero}\marg{IsZero}\etype{fnn} +expandably checks if the first mandatory argument |N| is not +zero or is zero. It then either executes the first or the second branch. -\begin{framed} - \TeX nical notes: +Beware that both branches must be present. -\begin{itemize} - \item The |#1| is replaced in the iterated-over text exactly as in general - \TeX\ macros or \LaTeX\ commands. This spares the user quite a few - |\expandafter|'s or other tricks needed with loops which have the - values encapsulated in macros, like \LaTeX's |\@for| and |\@tfor|. +\subsection{\csbh{xintiiifOne}}\label{xintiiifOne} - \item \csa{xintFor} (and \csa{xintFor*}) isn't purely expandable: one can - not use it inside an |\edef|. But it may be used, as will be shown in - examples, in some contexts such as \LaTeX's |tabular| which are usually - hostile to non-expandable loops. - - \item \csa{xintFor} (and \csa{xintFor*}) does some assignments prior to - executing each iteration of the replacement text, but it acts purely - expandably after the last iteration, hence if for example the replacement - text ends with a |\\|, the loop can be used insided a tabular and be - followed by a |\hline| without creating the dreaded ``|Misplaced - \noalign|'' error. +\csa{xintiiifOne}\marg{N}\marg{IsOne}\marg{IsNotOne}\etype{fnn} expandably +checks if the first mandatory argument |N| is one or not one. It +then either executes the first or the second branch. Beware that both branches +must be present. - \item It does not create groups. +\subsection{\csbh{xintiiifCmp}}\label{xintiiifCmp} - \item It makes no global assignments. +\csa{xintiiifCmp}\marg{A}\marg{B}\marg{AB}\etype{ffnnn} +compares its first two arguments and chooses accordingly the correct branch. - \item The iterated replacement text may close a group which was opened even - before the start of the loop (typical example being with |&| in - alignments). -\begin{everbatim*} -\begin{tabular}{rccccc} - \hline - \xintFor #1 in {A, B, C} \do {% - #1:\xintFor #2 in {a, b, c, d, e} \do {&($ #2 \to #1 $)}\\ }% - \hline -\end{tabular} -\end{everbatim*} - - \item There is no facility provided which would give access to a count of - the number of iterations as it is technically not easy to do so it in a - way working with nested loops while maintaining the ``expandable after - done'' property; something in the spirit of \csbxint{iloopindex} is - possible but this approach would bring its own limitations and - complications. Hence the user is invited to update her own count or - \LaTeX{} counter or macro at each iteration, if needed. +\subsection{\csbh{xintiiifEq}}\label{xintiiifEq} - \item A |\macro| whose definition uses internally an \csbxint{For} loop - may be used inside another \csbxint{For} loop even if the two loops both - use the same macro parameter. The loop definition inside |\macro| - must use |##| as is the general rule for definitions done inside macros. +\csa{xintiiifEq}\marg{A}\marg{B}\marg{A=B}\marg{not(A=B)}\etype{ffnn} checks +equality of its two first arguments and executes the corresponding branch. - \item \csbxint{For} is for comma separated values and \csbxint{For*} for - lists of braced items; their respective expansion policies differ. They - are described later. -\end{itemize} -\unskip -\end{framed} +\subsection{\csbh{xintiiifGt}}\label{xintiiifGt} -\noindent Regarding \csbxint{For}: -\begin{itemize}[nosep, listparindent=\leftmarginiii] -\item the spaces between the various declarative elements are all optional, -\item in the list of comma separated values, spaces around the commas or at - the start and end are ignored, -\item if an item must contain itself its own commas, then it should - be braced, and the braces will be removed before feeding the iterated-over - text, -\item the list may be a macro, it is expanded only once, -\item items are not pre-expanded. The first item should be braced or start - with a space if the list is explicit and the item should not be - pre-expanded, -\item empty items give empty |#1|'s in the replacement text, they are not - skipped, -\item an empty list executes once the replacement text with an empty parameter - value, -\item the list, if not a macro, \fbox{must be braced.} -\end{itemize} +\csa{xintiiifGt}\marg{A}\marg{B}\marg{A>B}\marg{not(A>B)}\etype{ffnn} +checks if $A>B$ and executes the corresponding branch. -\noindent Regarding \csbxint{For*}:\ntype{{\lowast f}n} -\begin{itemize}[nosep, listparindent=\leftmarginiii] -\item it handles lists of braced items (or naked tokens), -\item it \hyperref[ssec:expansions]{\fexpan ds} the list, -\item and more generally it \hyperref[ssec:expansions]{\fexpan ds} each naked - token encountered - before assigning the |#1| values (gobbling spaces in the process); - this - makes it easy to simulate concatenation of multiple lists|\x|, |\y|: - if |\x| expands to |{1}{2}{3}| and |\y| expands to |{4}{5}{6}| then |{\x\y}| - as argument to |\xintFor*| has the same effect as |{{1}{2}{3}{4}{5}{6}}|. +\subsection{\csbh{xintiiifLt}}\label{xintiiifLt} - For a further illustration see the use of |\xintFor*| at the end of - \autoref{ssec:fibonacci}. -\item spaces at the start, end, or in-between items are gobbled (but naturally - not the spaces inside \emph{braced} items), -\item except if the list argument is a macro (with no parameters), \fbox{it - must be braced.}, -\item an empty list leads to an empty result. -\end{itemize} +\csa{xintiiifLt}\marg{A}\marg{B}\marg{A0| and |M^2-d=N| with +|M| the smallest (hence if |N=k^2| is a perfect square then |M=k+1|, |d=2k+1|). -The iterated macros as well as the list items are allowed to contain explicit -|\par| tokens. +\begin{everbatim*} +\xintAssign\xintiiSquareRoot {17000000000000000000000000}\to\A\B +\xintiiSub{\xintiiSqr\A}\B=\A\string^2-\B +\end{everbatim*} +A rational approximation to $\sqrt{|N|}$ is $|M|-\frac{|d|}{|2M|}$ which is a +majorant and the error is at most |1/2M| (if |N| is a perfect square |k^2| +this gives |k+1/(2k+2)|, not |k|.) -\subsection{\csbh{xintifForFirst}, \csbh{xintifForLast}} -\label{xintifForFirst}\label{xintifForLast} +Package \xintfracname has \csbxint{FloatSqrt} for square roots of floating +point numbers. -\csbxint{ifForFirst}\,\texttt{\{YES branch\}\{NO branch\}}\etype{nn} - and \csbxint{ifForLast}\,\texttt{\{YES - branch\}\hskip 0pt plus 0.2em \{NO branch\}}\etype{nn} execute the |YES| or -|NO| branch -if the -\csbxint{For} -or \csbxint{For*} loop is currently in its first, respectively last, iteration. +\subsection{\csbh{xintiiSqrt}, \csbh{xintiiSqrtR}} +\label{xintiiSqrt}\label{xintiiSqrtR} -Designed to work as expected under nesting (but see frame next.) Don't forget -an empty brace pair |{}| if a branch is to do nothing. May be used multiple -times in the replacement text of the loop. +\noindent|\xintiiSqrt|\n\ computes the largest integer whose square +is at most equal to |N|.\etype{f} |\xintiiSqrtR| +produces the rounded, not truncated, square root.\etype{f} +\begin{everbatim*} +\begin{itemize}[nosep] +\item \xintiiSqrt {3000000000000000000000000000000000000} +\item \xintiiSqrtR {3000000000000000000000000000000000000} +\item \xintiiSqrt {\xintiiE {3}{100}} +\end{itemize} +\end{everbatim*} -\begin{framed} - \noindent Pay attention to these implementation features: - \begin{itemize}[nosep, listparindent=\leftmarginiii] - \item \emph{if an inner \csbxint{For} loop is positioned before the - \csb{xintifForFirst} or \csb{xintifForLast} of the outer loop it will - contaminate their settings. This applies also naturally if the inner loop - arises from the expansion of some macro located before the outer - conditionals.} +\subsection{\csbh{xintiiBinomial}}\label{xintiiBinomial} - One fix is to make sure that the outer conditionals are expanded before the - inner loop is executed, e.g. this will be the case if the inner loop is - located inside one of the branches of the conditional. +|\xintiiBinomial{x}{y}|\etype{\numx\numx} computes binomial coefficients. - Another approach is to enclose, if feasible, the inner loop in a group of - its own. - \item \emph{if the replacement text closes a group (e.g. from a |&| inside an - alignment), the conditionals will lose their ascribed meanings and end up - possibly undefined, depending whether there is some outer loop whose - execution started before the opening of the group.} +If |x<0| an out-of-range error is raised. Else, if |y<0| or if |xx|, with a positive |x|.) - The fix is to arrange things so that the conditionals are expanded - before \TeX\ encounters the closing-group token. - \end{itemize} -\end{framed} +%\begin{framed} + The allowable range is $0\leqslant x\leqslant99999999$. +%\end{framed} + % Thus the maximal computable value is ${9999 \choose 5000}$ which turns out + % to have \dtt{3008} digits. + But this theoretical range includes binomial coefficients with more than the + roughly 19950 digits that the arithmetics of \xintname can handle. In such + cases, the computation will end up in a low-level \TeX{} error after a + long time. -\subsection{ \csbh{xintBreakFor}, \csbh{xintBreakForAndDo}} -\label{xintBreakFor}\label{xintBreakForAndDo} +% +It turns out that ${65000 \choose 32500}$ has \dtt{19565} digits and +${64000 \choose 32000}$ has \dtt{19264} digits. The latter can be evaluated +(this takes a long long time) but presumably not the former (I didn't try). +Reasonable feasible evaluations are with binomial coefficients not exceeding +about one thousand digits. -One may immediately terminate an \csbxint{For} or \csbxint{For*} loop with -\csbxint{BreakFor}. -\begin{framed} - As it acts by clearing up all the rest of the replacement text when - encountered, it will not work from inside some |\if...\fi| without - suitable |\expandafter| or swapping technique. +% +The |binomial| function is available in the \xintexprname parsers. +\begin{everbatim*} +\xinttheiiexpr seq(binomial(100,i), i=47..53)\relax +\end{everbatim*} - Also it can't be used from inside braces as from there it can't see the end - of the replacement text. -\end{framed} +See \csbxint{FloatBinomial} from package \xintfracname for the float variant, +used in \csbxint{floatexpr}. -There is also \csbxint{BreakForAndDo}. Both are illustrated by various examples -in the next section which is devoted to ``forever'' loops. -\subsection{\csbh{xintintegers}, \csbh{xintdimensions}, \csbh{xintrationals}} -\label{xintegers}\label{xintintegers} -\label{xintdimensions}\label{xintrationals} +In order to +evaluate binomial coefficients ${x \choose y}$ with $x>99999999$, or even +$x\geqslant 2^{31}$, but $y$ is not too large, one may use an ad hoc function +definition such as: +\begin{everbatim*} +\xintdeffunc mybigbinomial(x,y):=`*`(x-y+1..[1]..x)//y!;% +% without [1], x would have been limited to < 2^31 +\printnumber{\xinttheexpr mybigbinomial(98765432109876543210,10)\relax} +\end{everbatim*} -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 macros -in \LaTeX{} (the stretch and shrink components will be discarded). The |#1| -will be |\dimexpr sp\relax|, from which one can get the -litteral (approximate) representation in points via |\the#1|. So |#1| can be -used anywhere \TeX{} expects a dimension (and there is no need in conditionals -to insert a |\relax|, and one should \emph{not} do it), and to print its value -one uses \fbox{\csa{the\#1}}. The chosen representation guarantees exact -incrementation with no rounding errors accumulating from converting into -points at each step. +To get this functionality in macro form, one can do: +\begin{everbatim*} +\xintNewIIExpr\MyBigBinomial [2]{`*`(#1-#2+1..[1]..#1)//#2!} +\printnumber{\MyBigBinomial {98765432109876543210}{10}} +\end{everbatim*} +As we used \csa{xintNewIIExpr}, this macro will only accept strict integers. +Had we used \csa{xintNewExpr} the |\MyBigBinomial| would have accepted general +fractions or decimal numbers, and computed the product at the numerator +without truncating them to integers; but the factorial at the denominator +would truncate its argument. +\subsection{\csbh{xintiiPFactorial}}\label{xintiiPFactorial} +|\xintiiPFactorial{a}{b}|\etype{\numx\numx} computes the partial factorial +|(a+1)(a+2)...b|. For |a=b| the product is considered empty hence returns |1|. +%\begin{framed} + The allowed range with |1.2f| was $0\leqslant a \leqslant b\leqslant99999999$. + It was a bit unfortunate with + |1.2f| that the code deliberately raised an error if this condition + was not obeyed by the arguments. + + Starting with |1.2h|, $-100000000\leqslant a, b\leqslant99999999$ is + accepted. + The + rule is to interpret the formula as the product of the + $j$'s such that $ab$ or negative arguments, the definitive rules have not yet + been fixed. -If the list argument to \csbxint{For} (or \csbxint{For*}) is \csbxint{rationals} -or more generally -\csbxint{rationals}|[||start|\allowbreak|+|\allowbreak|delta||]| (\emph{within - braces}!), then \csbxint{For} does an infinite iteration where |#1| (or |#2|, -\dots, |#9|) will run through the arithmetic sequence of \xintfracname fractions -with initial value |start| and increment |delta| (default values: |start=1/1|, -|delta=1/1|). This loop works \emph{only with \xintfracname loaded}. if the -optional argument is present it must contain both of them, and they may be given -in any of the formats recognized by \xintfracname (fractions, decimal -numbers, numbers in scientific notations, numerators and denominators in -scientific notation, etc...) , or as macros or count registers (if they are -short integers). The |#1| (or |#2|, \dots, |#9|) will be an |a/b| fraction -(without a |[n]| part), where -the denominator |b| is the product of the denominators of -|start| and |delta| (for reasons of speed |#1| is not reduced to irreducible -form, and for another reason explained later |start| and |delta| are not put -either into irreducible form; the input may use explicitely \csa{xintIrr} to -achieve that). \begin{everbatim*} -\begingroup\small -\noindent\parbox{\dimexpr\linewidth-3em}{\color[named]{OrangeRed}% -\xintFor #1 in {\xintrationals [10/21+1/21]} \do -{#1=\xintifInt {#1} - {\textcolor{blue}{\xintTrunc{10}{#1}}} - {\xintTrunc{10}{#1}}% display in blue if an integer - \xintifGt {#1}{1.123}{\xintBreakFor}{, }% - }} -\endgroup\smallskip +\xintiiPFactorial {100}{130} \end{everbatim*} +%\end{framed} -\smallskip The example above confirms that computations are done exactly, and -illustrates that the two initial (reduced) denominators are not multiplied when -they are found to be equal. It is thus recommended to input |start| and |delta| -with a common smallest possible denominator, or as fixed point numbers with the -same numbers of digits after the decimal mark; and this is also the reason why -|start| and |delta| are not by default made irreducible. As internally the -computations are done with numerators and denominators completely expanded, one -should be careful not to input numbers in scientific notation with exponents in -the hundreds, as they will get converted into as many zeroes. +This theoretical range allows computations whose result values would have more +than the roughly 19950 digits that the arithmetics of \xintname can handle. In +such cases, the computation will end up in a low-level \TeX{} error after a +long time. +The |pfactorial| function is available in the \xintexprname parsers. \begin{everbatim*} -\noindent\parbox{\dimexpr.7\linewidth}{\raggedright -\xintFor #1 in {\xintrationals [0.000+0.125]} \do -{\edef\tmp{\xintTrunc{3}{#1}}% - \xintifInt {#1} - {\textcolor{blue}{\tmp}} - {\tmp}% - \xintifGt {#1}{2}{\xintBreakFor}{, }% - }}\smallskip +\xinttheiiexpr pfactorial(100,130)\relax \end{everbatim*} -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 - +See \csbxint{FloatPFactorial} from package \xintfracname for the float +variant, used in \csbxint{floatexpr}. -\subsection{\csbh{xintForpair}, \csbh{xintForthree}, \csbh{xintForfour}}\label{xintForpair}\label{xintForthree}\label{xintForfour} -The syntax\ntype{on} is illustrated in this -example. The notation is the usual one for |n|-uples, with parentheses and -commas. Spaces around commas and parentheses are ignored. -% +In case values are needed with $b>99999999$, or even $b\geqslant 2^{31}$, but +$b-a$ is not too large, one may use an ad hoc function definition such as: \begin{everbatim*} -{\centering\begin{tabular}{cccc} - \xintForpair #1#2 in { ( A , a ) , ( B , b ) , ( C , c ) } \do {% - \xintForpair #3#4 in { ( X , x ) , ( Y , y ) , ( Z , z ) } \do {% - $\Biggl($\begin{tabular}{cc} - -#1- & -#3-\\ - -#4- & -#2-\\ - \end{tabular}$\Biggr)$&}\\\noalign{\vskip1\jot}}% -\end{tabular}\\} +\xintdeffunc mybigpfac(a,b):=`*`(a+1..[1]..b);% +% without [1], b would have been limited to < 2^31 +\printnumber{\xinttheexpr mybigpfac(98765432100,98765432120)\relax} \end{everbatim*} -\csbxint{Forpair} must be followed by either |#1#2|, |#2#3|, |#3#4|, \dots, or -|#8#9| with |#1| usable as an alias for |#1#2|, |#2| as alias for |#2#3|, -etc \dots\ and similarly for \csbxint{Forthree} (using |#1#2#3| or simply -|#1|, |#2#3#4| or simply |#2|, \dots) and \csbxint{Forfour} (with |#1#2#3#4| -etc\dots). +\subsection{\csbh{xintiiMax}}\label{xintiiMax} -Nesting works as long as the macro parameters are distinct among |#1|, |#2|, -..., |#9|. A macro which expands to an \csa{xintFor} or a -\csa{xintFor(pair,three,four)} can be used in another one with no constraint -about using distinct macro parameters. +|\xintiiMax|\n\m\etype{ff} returns the largest of the two in the sense +of the order structure on the relative integers (\emph{i.e.} the right-most +number if they are put on a line with positive numbers on the right): +|\xintiiMax {-5}{-6}|\dtt{=\xintiiMax{-5}{-6}}. -|\par| tokens are accepted in both the comma separated list and the -replacement text. +\subsection{\csbh{xintiiMin}}\label{xintiiMin} +|\xintiiMin|\n\m\etype{ff} returns the smallest of the two in the sense of the +order structure on the relative integers (\emph{i.e.} the left-most number if +they are put on a line with positive numbers on the right): |\xintiiMin +{-5}{-6}|\dtt{=\xintiiMin{-5}{-6}}. -\subsection{\csbh{xintAssign}}\label{xintAssign} +\subsection{\csbh{xintiiMaxof}}\label{xintiiMaxof} -\csa{xintAssign}\meta{braced things}\csa{to}% -\meta{as many cs as they are things} %\ntype{{(f$\to$\lowast [x)}{\lowast N}} -% -defines (without checking if something gets overwritten) the control sequences -on the right of \csa{to} to expand to the successive tokens or braced items -located to the left of \csa{to}. \csa{xintAssign} is not an expandable macro. +\csa{xintiiMaxof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns the +maximum. The list argument may be a macro, it is \fexpan ded first. -\fexpan sion is first applied to the material in front of \csa{xintAssign} -which is fetched as one argument if it is braced. Then the expansion of this -argument is examined and successive items are assigned to the macros following -|\to|. There must be exactly as many macros as items. No check is done. The -macro assignments are done with removal of one level of brace pairs from each -item. +\subsection{\csbh{xintiiMinof}}\label{xintiiMinof} -After the initial \fexpan sion, each assigned (brace-stripped) item will be -expanded according to the setting of the optional parameter. +\csa{xintiiMinof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns the +minimum. The list argument may be a macro, it is \fexpan ded first. -For example |\xintAssign [e]...| means that all assignments are done using -|\edef|. With |[f]| the assignments will be made using -\hyperref[fdef]{\ttfamily\char92fdef}. The default is simply to make the -definitions with |\def|, corresponding to an empty optional paramter |[]|. -Possibilities for the optional parameter are: |[], [g], [e], [x], [o], [go], -[oo], [goo], [f], [gf]|. For example |[oo]| means a double expansion. -\begin{everbatim*} -\xintAssign \xintiiDivision{1000000000000}{133333333}\to\Q\R -\meaning\Q\newline -\meaning\R\newline -\xintAssign {{\xintiiDivision{1000000000000}{133333333}}}\to\X -\meaning\X\newline -\xintAssign [oo]{{\xintiiDivision{1000000000000}{133333333}}}\to\X -\meaning\X\newline -\xintAssign \xintiiPow{7}{13}\to\SevenToThePowerThirteen -\meaning\SevenToThePowerThirteen\par -\end{everbatim*} +\subsection{\csbh{xintifTrueAelseB}} +\label{xintifTrueAelseB} -Two special cases: -\begin{itemize}[nosep] -\item if after this initial expansion no brace is found immediately after - \csa{xintAssign}, it is assumed that there is only one control sequence - following |\to|, and this control sequence is then defined via |\def| (or - what is set-up by the optional parameter) to expand to the material between - \csa{xintAssign} and \csa{to}. -\item if the material between \csa{xintAssign} and |\to| is enclosed in two - brace pairs, the first brace pair is removed, then the \fexpan sion is - immediately stopped by the inner brace pair, hence \csa{xintAssign} now - finds a unique item and thus defines only a single macro to be this item, - which is now stripped of the second pair of braces. -\end{itemize} +\csa{xintifTrueAelseB}\marg{f}\marg{true branch}\marg{false branch}\etype{fnn} +is a synonym for \csbxint{iiifNotZero}. +{\small + \noindent |\xintiiifnotzero| is lowercase companion macro.\par } + +Note 1: as it does only \fexpan sion on its argument it fails with inputs such +as |--0|. But with \xintfracname loaded, it does work fine if nested with +other \xintfracname macros, because the output format of such macros is fine +as input to \csbxint{iiifNotZero}. This remark applies to all other «Boolean +logic» macros next. + +Note 2: prior to |1.2o| this macro was using \csbxint{ifNotZero} which applies +\csbxint{Num} to its argument (or gets redefined by \xintfracname to handle +general decimal numbers or fractions).\CHANGED{1.2o} Hence it would have +worked with input such as |--0|. But it was decided at |1.2o| that the +overhead was not worth it. The same remark applies to the other «Boolean +logic» type macros next. + +\subsection{\csbh{xintifFalseAelseB}} +\label{xintifFalseAelseB} -\emph{Note:} prior to release |1.09j|, |\xintAssign| did an |\edef| by default -for each item assignment but it now does |\def| corresponding to no or empty -optional parameter. +\csa{xintifFalseAelseB}\marg{f}\marg{false branch}\marg{true + branch}\etype{fnn} is a synonym for \csbxint{iiifZero}. -It is allowed for the successive braced items to be separated by spaces. They -are removed during the assignments. But if a single macro is defined (which -happens if the argument after \fexpan sion does not start with a brace), -naturally the scooped up material has all intervening spaces, as it is -considered a -single item. But an upfront initial space will have been absorbed by \fexpan -sion. -\begin{everbatim*} -\def\X{ {a} {b} {c} {d} }\def\Y { u {a} {b} {c} {d} } -\xintAssign\X\to\A\B\C\D -\xintAssign\Y\to\Z -\meaning\A, \meaning\B, \meaning\C, \meaning\D+++\newline -\meaning\Z+++\par -\end{everbatim*} -As usual successive space characters in input make for a single \TeX\ space token. +{\small + \noindent |\xintiiifzero| is lowercase companion macro.\par } +\subsection{\csbh{xintNOT}}\label{xintNOT} -\subsection{\csbh{xintAssignArray}}\label{xintAssignArray} +\csa{xintNOT}\etype{f} is a synonym for \csa{xintiiIsZero}. -\xintAssignArray \xintBezout {1000}{113}\to\Bez +{\small |\xintiiiszero| serves as lowercase companion macro.\par} -\csa{xintAssignArray}\meta{braced - things}\csa{to}\csa{myArray} %\ntype{{(f$\to$\lowast x)}N} -% -first expands fully what comes immediately after |\xintAssignArray| and -expects to find a list of braced things |{A}{B}...| (or tokens). It then -defines \csa{myArray} as a macro with one parameter, such that \csa{myArray\x} -expands to give the |x|th braced thing of this original -list (the argument \texttt{\x} itself is fed to a |\numexpr| by |\myArray|, -and |\myArray| expands in two steps to its output). With |0| as parameter, -\csa{myArray}|{0}| returns the number |M| of elements of the array so that the -successive elements are \csa{myArray}|{1}|, \dots, \csa{myArray}|{M}|. -% -\leftedline{|\xintAssignArray \xintBezout {1000}{113}\to\Bez|} will set -|\Bez{0}| to \dtt{\Bez0}, |\Bez{1}| to \dtt{\Bez1}, |\Bez{2}| to -\dtt{\Bez2}, |\Bez{3}| to \dtt{\Bez3}, |\Bez{4}| to -\dtt{\Bez4}, and |\Bez{5}| to \dtt{\Bez5}: -\dtt{(\Bez3)${}\times{}$\Bez1${}-{}$(\Bez4)${}\times{}$\Bez2${}={}$\Bez5.} -This macro is incompatible with expansion-only contexts. - -\csa{xintAssignArray} admits an optional parameter, for example -|\xintAssignArray [e]| means that the definitions of the macros will be made -with |\edef|. The empty optional parameter (default) means that definitions -are done with |\def|. Other possibilities: |[], [o], [oo], [f]|. Contrarily to -\csbxint{Assign} one can not use the |g| here to make the definitions global. -For this, one should rather do |\xintAssignArray| within a group starting with -|\globaldefs 1|. - - -\subsection{\csbh{xintDigitsOf}}\label{xintDigitsOf} - -This is a synonym for \csbxint{AssignArray},\ntype{fN} to be used to define -an array giving all the digits of a given (positive, else the minus sign will -be treated as first item) number. -\begingroup\xintDigitsOf\xintiPow {7}{500}\to\digits -% -\leftedline{|\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 +Its former name was \csa{xintNot} which is now deprecated and will be removed +at some future release. -\subsection{\csbh{xintRelaxArray}}\label{xintRelaxArray} +\subsection{\csbh{xintAND}}\label{xintAND} -\csa{xintRelaxArray}\csa{myArray} %\ntype{N} -% -(globally) sets to \csa{relax} all macros which were defined by the previous -\csa{xintAssignArray} with \csa{myArray} as array macro. +|\xintAND{f}{g}|\etype{ff} returns \dtt{1} if |f!=0| and |g!=0| and \dtt{0} +otherwise. +\subsection{\csbh{xintOR}}\label{xintOR} +|\xintOR{f}{g}|\etype{ff} returns \dtt{1} if |f!=0| or |g!=0| and \dtt{0} +otherwise. -\clearpage -\section{Macros of the \xintcorename package} -\label{sec:core} +\subsection{\csbh{xintXOR}}\label{xintXOR} -\localtableofcontents +|\xintXOR{f}{g}|\etype{ff} returns \dtt{1} if exactly one of |f| or |g| +is true (i.e. non-zero), else \dtt{0}. -Prior to release |1.1| the macros which are now included in the separate -package \xintcorename were part of \xintname. Package \xintcorename is -automatically loaded by \xintname.\IMPORTANT\ - -\xintcorename provides the five basic arithmetic operations on big integers: -addition, subtraction, multiplication, division and powers. Division may be -either rounded (\csbxint{iiDivRound}) (the rounding of |0.5| is |1| and the -one of |-0.5| is |-1|) or Euclidean (\csbxint{iiQuo}) (which for positive -operands is the same as truncated division), or truncated (\csbxint{iiDivTrunc}). - -In the description of the macros the \texttt{\n} and \texttt{\m} symbols stand -for explicit (big) integers within braces or more generally any control -sequence (possibly within braces) \hyperref[ssec:expansions]{\fexpan ding} to -such a big integer. - -The macros with a single |i| in their names parse their arguments -automatically through \hyperref[xintiNum]{\string\xintNum}. This type of -expansion applied to an argument is signaled by a -\textcolor[named]{PineGreen}{\Numf} in the margin. The accepted input format -is then a sequence of plus and minus signs, followed by some string of zeroes, -followed by digits. - -If \xintfracname additionally to \xintcorename is loaded, \csbxint{Num} -becomes a synonym to \csbxint{TTrunc}; this means that -arbitrary fractions will be accepted as arguments of the -macros with a single |i| in their names, but get truncated to integers before -further processing. The format of the output will be as with only \xintname -loaded. The only extension is in allowing a wider variety of inputs. - -The macros with |ii| in their names have arguments which will only be \fexpan -ded, but will not be parsed via \hyperref[xintiNum]{\string\xintNum}. -Arguments of this type are signaled by the margin annotation -\textcolor[named]{PineGreen}{\emph{f}}. For such big integers only one minus -sign and no plus sign, nor leading zeros, are accepted. |-0| is not valid in -this strict input format. Loading \xintfracname does not bring any -modification to these macros whether for input or output. +\subsection{\csbh{xintANDof}}\label{xintANDof} -The letter \texttt{x} (with margin annotation -\textcolor[named]{PineGreen}{\numx}) 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... +\csa{xintANDof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns \dtt{1} if +all are true (i.e. non zero) and \dtt{0} otherwise. The list argument may be a +macro, it (or rather its first token) is \fexpan ded first to deliver its +items. -For the rules regarding direct use of count registers or \csa{numexpr} -expression, in the arguments to the package macros, see the -\autoref{sec:useofcount} section. +\subsection{\csbh{xintORof}}\label{xintORof} -\begin{framed} - The macros \csbxint{iAdd}, \csbxint{iMul}, \dots, respectively - \csbxint{iiAdd}, \csbxint{iiMul}, \dots from \xintcorename are guaranteed to - always output an integer without a trailing |/B| or |[N]|. The |ii| macros - have the lesser overhead; the |i| macros can be used (if \xintfracname is - loaded), with fractions, as they will truncate their arguments to integers. - But their output format remains unmodified: integers with no fraction slash - nor |[N]|. -\end{framed} +\csa{xintORof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns \dtt{1} if at +least one is true (i.e. does not vanish), else it produces \dtt{0}. The list +argument may be a macro, it is \fexpan ded first. -The {\color[named]{PineGreen}$\star$}'s in the margin are there to remind of -the complete expandability, even \fexpan dability of the macros, as discussed -in \autoref{ssec:expansions}. +\subsection{\csbh{xintXORof}}\label{xintXORof} +\csa{xintXORof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast f} returns \dtt{1} if an +odd number of them are true (i.e. do not vanish), else it produces \dtt{0}. +The list argument may be a macro, it is \fexpan ded first. -\subsection{\csbh{xintNum}, \csbh{xintiNum}}\label{xintiNum} +\subsection{\csbh{xintLen}}\label{xintLen} -|\xintNum|\n\etype{f} removes chains of plus or minus signs, followed by -zeroes. % -% -\leftedline{|\xintNum{+---++----+--000000000367941789479}|\dtt - {=\xintNum{+---++----+--000000000367941789479}}} +|\xintLen|\etype{\Numf} is originally an alias for \csbxint{iLen}. But with +\xintfracname loaded its meaning is \hyperref[xintLenFrac]{modified} to accept +more general inputs. + +\subsection{Deprecated macros (they require \xintfracname)}\label{ssec:xintdeprecated} + +These macros get their definitive definitions only from loading \xintfracname. +With only \xintname loaded they raise an error message (but then +operate as in former releases.) They will get removed +from \xintname at some future release:\DEPRECATED{1.2o} +|\xintEq|, +|\xintNeq|, +|\xintGeq|, +|\xintGt|, +|\xintLt|, +|\xintGtorEq|, +|\xintLtorEq|, +|\xintIsZero|, +|\xintIsNotZero|, +|\xintIsOne|, +|\xintOdd|, +|\xintEven|, +|\xintifSgn|, +|\xintifCmp|, +|\xintifEq|, +|\xintifGt|, +|\xintifLt|, +|\xintifZero|, +|\xintifNotZero|, +|\xintifOne|, +|\xintifOdd|. + +With the exception of |\xintNeq| which is renamed to |\xintNotEq|, the above +listed macros belong to \xintfracname, which extends their scope to handle +decimal numbers and fractions (|\xintOdd|, |\xintEven|, |\xintifOdd| will test +the argument after truncation to an integer.) Thus loading \xintfracname +overrides the \xintname deprecations. + +\subsection{Deprecated macros using \csbh{xintNum}}\label{ssec:xintdeprecatedNum} + +These macros filter their arguments via \csbxint{Num}. They are deprecated and +will be removed at some future release:\DEPRECATED{1.2o} +|\xintMON|, +|\xintMMON|, +|\xintiMax|, +|\xintiMin|, +|\xintiMaxof|, +|\xintiMinof|, +|\xintiSquareRoot|, +|\xintiSqrt|, +|\xintiSqrtR|, +|\xintiBinomial|, +|\xintiPFactorial|. -All \xintname macros with a single |i| in their names, such as \csbxint{iAdd}, -\csbxint{iMul} apply \csbxint{Num} to their arguments. +\clearpage +\section{Macros of the \xintfracname package} +\label{sec:frac} -When \xintfracname is loaded, \csbxint{Num} becomes a synonym to -\csbxint{TTrunc}. And \csbxint{iNum} preserved the original integer only -meaning. +First version of this package was in release |1.03| (|2013/04/14|) of the +\xintname bundle. -\subsection{\csbh{xintSgn}, \csbh{xintiiSgn}}\label{xintiiSgn} +\localtableofcontents -|\xintiiSgn|\n\etype{f} returns 1 if the number is positive, 0 if it is zero -and -1 if it is negative. It skips the \csbxint{Num} overhead. +\def\x{|{x}|} -\csbxint{Sgn}\etype{\Numf} is the variant using \csbxint{Num} and getting -extended by \xintfracname to fractions. -\subsection{\csbh{xintiOpp}, \csbh{xintiiOpp}}\label{xintiOpp}\label{xintiiOpp} +\xintfracname loads automatically \xintcorename and \xintname and inherits +their macro definitions. Only these two are redefined: +\hyperref[xintNumFrac]{\string\xintNum} and +\hyperref[xintLenFrac]{\string\xintLen}. As explained in \autoref{ssec:inputs} +and \autoref{ssec:outputs} the interchange format for the \xintfracname +macros, i.e. |A/B[N]|, is not understood by the |ii|-named macros of +\xintcorename/\xintname which expect the so-called strict integer format. +Hence, to use such an |ii|-macro with an output from an \xintfracname macro, +an extra \csbxint{Num} wrapper is required. But macros already defined by +\xintfracname cover most use cases hence this should be a rarely needed. -|\xintiOpp|\n\etype{\Numf} return the opposite |-N| of the number |N|. +In the macro descriptions, the variable |f|\ntype{\Ff} and the margin +indicator stand for the \xintfracname input format for integers, scientific +numbers, and fractions as described in \autoref{ssec:inputs}. -\csa{xintiiOpp} is the strict integer-only variant which skips -the \csbxint{Num} overhead.\etype{f} +As in the \hyperref[sec:xint]{xint.sty} documentation, |x|\ntype{\numx} stands +for something which internally will be handled in a \csa{numexpr}. It may thus +be an expression as understood by \csa{numexpr} but its evaluation and +intermediate steps must obey the \TeX\ bound. -Important note: an input such as |-\foo| is not legal, generally speaking, as -argument to the macros of the \xintname bundle (except, naturally in -\csbxint{expr}-essions). The reason is that the minus sign stops the \fexpan -sion done during parsing of the inputs. One must use the syntax -|\xintiiOpp{\foo}| or |\xintiOpp{\foo}| when one wants to pass |-\foo| as -argument to other macros. +The output format for most macros is the |A/B[N]| format but naturally the +float macros use the scientific notation on output. And some macros are +special, for example \csbxint{Trunc} produces decimal numbers, \csbxint{Irr} +produces an |A/B| with no |[N]|, \csbxint{iTrunc} and \csbxint{iRound} produce +integers without trailing |[N]| either, etc\dots -\subsection{\csbh{xintiAbs}, \csbh{xintiiAbs}}\label{xintiAbs}\label{xintiiAbs} +\subsection{\csbh{xintNum}}\label{xintNumFrac} -|\xintiAbs|\n\etype{\Numf} returns the absolute value of the number. +The original \csbxint{Num} \etype{\Ff} from \xintname is made a synonym to +\csbxint{TTrunc} (whose description is to be found farther in this section). -\csa{xintiiAbs} skips the \csbxint{Num} overhead.\etype{f} +Attention that for example |\xintNum{1e100000}| expands to the needed +\dtt{100001} digits... -\subsection{\csbh{xintiiFDg}}\label{xintFDg}\label{xintiiFDg} +The original \hyperref[xintiNum]{\string\xintNum} from \xintcorename which +does not understand the fraction slash or the scientific notation is still +available under the name \csbxint{iNum}. -|\xintiiFDg|\n\etype{f} returns the first digit (most significant) of the -decimal expansion. It skips the overhead of parsing via \csbxint{Num}. The -variant \csa{xintFDg}\etype{\Numf} uses |\xintNum| and gets extended by -\xintfracname. +\subsection{\csbh{xintRaw}}\label{xintRaw} -\subsection{\csbh{xintiiLDg}}\label{xintLDg}\label{xintiiLDg} +This macro `prints' the\etype{\Ff} +fraction |f| as it is received by the package after its parsing and +expansion, in a form |A/B[N]| equivalent to the internal +representation: the denominator |B| is always strictly positive and is +printed even if it has value |1|. +\begin{everbatim*} +\xintRaw{\the\numexpr 571*987\relax.123e-10/\the\numexpr-201+59\relax e-7} +\end{everbatim*} -|\xintiiLDg|\n\etype{f} returns the least significant digit. When the number -is positive, this is the same as the remainder in the euclidean division by -ten. It skips the overhead of parsing via \csbxint{Num}. Rewritten with -|1.2i|. +No simplification is done, not even of common zeroes between numerator and +denominator: +\begin{everbatim*} +\xintRaw {178000/25600000} +\end{everbatim*} -The variant \csa{xintLDg}\etype{\Numf} uses |\xintNum|. +\subsection{\csbh{xintNumerator}}\label{xintNumerator} -\subsection{\csbh{xintiAdd}, \csbh{xintiiAdd}}\label{xintiAdd}\label{xintiiAdd} +The input data\etype{\Ff} is parsed as if by \csbxint{Raw} into |A/B[N]| +format and +the macro outputs |A| if |N<=0|, or |A| extended by |N| zeroes if |N>0|. +\begin{everbatim*} +\xintNumerator {178000/25600000[17]}\newline +\xintNumerator {312.289001/20198.27}\newline +\xintNumerator {178000e-3/256e5}\newline +\xintNumerator {178.000/25600000} +\end{everbatim*} -|\xintiAdd|\n\m\etype{\Numf\Numf} computes the sum of the two (big) integers. +\subsection{\csbh{xintDenominator}}\label{xintDenominator} -\csa{xintiiAdd} skips the \csbxint{Num} overhead.\etype{ff} +The input data\etype{\Ff} is parsed as if by \csbxint{Raw} into |A/B[N]| +format and +the macro outputs |B| if |N>0|, or |B| extended by \verb+|N|+ zeroes if |N<=0|. +\begin{everbatim*} +\xintDenominator {178000/25600000[17]}\newline +\xintDenominator {312.289001/20198.27}\newline +\xintDenominator {178000e-3/256e5}\newline +\xintDenominator {178.000/25600000} +\end{everbatim*} -\subsection{\csbh{xintCmp}, \csbh{xintiiCmp}} +\subsection{\csbh{xintRawWithZeros}}\label{xintRawWithZeros} -|\xintCmp|\n\m\etype{\Numf\Numf} returns \dtt{1} if |N>M|, \dtt{0} if |N=M|, -and \dtt{-1} if |N0|, even +in cases where it turns out that |B=1|. +Use \csbxint{PRaw} on top of \csa{xintIrr} if it is needed to get rid of such a +trailing |/1|. -\subsection{\csbh{xintiMul}, \csbh{xintiiMul}}\label{xintiMul}\label{xintiiMul} +\subsection{\csbh{xintJrr}}\label{xintJrr} -|\xintiMul|\n\m\etype{\Numf\Numf} computes the product of two (big) integers. +This also puts the fraction\etype{\Ff} into its unique irreducible form: +\begin{everbatim*} +\xintJrr {178.256/256.178} +\end{everbatim*} -\csa{xintiiMul} skips the \csbxint{Num} overhead.\etype{ff} +This is (supposedly, not tested for ages) faster than \csa{xintIrr} for +fractions having some big common factor in the numerator and the denominator. +\begin{everbatim*} +\xintJrr {\xintiiPow{\xintiiFac {15}}{3}/% + \xintiiPrd{{\xintiiFac{10}}{\xintiiFac{30}}{\xintiiFac{5}}}} +\end{everbatim*} -\subsection{\csbh{xintiSqr}, \csbh{xintiiSqr}}\label{xintiSqr}\label{xintiiSqr} +But to notice the difference one would need computations with much bigger +numbers than in this example. As \csbxint{Irr}, \csa{xintJrr} does not remove +the trailing |/1| from a fraction reduced to an integer. -|\xintiSqr|\n\etype{\Numf} returns the square. +\subsection{\csbh{xintPRaw}}\label{xintPRaw} -\csa{xintiiSqr} skips the \csbxint{Num} overhead.\etype{f} +|PRaw|\etype{\Ff} stands for ``pretty raw''. It does like \csbxint{Raw} apart +from removing the |[N]| part if |N=0| and removing the |B| if |B=1|. +\begin{everbatim*} +\xintPRaw {123e10/321e10}, \xintPRaw {123e9/321e10}, \xintPRaw {\xintIrr{861/123}} +\end{everbatim*} -\subsection{\csbh{xintiPow}, \csbh{xintiiPow}}\label{xintiPow}\label{xintiiPow} +\subsection{\csbh{xintTrunc}}\label{xintTrunc} -|\xintiPow|\n\x\etype{\Numf\numx} returns |N^x|. When |x| is zero, this is 1. -If |N=0| and |x<0|, if \verb+|N|>1+ and |x<0|, an error is raised. There will -also be an error naturally if |x| exceeds the maximal \eTeX{} number -\dtt{\number"7FFFFFFF}, but the real limit for huge exponents comes from -either the computation time or the settings of some tex memory parameters. +\csa{xintTrunc}|{x}{f}|\etype{\numx\Ff} returns the integral part, a dot +(standing for the decimal mark), and +then the first |x| digits of the decimal expansion of the fraction |f|, except +when the fraction is (or evaluates to) zero, then it simply prints \dtt{0} +(with no dot). \begin{framed} - Indeed, the maximal power of $2$ which \xintname is able to compute - explicitely is |2^(2^17)=2^131072| which has \dtt{39457} digits. This - exceeds the maximal size on input for the \xintcorename multiplication, hence - any |2^N| with a higher |N| will fail. On the other hand |2^(2^16)| has - \dtt{19729} digits, thus it can be squared once to obtain |2^(2^17)| or - multiplied by anything smaller, thus all exponents up to and including |2^17| - are allowed (because the power operation works by squaring things and making - products). + The argument |x| must be non-negative, the behavior is currently undefined + when |x<0| and will provoke errors. \end{framed} -Side remark: after all it does pay to think! I almost melted my CPU trying by -dichotomy to pin-point the exact maximal allowable |N| for |\xintiiPow 2{N}| -before finally making the reasoning above. Indeed, each such computation with -|N>130000| activates the fan of my laptop and results in so warm a keyboard -that I can hardly go on working on it! And it takes about 12 minutes for each -|\xintiiPow2{N}| with such |N|'s of the order of $130000$ (a.t.t.o.w.). - -When \xintfracname is loaded the type of the second argument to \csa{xintiPow} -becomes \Numf: fractional input is accepted but will be truncated to an -integer; it still must be non-negative else the macro would produce fractions. -For the version accepting negative (but still integer) exponents see -\csbxint{Pow}. - -\csa{xintiiPow} is the variant which skips the \csbxint{Num} -overhead\etype{f\numx} for the first argument. - - -\subsection{\csbh{xintiFac}, \csbh{xintiiFac}} -\label{xintiiFac} - -|\xintiiFac|\x\etype{\numx} computes the factorial. +Except when the input is (or evaluates to) exactly zero, the output contains +exactly |x| digits after the decimal mark, thus the output may be +\dtt{0.00...0} or \dtt{-0.00...0}, indicating that the original fraction was +positive, respectively negative. \begin{framed} - The (theoretically) allowable range is $0\leqslant x\leqslant10000$. - - However the maximal possible computation depends on the values of some memory - parameters of the |tex| executable: with the current default settings of - TeXLive 2015, the maximal computable factorial (a.t.t.o.w. 2015/10/06) turns - out to be $5971!$ which has $19956$ digits.%\footnotemark -\end{framed} + \textbf{Warning:} \emph{it is not yet decided is this behaviour is + definitive.} + Currently \xintfracname has no notion of a positive zero or a negative zero. + Hence transitivity of \csbxint{Trunc} is broken for the case where the first + truncation gives on output \dtt{0.00...0} or \dtt{-0.00...0}: a second + truncation to less digits will then output \dtt{0}, whereas if it had been + applied directly to the initial input it would have produced \dtt{0.00...0} + or respectively \dtt{-0.00...0} (with less zeros). + If \xintfracname distinguished zero, positive zero, and + negative zero it would be possible to maintain transitivity. -|\xintiFac| is originally a synonym. With \xintfracname loaded it applies -|\xintNum| to its argument and thus accepts a fractional input but truncates -it to an integer. + The problem would also be fixed, even without distinguishing a negative zero + on input, if \csbxint{Trunc} always produced \dtt{0.00...0} (with no sign) + when the mathematical result is zero, discarding the information on original + input being positive, zero, or negative. -The |factorial| function, or equivalently |!| as post-fix operator is -available in \csbxint{iiexpr}, \csbxint{expr}: + I have multiple times hesitated about what to do and must postpone again + final decision. +\end{framed} \begin{everbatim*} -\printnumber{\xinttheiiexpr 200!\relax}\par +\xintTrunc {16}{-803.2028/20905.298}\newline +\xintTrunc {20}{-803.2028/20905.298}\newline +\xintTrunc {10}{\xintPow {-11}{-11}}\newline +\xintTrunc {12}{\xintPow {-11}{-11}}\newline +\xintTrunc {50}{\xintPow {-11}{-11}}\newline +\xintTrunc {12}{\xintAdd {-1/3}{3/9}}\par \end{everbatim*} -See also \csbxint{FloatFac} from package \xintfracname for the float variant, -used in \csbxint{floatexpr}. - +The digits printed are exact up to and including the last one. +\subsection{\csbh{xintXTrunc}}\label{xintXTrunc} -\subsection{\csbh{xintiDivision}, - \csbh{xintiiDivision}}\label{xintiDivision}\label{xintiiDivision} +\csa{xintXTrunc}|{x}{f}|\retype{\numx\Ff} is similar to \csbxint{Trunc} with +the following important differences: +\begin{itemize}[nosep] +\item it is completely expandable but not +\fexpan dable, as is indicated by the hollow star in the margin, +\item hence it can not be used as argument to the other package macros, but as + it \fexpan ds its |{f}| argument, it accepts arguments expressed with other + \xintfracname macros, +\item it requires |x>0|, +\item contrarily to \csbxint{Trunc} the number of digits on output is not + limited to about \dtt{19950} and may go well beyond \dtt{100000} (this is + mainly useful for outputting a decimal expansion to a file), +\item when the mathematical result is zero, it always prints it as + \dtt{0.00...0} or \dtt{-0.00...0} with |x| zeros after the decimal mark. +\end{itemize} -|\xintiiDivision|\n\m\etype{ff} returns |{quotient Q}{remainder R}|. This is -euclidean division: |N = QM + R|, |0|${}\leq{}$\verb+R < |M|+. So the -remainder is always non-negative and the formula |N = QM + R| always holds -independently of the signs of |N| or |M|. Division by zero is an error (even -if |N| vanishes) and returns |{0}{0}|. It skips the overhead of parsing via -\csbxint{Num}. +\textbf{Warning:} +transitivity is broken too (see discussion of \csbxint{Trunc}), due to the +sign in the last item. Hence \emph{the definitive policy is yet to be fixed.} -|\xintiDivision|\etype{\Numf\Numf} submits its arguments to \csbxint{Num}. +Transitivity is here in the sense of using a first |\edef| and then a second +one, because it is not possible to nest \csb{xintXTrunc} directly as argument +to itself. Besides, although the number of digits on output isn't limited, +nevertheless |x| should be less than about |19970| when the number of digits +of the input (assuming it is expressed as a decimal number) is even bigger: +|\xintXTrunc{30000}{\Z}| after |\edef\Z{\xintXTrunc{60000}{1/66049}| raises an +error in contrast with a direct |\xintXTrunc{30000}{1/66049}|. But +|\xintXTrunc{30000}{123.456789}| works, because here the number of digits +originally present is smaller than what is asked for, thus the routine only +has to add trailing zeros, and this has no limitation (apart from \TeX\ main +memory). -\subsection{\csbh{xintiQuo}, \csbh{xintiiQuo}}\label{xintiQuo}\label{xintiiQuo} +\csbxint{XTrunc} will expand fully in an |\edef| or a |\write| (|\message|, +|\wlog|, \dots) or in an \csbxint{expr}-ession, or as list argument to +\csbxint{For*}. -|\xintiiQuo|\n\m\etype{ff} returns the quotient from the euclidean division. -It skips the overhead of parsing via \csbxint{Num}. +Here is an example session where the +user checks that the decimal expansion of $1/66049=1/257^2$ has the maximal +period length $257*256=65792$ (this period length must be a divisor of +$\phi(66049)$ and to check it is the maximal one it is enough to show that +neither $32896$ nor $256$ are periods.) -|\xintiQuo|\etype{\Numf\Numf} submits its arguments to \csbxint{Num}. +\begingroup\small +\everb|@ +$ rlwrap etex -jobname worksheet-66049 +This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016) (preloaded format=etex) + restricted \write18 enabled. +**xintfrac.sty +entering extended mode +(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintfrac.sty +(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xint.sty +(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintcore.sty +(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintkernel.sty)))) +*% we load xinttools for \xintKeep, etc... \xintXTrunc itself has no more -\subsection{\csbh{xintiRem}, \csbh{xintiiRem}}\label{xintiRem}\label{xintiiRem} +*% any dependency on xinttools.sty since 1.2i -|\xintiiRem|\n\m\etype{ff} returns the remainder from the euclidean -division. It skips the overhead of parsing via \csbxint{Num}. +*\input xinttools.sty +(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xinttools.sty) +*\def\m#1;{\message{#1}} -|\xintiRem|\etype{\Numf\Numf} submits its arguments to \csbxint{Num}. +*\m \the\numexpr 257*257\relax; +66049 +*\m \the\numexpr 257*256\relax; +65792 +*% Thus 1/66049 will have a period length dividing 65792. -\subsection{\csbh{xintiDivRound}, \csbh{xintiiDivRound}} -\label{xintiDivRound}\label{xintiiDivRound} +*% Let us first check it is indeed periodical. -|\xintiiDivRound|\n\m\etype{ff} returns the rounded value of the algebraic -quotient $N/M$ of two big integers. The rounding is ``away from zero.'' The -macro skips the overhead of parsing via \csbxint{Num}. -\begin{everbatim*} -\xintiiDivRound {100}{3}, \xintiiDivRound {101}{3} -\end{everbatim*} +*\edef\Z{\xintXTrunc{66000}{1/66049}} -|\xintiDivRound|\etype{\Numf\Numf} submits its arguments to \csbxint{Num}. +*% Let's display the first decimal digits. -\subsection{\csbh{xintiDivTrunc}, \csbh{xintiiDivTrunc}} -\label{xintiDivTrunc}\label{xintiiDivTrunc} +*\m \xintXTrunc{208}{\Z}; -|\xintiiDivTrunc|\n\m\etype{ff} computes the truncation towards zero of the -algebraic quotient $N/M$. It skips the overhead of parsing the operands with -\csbxint{Num}. For $M>0$ it is the same as \csbxint{iiQuo}. -\begin{everbatim*} -$\xintiiQuo {1000}{-57}, \xintiiDivRound {1000}{-57}, \xintiiDivTrunc {1000}{-57}$ -\end{everbatim*} +0.00001514027464458205271843631243470756559523989765174340262532362337052794137 +6856576178291874214598252812306015231116292449545034746930309315810988811337037 +6538630410755651107511090251177156353616254598858423 +*% let's now fetch the trailing digits -|\xintiDivTrunc|\etype{\Numf\Numf} submits its arguments to \csbxint{Num}. +*\m \xintKeep{65792-66000}{\Z};% 208 trailing digits -\subsection{\csbh{xintiMod}, \csbh{xintiiMod}} -\label{xintiMod}\label{xintiiMod} +0000151402746445820527184363124347075655952398976517434026253236233705279413768 +5657617829187421459825281230601523111629244954503474693030931581098881133703765 +38630410755651107511090251177156353616254598858423 +*% yes they match! we now check that 65792/2 and 65792/257=256 aren't periods. -|\xintiiMod|\n\m\etype{ff} computes $N - M*t(N/M)$, where $t(N/M)$ is the -algebraic quotient truncated towards zero . The macro skips the overhead of parsing -the operands with \csbxint{Num}. For $M>0$ it is the same as \csbxint{iiRem}. -\begin{everbatim*} -$\xintiiRem {1000}{-57}, \xintiiMod {1000}{-57}, - \xintiiRem {-1000}{57}, \xintiiMod {-1000}{57}$ -\end{everbatim*} +*\m \xintXTrunc{256}{\Z}; -|\xintiMod|\etype{\Numf\Numf} submits its arguments to \csbxint{Num}. +0.00001514027464458205271843631243470756559523989765174340262532362337052794137 +6856576178291874214598252812306015231116292449545034746930309315810988811337037 +6538630410755651107511090251177156353616254598858423291798513225029902042423049 +554118911717058547442 +*\m \xintXTrunc{256+256}{\Z}; -\begin{framed} - For legacy reasons the macros next do not have |ii| in their names but they - behave in the corresponding way, \emph{i.e.} their - argument must be a (long) integer in the strict format or a macro \fexpan - ding to such digit tokens. -\end{framed} +0.00001514027464458205271843631243470756559523989765174340262532362337052794137 +6856576178291874214598252812306015231116292449545034746930309315810988811337037 +6538630410755651107511090251177156353616254598858423291798513225029902042423049 +5541189117170585474420505987978621932201850141561567926842192917379521264515738 +3154930430438008145467758785144362518736089872670290239064936637950612424109373 +3440324607488379839210283274538600130206361943405653378552286938485064119063119 +8049932625777831609865402958409665551333 +*% now with 65792/2=32896. Problem: we can't do \xintXTrunc{32896+100}{\Z} -\subsection{\csbh{xintDouble}, \csbh{xintHalf}} -\label{xintDouble} -\label{xintHalf} +*% but only direct \xintXTrunc{32896+100}{1/66049}. Anyway we want to nest it -|\xintDouble|\n\etype{f} computes |2N| and |\xintHalf|\n{} computes |N/2| -truncated towards zero. Rewritten for |1.2i|. +*% hence let's do it all with (slower) \xintKeep, \xintKeepUnbraced. -\subsection{\csbh{xintInc}, \csbh{xintDec}} -\label{xintInc} -\label{xintDec} +*\m \xintKeep {-100}{\xintKeepUnbraced{2+65792/2+100}{\Z}}; -|\xintInc|\n\etype{f} evaluates to |N+1| and |\xintDec|\n{} to |N-1|. -Rewritten for |1.2i|. +9999848597253554179472815636875652924344047601023482565973746763766294720586231 +434238217081257854017 +*% This confirms 32896 isn't a period length. -\subsection{\csbh{xintDSL}}\label{xintDSL} +*% To conclude let's write the 66000 digits to the log. -|\xintDSL|\n\etype{f} is decimal shift left, \emph{i.e.} multiplication by -ten. Rewritten with |1.2i| and moved from \xintname to \xintcorename. +*\wlog{\Z} -\subsection{\csbh{xintDSR}}\label{xintDSR} +*% We want always more digits: -|\xintDSR|\n\etype{f} is truncated decimal shift right, \emph{i.e.} it is the -truncation of |N/10| towards zero. Rewritten with |1.2i| and moved from -\xintname to \xintcorename. +*\wlog{\xintXTrunc{150000}{1/66049}} -\subsection{\csbh{xintDSRr}}\label{xintDSRr} +*\bye +| +\endgroup % $ à cause de fontification de AUCTeX. -|\xintDSRr|\n\etype{f} is rounded decimal shift right, \emph{i.e.} it is the -rounding of |N/10| away from zero. It is needed in \xintcorename for use by -\csbxint{iiDivRound}.\NewWith {1.2i} +The acute observer will have noticed that there is something funny when one +compares the first digits with those after the middle-period: +\begin{everbatim} +0000151402746445820527184363124347075655952398976517434026253236233705279413768... +9999848597253554179472815636875652924344047601023482565973746763766294720586231... +\end{everbatim} +Mathematical exercise: can you explain why the two indeed add to |9999...9999|? +You can try your hands at this simpler one: +\begin{everbatim*} +1/49=\xintTrunc{42+5}{1/49}...\newline +\xintTrim{2}{\xintTrunc{21}{1/49}}\newline +\xintKeep{-21}{\xintTrunc{42}{1/49}} +\end{everbatim*} -\clearpage -\section{Macros of the \xintname package} -\label{sec:xint} +This was again an example of the type |1/N| with |N| the square of a prime. +One can also find counter-examples within this class: |1/31^2| and |1/37^2| +have an odd period length (|465| and respectively |111|) hence they can not +exhibit the symmetry. \begin{framed} - This package loads automatically \xintcorename (and \xintkernelname) hence - all macros described in \autoref{sec:core} are still available. Notice - though that it does \emph{not} load package \xinttoolsname. + Mathematical challenge: prove generally that if the period length of the + decimal expansion of |1/p^r| (with |p| a prime distinct from |2| and |5| and + |r| a positive exponent) is even, then the previously observed symmetry + about the two halves of the period adding to a string of nine's applies. \end{framed} -\localtableofcontents - -This is \texttt{\xintbndlversion} of -\texttt{\xintbndldate}. - -Version |1.0| was released |2013/03/28|. - -Since |1.1 2014/10/28| the core arithmetic macros have been moved to a separate -package \xintcorename, which is automatically loaded by \xintname. -See the documentation of \xintcorename or \autoref{ssec:expansions} for the -significance of the \textcolor[named]{PineGreen}{\Numf}, -\textcolor[named]{PineGreen}{\emph{f}}, \textcolor[named]{PineGreen}{\numx} -and \textcolor[named]{PineGreen}{$\star$} margin annotations and some -important background information. -\subsection{\csbh{xintReverseDigits}} \label{xintReverseDigits} +\subsection{\csbh{xintTFrac}}\label{xintTFrac} -|\xintReverseDigits|\n\etype{f} will reverse the order of the digits of the -number. \csa{xintRev} is the former -denomination and is kept as an alias. Leading zeroes resulting from the -operation are not removed. Contrarily to \csbxint{ReverseOrder} this macro -expands its argument; it is only usable with digit tokens. It does accept a -leading minus sign which is left upfront in output. +\csa{xintTFrac}|{f}|\etype{\Ff} returns the fractional part, +|f=trunc(f)+frac(f)|. Thus if |f<0|, then |-10| one has +|0<= frac(f)<1|. The |T| stands for `Trunc', and there should exist also +similar macros associated respectively with `Round', `Floor', and `Ceil', each +type of rounding to an integer deserving arguably to be associated with a +fractional ``modulo''. By sheer laziness, the package currently implements +only the ``modulo'' associated with `Truncation'. Other types of modulo may be +obtained more cumbersomely via a combination of the rounding with a subsequent +subtraction from |f|. +Notice that the result is filtered through \csbxint{REZ}, and will thus be of +the form |A/B[N]|, where neither |A| nor |B| has trailing zeros. But the +output fraction is not reduced to smallest terms. -\begingroup +The function call in expressions (\csbxint{expr}, \csbxint{floatexpr}) is +|frac|. Inside |\xintexpr..\relax|, the function |frac| is mapped to +\csa{xintTFrac}. Inside |\xintfloatexpr..\relax|, |frac| first applies +\csa{xintTFrac} to its argument (which may be an exact fraction with more +digits than the floating point precision) and only in a second stage makes the +conversion to a floating point number with the precision as set by |\xintDigits| +(default is \dtt{16}). \begin{everbatim*} -\fdef\x{\xintReverseDigits - {98765432109876543210987654321098765432109876543210}}\meaning\x\par -\noindent\fdef\x{\xintReverseDigits {\xintReverseDigits - {98765432109876543210987654321098765432109876543210}}}\meaning\x\par +\xintTFrac {1235/97}, \xintTFrac {-1235/97}\newline +\xintTFrac {1235.973}, \xintTFrac {-1235.973}\newline +\xintTFrac {1.122435727e5}\par \end{everbatim*} -\endgroup -\subsection{\csbh{xintLen}}\label{xintiLen} +\subsection{\csbh{xintRound}}\label{xintRound} -|\xintLen|\n\etype{\Numf} returns the length of the number, not counting the -sign. % -% -\leftedline{|\xintLen{-12345678901234567890123456789}|\dtt - {=\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). % -% -\leftedline{|\xintLen{-1e3/5.425}|\dtt - {=\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}|\dtt{=\xintRaw - {-1e3/5.425}}. +\csa{xintRound}|{x}{f}|\etype{\numx\Ff} returns the start of the decimal +expansion of the fraction |f|, rounded to |x| digits precision after the decimal +point. The argument |x| should be non-negative. Only when |f| evaluates exactly +to zero does \csa{xintRound} return |0| without decimal point. When |f| is not +zero, its sign is given in the output, also when the digits printed are all +zero. +\begin{everbatim*} +\xintRound {16}{-803.2028/20905.298}\newline +\xintRound {20}{-803.2028/20905.298}\newline +\xintRound {10}{\xintPow {-11}{-11}}\newline +\xintRound {12}{\xintPow {-11}{-11}}\newline +\xintRound {12}{\xintAdd {-1/3}{3/9}}\par +\end{everbatim*} -Let's point out that the whole thing should sum up to -less than circa $2^{31}$, but this is a bit theoretical. +\subsection{\csbh{xintFloor}}\label{xintFloor} -|\xintLen| is only for numbers or fractions. See also \csbxint{NthElt} from -\xinttoolsname. See also \csbxint{Length} from \xintkernelname for counting -tokens (or rather braced groups), more generally. +|\xintFloor {f}|\etype{\Ff} returns the largest relative integer |N| with +|N|${}\leqslant{}$|f|. +\begin{everbatim*} +\xintFloor {-2.13}, \xintFloor {-2}, \xintFloor {2.13} +\end{everbatim*} +Note the trailing |[0]|, see \csbxint{iFloor} if it is not desired. -\subsection{\csbh{xintCmp}, \csbh{xintiiCmp}}\label{xintiiCmp} +\subsection{\csbh{xintCeil}}\label{xintCeil} -|\xintCmp|\n\m\etype{\Numf\Numf} returns \dtt{1} if |N>M|, \dtt{0} if |N=M|, -and \dtt{-1} if |N{}$|f|. +\begin{everbatim*} +\xintCeil {-2.13}, \xintCeil {-2}, \xintCeil {2.13} +\end{everbatim*} -\csa{xintiiCmp} skips the \csbxint{Num} overhead.\etype{ff} +\subsection{\csbh{xintiTrunc}}\label{xintiTrunc} -\csbxint{Cmp} is re-defined by \xintfracname to accept fractions. +\csa{xintiTrunc}|{x}{f}|\etype{\numx\Ff} returns the integer equal to |10^x| +times what \csa{xintTrunc}|{x}{f}| would produce. +\begin{everbatim*} +\xintiTrunc {16}{-803.2028/20905.298}\newline +\xintiTrunc {10}{\xintPow {-11}{-11}}\newline +\xintiTrunc {12}{\xintPow {-11}{-11}}\par +\end{everbatim*} -Since |1.2l| these macros are actually provided by package \xintcorename.sty -(which is loaded by \xintname). +In particular \csa{xintiTrunc}|{0}{f}|'s output is in strict integer format +contrarily to \csa{xintTrunc}|{0}{f}| which produces an output with a decimal +mark, except if |f| turns out to be zero. -\subsection{\csbh{xintEq}, \csbh{xintiiEq}}\label{xintEq} +\subsection{\csbh{xintTTrunc}}\label{xintTTrunc} -|\xintEq|\n\m\etype{\Numf\Numf} returns 1 if |N=M|, 0 otherwise. Extended -by \xintfracname to fractions. +\csa{xintTTrunc}|{f}|\etype{\Ff} truncates to an integer (truncation towards +zero). This is the same as |\xintiTrunc {0}{f}| and also the same as +\csbxint{Num}. -\csa{xintiiEq} skips the \csbxint{Num} overhead.\etype{ff} +\subsection{\csbh{xintiRound}}\label{xintiRound} -\subsection{\csbh{xintNeq}, \csbh{xintiiNeq}} +\csa{xintiRound}|{x}{f}|\etype{\numx\Ff} returns the integer equal to |10^x| +times what \csa{xintRound}|{x}{f}| would return. +\begin{everbatim*} +\xintiRound {16}{-803.2028/20905.298}\newline +\xintiRound {10}{\xintPow {-11}{-11}}\par +\end{everbatim*} -|\xintNeq|\n\m\etype{\Numf\Numf} returns 0 if |N=M|, 1 otherwise. Extended -by \xintfracname to fractions. +In particular \csa{xintiRound}|{0}{f}|'s output is in strict integer format +contrarily to \csa{xintRound}|{0}{f}| which produces an output with a decimal +mark, except if |f| turns out to be zero. -\csa{xintiiNeq} skips the \csbxint{Num} overhead.\etype{ff} +\subsection{\csbh{xintiFloor}}\label{xintiFloor} -\subsection{\csbh{xintGt}, \csbh{xintiiGt}}\label{xintGt} +|\xintiFloor {f}|\etype{\Ff} does the same as \csbxint{Floor} but without the +trailing |/1[0]|. +\begin{everbatim*} +\xintiFloor {-2.13}, \xintiFloor {-2}, \xintiFloor {2.13} +\end{everbatim*} -|\xintGt|\n\m\etype{\Numf\Numf} returns 1 if |N|$>$|M|, 0 otherwise. -Extended by \xintfracname to fractions. +\subsection{\csbh{xintiCeil}}\label{xintiCeil} -\csa{xintiiGt} skips the \csbxint{Num} overhead.\etype{ff} +|\xintiCeil {f}|\etype{\Ff} does the same as \csbxint{Ceil} but its output is +without the |/1[0]|. +\begin{everbatim*} +\xintiCeil {-2.13}, \xintiCeil {-2}, \xintiCeil {2.13} +\end{everbatim*} -\subsection{\csbh{xintLt}, \csbh{xintiiLt}}\label{xintLt} +\subsection{\csbh{xintE}}\label{xintE} -|\xintLt|\n\m\etype{\Numf\Numf} returns 1 if |N|$<$|M|, 0 otherwise. -Extended by \xintfracname to fractions. +|\xintE {f}{x}|\etype{\Ff\numx} multiplies the fraction |f| by $10^x$. The +\emph{second} argument |x| must obey the \TeX{} bounds. Example: +\begin{everbatim*} +\count 255 123456789 \xintE {10}{\count 255} +\end{everbatim*} +Don't feed this example to \csbxint{Num}! -\csa{xintiiLt} skips the \csbxint{Num} overhead.\etype{ff} +\subsection{\csbh{xintCmp}}\label{xintCmp} -\subsection{\csbh{xintLtorEq}, \csbh{xintiiLtorEq}} +This\etype{\Ff\Ff} compares two fractions |F| and |G| and produces +|-1|, |0|, or |1| according to |FG|. -|\xintLtorEq|\n\m\etype{\Numf\Numf} returns 1 if |N|$\leqslant$|M|, 0 otherwise. -Extended by \xintfracname to fractions. +For choosing branches according to the result of comparing |f| and |g|, see +\csbxint{ifCmp}. -\csa{xintiiLtorEq} skips the \csbxint{Num} overhead.\etype{ff} +\subsection{\csbh{xintEq}}\label{xintEq} -\subsection{\csbh{xintGtorEq}, \csbh{xintiiGtorEq}} +|\xintEq{f}{g}|\etype{\Ff\Ff} returns 1 if |f=g|, 0 otherwise. -|\xintGtorEq|\n\m\etype{\Numf\Numf} returns 1 if |N|$\geqslant$|M|, 0 otherwise. -Extended by \xintfracname to fractions. +\subsection{\csbh{xintNotEq}}\label{xintNotEq} -\csa{xintiiGtorEq} skips the \csbxint{Num} overhead.\etype{ff} +|\xintNotEq{f}{g}|\etype{\Ff\Ff} returns 0 if |f=g|, 1 otherwise. -\subsection{\csbh{xintIsZero}, \csbh{xintiiIsZero}}\label{xintIsZero} +Former denomination \csa{xintNeq} is deprecated. -|\xintIsZero|\n\etype{\Numf} returns 1 if |N=0|, 0 otherwise. -Extended by \xintfracname to fractions. +\subsection{\csbh{xintGeq}}\label{xintGeq} -\csa{xintiiIsZero} skips the \csbxint{Num} overhead.\etype{f} +This\etype{\Ff\Ff} compares the \emph{absolute values} of two +fractions. +|\xintGeq{f}{g}| outputs |1| if {\catcode`| 12 $|f|\geqslant|g|$} and |0| +if not. -\subsection{\csbh{xintNot}}\label{xintNot} +Important: the macro compares \emph{absolute values}. -\csa{xintNot}\etype{\Numf} is a synonym for \csa{xintIsZero}. +\subsection{\csbh{xintGt}}\label{xintGt} -\subsection{\csbh{xintIsNotZero}, \csbh{xintiiIsNotZero}}\label{xintIsNotZero} +|\xintGt{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$>$|g|, \dtt{0} otherwise. -|\xintIsNotZero|\n\etype{\Numf} returns 1 if |N<>0|, 0 otherwise. -Extended by \xintfracname to fractions. +\subsection{\csbh{xintLt}}\label{xintLt} -\csa{xintiiIsNotZero} skips the \csbxint{Num} overhead.\etype{f} +|\xintLt{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$<$|g|, \dtt{0} otherwise. -\subsection{\csbh{xintIsOne}, - \csbh{xintiiIsOne}}\label{xintIsOne}\label{xintiiIsOne} +\subsection{\csbh{xintGtorEq}}\label{xintGxstorEq} -|\xintIsOne|\n\etype{\Numf} returns 1 if |N=1|, 0 otherwise. +|\xintGtorEq{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$\geqslant$|g|, \dtt{0} otherwise. Extended by \xintfracname to fractions. -\csa{xintiiIsOne} skips the \csbxint{Num} overhead.\etype{f} - -\subsection{\csbh{xintAND}}\label{xintAND} - -|\xintAND|\n\m\etype{\Numf\Numf} returns 1 if |N<>0| and |M<>0| and zero -otherwise. Extended by \xintfracname to fractions. +\subsection{\csbh{xintLtorEq}}\label{xintLtorEq} -\subsection{\csbh{xintOR}}\label{xintOR} +|\xintLtorEq{f}{g}|\etype{\Ff\Ff} returns \dtt{1} if |f|$\leqslant$|g|, \dtt{0} otherwise. -|\xintOR|\n\m\etype{\Numf\Numf} returns 1 if |N<>0| or |M<>0| and zero -otherwise. Extended by \xintfracname to fractions. +\subsection{\csbh{xintIsZero}}\label{xintIsZero} -\subsection{\csbh{xintXOR}}\label{xintXOR} +|\xintIsZero{f}|\etype{f} returns \dtt{1} if |f=0|, \dtt{0} otherwise. -|\xintXOR|\n\m\etype{\Numf\Numf} returns 1 if exactly one of |N| or |M| -is true (i.e. non-zero). Extended by \xintfracname to fractions. +\subsection{\csbh{xintIsNotZero}}\label{xintIsNotZero} -\subsection{\csbh{xintANDof}}\label{xintANDof} +|\xintIsNotZero{f}|\etype{f} returns \dtt{1} if |f!=0|, \dtt{0} otherwise. -\csa{xintANDof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast\Numf} 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. +\subsection{\csbh{xintIsOne}}\label{xintIsOne} -\subsection{\csbh{xintORof}}\label{xintORof} +|\xintIsOne{f}|\etype{f} returns \dtt{1} if |f=1|, \dtt{0} otherwise. -\csa{xintORof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast\Numf} 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. +\subsection{\csbh{xintOdd}}\label{xintOdd} -\subsection{\csbh{xintXORof}}\label{xintXORof} +|\xintOdd{f}|\etype{f} returns \dtt{1} if the integer obtained by truncation is +odd, and \dtt{0} otherwise. -\csa{xintXORof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast\Numf} 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{xintEven}}\label{xintEven} -\subsection{\csbh{xintGeq}}\label{xintiGeq} +|\xintEven{f}|\etype{f} returns \dtt{1} if the integer obtained by truncation is +even, and \dtt{0} otherwise. -|\xintGeq|\n\m\etype{\Numf\Numf} 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|) -Important: the macro compares \emph{absolute values}. +\subsection{\csbh{xintifSgn}}\label{xintifSgn} -\subsection{\csbh{xintiMax}, \csbh{xintiiMax}}\label{xintiMax}\label{xintiiMax} +\csbh{xintifSgn}\marg{f}\marg{B}\marg{C}\etype{\Ff nnn} executes either the +\meta{A}, \meta{B} or \meta{C} code, depending on its first argument being +respectively negative, zero, or positive. -|\xintiMax|\n\m\etype{\Numf\Numf} 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}|\dtt{=\xintiMax{-5}{-6}}. +\subsection{\csbh{xintifZero}}\label{xintifZero} -The |\xintiiMax| macro skips the overhead of parsing the operands with -\csbxint{Num}.\etype{ff} +\csa{xintifZero}\marg{f}\marg{IsZero}\marg{IsNotZero}\etype{\Ff nn} expandably +checks if the first mandatory argument |N| (a number, possibly a fraction if +\xintfracname is loaded, or a macro expanding to one such) is zero or not. It +then either executes the first or the second branch. -\subsection{\csbh{xintiMin}, \csbh{xintiiMin}}\label{xintiMin}\label{xintiiMin} +Beware that both branches must be present. -|\xintiMin|\n\m\etype{\Numf\Numf} 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}|\dtt{=\xintiMin{-5}{-6}}. +\subsection{\csbh{xintifNotZero}}\label{xintifNotZero} -The |\xintiiMin| macro skips the overhead of parsing the operands with -\csbxint{Num}.\etype{ff} +\csa{xintifNotZero}\marg{N}\marg{IsNotZero}\marg{IsZero}\etype{\Ff nn} +expandably checks if the first mandatory argument |f| is not +zero or is zero. It then either executes the first or the second branch. -\subsection{\csbh{xintiMaxof}, \csbh{xintiiMaxof}}\label{xintiMaxof}\label{xintiiMaxof} +Beware that both branches must be present. -\csa{xintiMaxof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast\Numf} returns the -maximum. The list argument may be a macro, it is \fexpan ded first. Each item -is submitted to |\xintNum| normalization. +\subsection{\csbh{xintifOne}}\label{xintifOne} -\csa{xintiiMaxof} does the same, skips |\xintNum| normalization of -items. +\csa{xintifOne}\marg{N}\marg{IsOne}\marg{IsNotOne}\etype{\Ff nn} expandably +checks if the first mandatory argument |f| is one or not one. It +then either executes the first or the second branch. Beware that both branches +must be present. -\subsection{\csbh{xintiMinof}, \csbh{xintiiMinof}}\label{xintiMinof}\label{xintiiMinof} +\subsection{\csbh{xintifOdd}}\label{xintifOdd} -\csa{xintiMinof}|{{a}{b}{c}...}|\etype{f{$\to$}\lowast\Numf} returns the -minimum. The list argument may be a macro, it is \fexpan ded first. Each item -is submitted to |\xintNum| normalization. +\csa{xintifOdd}\marg{N}\marg{odd}\marg{not odd}\etype{\Ff nn} expandably +checks if the first mandatory argument |f|, after truncation to an integer, is +odd or even. It then executes accordingly the first or the second branch. +Beware that both branches must be present. -\csa{xintiiMinof} does the same, skips |\xintNum| normalization of -items. +\subsection{\csbh{xintifCmp}}\label{xintifCmp} -\subsection{\csbh{xintiiSum}}\label{xintiiSum} +\csa{xintifCmp}\marg{f}\marg{g}\marg{if fg}\etype{\Ff\Ff nnn} compares its first two arguments and chooses accordingly +the correct branch. -\csa{xintiiSum}\marg{braced things}\etype{{\lowast f}} after expanding its -argument expects to find a sequence of tokens (or braced material). Each is -\fexpan ded, and the sum of all these numbers is returned. -Note: the summands are \emph{not} parsed by \csbxint{Num}. +\subsection{\csbh{xintifEq}}\label{xintifEq} -% -\leftedline{% - \csa{xintiiSum}|{{123}{-98763450}{\xintiiFac{7}}{\xintiMul{3347}{591}}}|% - \dtt{=\xintiiSum{{123}{-98763450}{\xintiiFac{7}}{\xintiMul{3347}{591}}}}} -% -\leftedline{\csa{xintiiSum}|{1234567890}|\dtt{=\xintiiSum{1234567890}}} -An empty sum is no error and returns zero: |\xintiiSum -{}|\dtt{=\xintiiSum {}}. A sum with only one term returns that -number: |\xintiiSum {{-1234}}|\dtt{=\xintiiSum {{-1234}}}. -Attention that |\xintiiSum {-1234}| is not legal input and will make the -\TeX{} run fail. On the other hand |\xintiiSum -{1234}|\dtt{=\xintiiSum{1234}}. +\csa{xintifEq}\marg{f}\marg{g}\marg{YES}\marg{NO}\etype{\Ff\Ff nn} checks +equality of its two first arguments and executes accordingly the |YES| or the +|NO| branch. +\subsection{\csbh{xintifGt}}\label{xintifGt} -\subsection{\csbh{xintiiPrd}}\label{xintiiPrd} +\csa{xintifGt}\marg{f}\marg{g}\marg{YES}\marg{NO}\etype{\Ff\Ff nn} +checks if $f>g$ and in that case executes the |YES| branch. -\csa{xintiiPrd}\marg{braced things}\etype{{\lowast f}} after expanding its -argument expects to find a sequence of (of braced items or unbraced -single tokens). Each is -expanded (with the usual meaning), and the product of all these numbers is -returned. Note: the operands are \emph{not} parsed by \csbxint{Num}. -% -\leftedline{\csa{xintiiPrd}|{{-9876}{\xintiiFac{7}}{\xintiMul{3347}{591}}}|% - \dtt{=% - \xintiiPrd{{-9876}{\xintiiFac{7}}{\xintiMul{3347}{591}}}}} -% -\leftedline{\csa{xintiiPrd}|{123456789123456789}|\dtt{=% - \xintiiPrd{123456789123456789}}} An empty product is no error and returns 1: -|\xintiiPrd {}|\dtt{=\xintiiPrd {}}. A product reduced to a single term -returns this number: |\xintiiPrd {{-1234}}=|\dtt{\xintiiPrd {{-1234}}}. -Attention that |\xintiiPrd {-1234}| is not legal input and will make the \TeX{} -compilation fail. On the other hand |\xintiiPrd {1234}|\dtt{=\xintiiPrd - {1234}}. % -% -\begin{everbatim*} -$2^{200}3^{100}7^{100}=\printnumber - {\xintiiPrd {{\xintiPow {2}{200}}{\xintiPow {3}{100}}{\xintiPow {7}{100}}}}$ -\end{everbatim*} +\subsection{\csbh{xintifLt}}\label{xintifLt} -With \xintexprname, this would be easier: -% -\leftedline {|\xinttheiiexpr 2^200*3^100*7^100\relax |} +\csa{xintifLt}\marg{f}\marg{g}\marg{YES}\marg{NO}\etype{\Ff\Ff nn} +checks if $fB}\etype{\Numf\Numf nnn} compares -its arguments and chooses accordingly the correct branch. +\subsection{\csbh{xintSqr}}\label{xintSqr} -\csa{xintiiifCmp} skips the \csbxint{Num} overhead.\etype{ff} +Computes the square\etype{\Ff} of one fraction. -\subsection{\csbh{xintifEq}, \csbh{xintiiifEq}}\label{xintifEq} +\subsection{\csbh{xintPow}}\label{xintPow} -\csa{xintifEq}\marg{A}\marg{B}\marg{YES}\marg{NO}\etype{\Numf\Numf nn} -checks equality of its two first arguments (numbers, or fractions if -\xintfracname is loaded) and does the |YES| or the |NO| branch. +\csa{xintPow}{|{f}{x}|}:\etype{\Ff\Numf} computes |f^x| with |f| a fraction and +|x| possibly also, but |x| will first get truncated to a (positive or negative) +integer. -\csa{xintiiifEq} skips the \csbxint{Num} overhead.\etype{ff} +The output will now always be in the form |A/B[n]| (even if the exponent +vanishes: |\xintPow {2/3}{0}|\dtt{=\xintPow{2/3}{0}}). -\subsection{\csbh{xintifGt}, \csbh{xintiiifGt}}\label{xintifGt} -\csa{xintifGt}\marg{A}\marg{B}\marg{YES}\marg{NO}\etype{\Numf\Numf nn} checks if -$A>B$ and in that case executes the |YES| branch. Extended to fractions (in -particular decimal numbers) by \xintfracname. +Within an \csbxint{iiexpr}|..\relax| the infix operator |^| is mapped to +\csa{xintiiPow}; within an \csbxint{expr}-ession it is mapped to +\csa{xintPow}. -\csa{xintiiifGt} skips the \csbxint{Num} overhead.\etype{ff} +\subsection{\csbh{xintFac}}\label{xintFac} -\subsection{\csbh{xintifLt}, \csbh{xintiiifLt}}\label{xintifLt} +This is a convenience variant of \csbxint{iiFac} which applies \csbxint{Num} +to its argument\etype{\Numf}. Notice however that the output will have a trailing +|[0]| according to the \xintfracname format for integers. -\csa{xintifLt}\marg{A}\marg{B}\marg{YES}\marg{NO}\etype{\Numf\Numf nn} -checks if $A0|, |M^2-d=N| and -|M| smallest (hence |=1+\xintiSqrt{N}|). +\subsection{\csbh{xintMinof}}\label{xintMinof} -|\xintiiSquareRoot|\etype{f} is the variant skipping the |\xintNum| overhead. +The minimum of any number of fractions, each within braces, and the whole +thing within braces. \etype{f{$\to$}{\lowast\Ff}} \begin{everbatim*} -\xintAssign\xintiiSquareRoot {17000000000000000000000000}\to\A\B -\xintiiSub{\xintiiSqr\A}\B=\A\string^2-\B +\xintMinof {{1.23}{1.2299}{1.2301}} and \xintMinof {{-1.23}{-1.2299}{-1.2301}} \end{everbatim*} -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. +\subsection{\csbh{xintSum}}\label{xintSum} -\subsection{\csbh{xintiFac}, \csbh{xintiiFac}} +This\etype{f{$\to$}{\lowast\Ff}} computes the sum of fractions. The output +will now always be in the form |A/B[n]|. The original, for big integers only +(in strict format), is available as \csa{xintiiSum}. -Defined in \xintcorename, see \autoref{xintiiFac} for more info. +\begin{everbatim*} +\xintSum {{1282/2196921}{-281710/291927}{4028/28612}} +\end{everbatim*} -\subsection{\csbh{xintiBinomial}, \csbh{xintiiBinomial}} -\label{xintiiBinomial} +No simplification attempted. -|\xintiiBinomial{x}{y}|\etype{\numx\numx} computes binomial coefficients. +\subsection{\csbh{xintPrd}}\label{xintPrd} -|\xintiBinomial| is originally a synonym. -With \xintfracname loaded it applies -|\xintNum| to its arguments and thus accepts fractional inputs but truncates -them to an integer. - -When |x<0| an out-of-range error is raised. Else, if |y<0| or if |xx|, with a positive |x|.) - -\begin{framed} - The allowable range is $0\leqslant x\leqslant99999999$. -\end{framed} - % Thus the maximal computable value is ${9999 \choose 5000}$ which turns out - % to have \dtt{3008} digits. - This theoretical range includes binomial coefficients with more than the - roughly 19950 digits that the arithmetics of \xintname can handle. In such - cases, the computation will end up in a low-level \TeX{} error after a - long time. +TThis\etype{f{$\to$}{\lowast\Ff}} computes the product of fractions. The output +will now always be in the form |A/B[n]|. The original, for big integers only +(in strict format), is available as \csa{xintiiPrd}. -% -It turns out that ${65000 \choose 32500}$ has \dtt{19565} digits and -${64000 \choose 32000}$ has \dtt{19264} digits. The latter can be evaluated -(this takes a long long time) but presumably not the former (I didn't try). -Reasonable feasible evaluations are with binomial coefficients not exceeding -about one thousand digits. +\begin{everbatim*} +\xintPrd {{1282/2196921}{-281710/291927}{4028/28612}} +\end{everbatim*} +No simplification attempted. -% -The |binomial| function is available in the \xintexprname parsers. \begin{everbatim*} -\xinttheiiexpr seq(binomial(100,i), i=47..53)\relax +$\xintIsOne {21921379213/21921379213}\neq\xintIsOne {1.00000000000000000000000000000001}$ \end{everbatim*} -See \csbxint{FloatBinomial} from package \xintfracname for the float variant, -used in \csbxint{floatexpr}. +\subsection{\csbh{xintDigits}, \csbh{xinttheDigits}} +\label{xintDigits} +\label{xinttheDigits} +The syntax |\xintDigits := D;| (where spaces do not matter) assigns the +value of |D| to the number of digits to be used by floating point +operations. The default is |16|. The maximal value is |32767|. The macro +|\xinttheDigits|\etype{} serves to print the current value. +\subsection{\csbh{xintFloat}}\label{xintFloat} -In order to -evaluate binomial coefficients ${x \choose y}$ with $x>99999999$, or even -$x\geqslant 2^{31}$, but $y$ is not too large, one may use an ad hoc function -definition such as: -\begin{everbatim*} -\xintdeffunc mybigbinomial(x,y):=`*`(x-y+1..[1]..x)//y!;% -% without [1], x would have been limited to < 2^31 -\printnumber{\xinttheexpr mybigbinomial(98765432109876543210,10)\relax} -\end{everbatim*} +The macro |\xintFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} has an optional +argument |P| which replaces the current value of |\xinttheDigits|. The +fraction |f| is then printed in scientific notation with a rounding to |P| digits. + +That is, on output: the first digit is from |1| to |9|, it is possibly +prefixed by a minus sign and is followed by a dot and |P-1| digits, then a +lower case |e| and an exponent |N|. The trailing zeroes are not trimmed. -To get this functionality in macro form, one can do: +\begin{framed} + There is currently one exceptional case: the zero value, which gets output + as \dtt{\xintFloat{0}}. It is yet to be decided what the final policy will be. +\end{framed} + +Starting with |1.2k|,\NewWith{1.2k} when the input is a fraction |AeN/BeM| +the output always is the \emph{correct rounding} to |P| digits. Formerly, this +was guaranteed only when |A| and |B| had at most |P+2| digits, or when |B| was +|1| and |A| was arbitrary, but in other cases it was only guaranteed that the +difference between the original fraction and the rounding was at most +\dtt{0.6} unit in the last place (of the output), hence the output could +differ in the last digit (and earlier ones in case of chains of zeros or +nines) from the correct rounding. + +Also:\CHANGED{1.2k} for releases |1.2j| and earlier, in the special case when +|A/B| ended up being rounded up to the next power of ten, the output was with +a mantissa of the shape |10.0...0eN|. However, this worked only for |B=1| or +when both |A| and |B| had at most |P+2| digits, because the detection of the +rounding-up to next power of ten was done not on original |A/B| but on an +approximation |A'/B'|, and it could happen that |A'/B'| was itself being +rounded \emph{down} to a power of ten which however was a rounding \emph{up} +of original |A/B|. With the |1.2j| refactoring which achieves correct rounding +in all cases, it was decided not to add to the code the extra overhead of +detecting with 100\% fiability the rounding up to next power of ten (such +overhead would necessitate alterations of the algorithm and as a result we +would end up with a slightly less efficient one; it would make sense in a +model where inputs have their intrinsic precisions which is obeyed by the +implementation of the basic operations, but currently the design decision for +the floating point macros is that when the target precision is |P| the inputs +are rounded first to |P| digits before further processing.) \begin{everbatim*} -\xintNewIIExpr\MyBigBinomial [2]{`*`(#1-#2+1..[1]..#1)//#2!} -\printnumber{\MyBigBinomial {98765432109876543210}{10}} +{\def\x{99999999999999994999999999999999/99999999999999999999999999999999}% +\xintFor #1 in {13, 14, 15, 16, 17, 18, 19, 47, 48, 49, 50, 79, 80, 81} +\do{#1: \xintFloat[#1]{\x}\xintifForLast{\par}{\newline}}}% +\end{everbatim*} +As an aside, which is illustrated by the above, rounding is not +transitive in the number of kept digits. +\begin{everbatim*} +{\def\x{137893789173289739179317/13890138013801398}% +\xintFor* #1 in {\xintSeq{4}{20}} +\do{#1: \xintFloat[#1]{\x}\newline}}% +\xintFloat{5/9999999999999999}\newline +\xintFloat[32]{5/9999999999999999}\newline +\xintFloat[48]{5/9999999999999999}\par \end{everbatim*} -As we used \csa{xintNewIIExpr}, this macro will only accept strict integers. -Had we used \csa{xintNewExpr} the |\MyBigBinomial| would have accepted general -fractions or decimal numbers, and computed the product at the numerator -without truncating them to integers; but the factorial at the denominator -would truncate its argument. - -\subsection{\csbh{xintiPFactorial}, \csbh{xintiiPFactorial}} -\label{xintiiPFactorial} -|\xintiiPFactorial{a}{b}|\etype{\numx\numx} computes the partial factorial -|(a+1)(a+2)...b|. For |a=b| the product is considered empty hence returns |1|. -|\xintiPFactorial| is originally a synonym. -With \xintfracname loaded it applies -|\xintNum| to its arguments and thus accepts fractional inputs but truncates -them to an integer. +\subsection{\csbh{xintPFloat}}\label{xintPFloat} -\begin{framed} - The allowed range with |1.2f| was $0\leqslant a \leqslant b\leqslant99999999$. +The macro |\xintPFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} is like +\csbxint{Float} but ``pretty-prints'' the output. Its behaviour has changed +with release |1.2f|\IMPORTANT{}: there is only one simplification rule now +which is that decimal notation (with possibly needed extra zeros) is used in +place of scientific notation when the exponent would end up being between +\dtt{-5} and \dtt{5} inclusive. - It was a bit unfortunate with - |1.2f| that the code deliberately raised an error if this condition - was not obeyed by the arguments. +If the input vanishes the output will be \dtt{\xintPFloat{0}} with a a decimal +mark.% +% +\footnote{Currently there are no subnormal numbers, and no underflow + because the exponent is only limited by the maximal \TeX\ number; thus + underflow situations would manifest themselves via low-level arithmetic + overflow errors.} - Starting with |1.2h|, $-100000000\leqslant a, b\leqslant99999999$ is - accepted.\CHANGEDf{1.2h} - The - rule is to interpret the formula as the product of the - $j$'s such that $ab$ or negative arguments, the definitive rules have not yet - been fixed. +Currently trailing zeros are not trimmed. \begin{everbatim*} -\xintiiPFactorial {100}{130} +\begingroup\def\test #1{#1${}\to{}$\xintPFloat{#1}}% +\string\xintDigits\ at \xinttheDigits +\begin{itemize}[nosep] +\item \test {0} +\item \test {1.23456789e-7} +\item \test {1.23456789e-6} +\item \test {1.23456789e-5} +\item \test {1.23456789e-4} +\item \test {1.23456789e-3} +\item \test {1.23456789e-2} +\item \test {1.23456789e-1} +\item \test {1.23456789e0} +\item \test {1.23456789e1} +\item \test {1.23456789e2} +\item \test {1.23456789e3} +\item \test {1.23456789e4} +\item \test {1.23456789e5} +\item \test {1.23456789e6} +\item \test {1.23456789e7} +\end{itemize} +\endgroup \end{everbatim*} -\end{framed} -This theoretical range allows computations whose result values would have more -than the roughly 19950 digits that the arithmetics of \xintname can handle. In -such cases, the computation will end up in a low-level \TeX{} error after a -long time. +\subsection{\csbh{xintFloatE}}\label{xintFloatE} -% -The |pfactorial| function is available in the \xintexprname parsers. +|\xintFloatE [P]{f}{x}|\etype{{\upshape[\numx]}\Ff\numx} multiplies the input +|f| by $10^x$, and +converts it to float format according to the optional first argument or current +value of |\xinttheDigits|. \begin{everbatim*} -\xinttheiiexpr pfactorial(100,130)\relax +\xintFloatE {1.23e37}{53} \end{everbatim*} -See \csbxint{FloatPFactorial} from package \xintfracname for the float -variant, used in \csbxint{floatexpr}. +\subsection{\csbh{xintFloatAdd}}\label{xintFloatAdd} -In case values are needed with $b>99999999$, or even $b\geqslant 2^{31}$, but -$b-a$ is not too large, one may use an ad hoc function definition such as: -\begin{everbatim*} -\xintdeffunc mybigpfac(a,b):=`*`(a+1..[1]..b);% -% without [1], b would have been limited to < 2^31 -\printnumber{\xinttheexpr mybigpfac(98765432100,98765432120)\relax} -\end{everbatim*} +|\xintFloatAdd [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| +and |g| with their float approximations |f'| and |g'| to |P| significant +places or to the precision from |\xintDigits|. It then produces +the sum |f'+g'|, correctly rounded to nearest with the same number of +significant places. -\begin{framed} - The macros described next are strictly for integer-only arguments (which get - only \fexpan ded, not filtered via \csbxint{Num}.) -\end{framed} +\subsection{\csbh{xintFloatSub}}\label{xintFloatSub} -\subsection{\csbh{xintDSH}}\label{xintDSH} -|\xintDSH|\x\n\etype{\numx f} 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{xintDSR} |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|. +|\xintFloatSub [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| +and |g| with their float approximations |f'| and |g'| to |P| significant +places or to the precision from |\xintDigits|. It then produces +the difference |f'-g'| correctly rounded to nearest |P|-float. -\subsection{\csbh{xintDSHr}, \csbh{xintDSx}}\label{xintDSHr}\label{xintDSx} -|\xintDSHr|\x\n\etype{\numx f} expects |x| to be zero or positive and it -returns then a value |R| which is correlated to the value |Q| returned by -|\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{xintiDivision}), -\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|. +\subsection{\csbh{xintFloatMul}}\label{xintFloatMul} -|\xintDSx|\x\n\etype{\numx f} for |x| negative is exactly as -|\xintDSH|\x\n, \emph{i.e.} multiplication by $10^{-|x|}$. For |x| zero or -positive it returns the two numbers |{Q}{R}| described above, each one within -braces. So |Q| is |\xintDSH|\x\n, and |R| is |\xintDSHr|\x\n, but computed -simultaneously. -\subsection{\csbh{xintDecSplit}, \csbh{xintDecSplitL}, \csbh{xintDecSplitR}} -\label{xintDecSplit} -\label{xintDecSplitL} -\label{xintDecSplitR} +|\xintFloatMul [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| +and |g| with their float approximations |f'| and |g'| to |P| (or +|\xinttheDigits|) significant places. It then correctly rounds +the product |f'*g'| to nearest |P|-float. -|\xintDecSplit|\x\n\etype{\numx f} cuts the number into two pieces (each one -within a pair of enclosing braces) |{L}{R}| where the decimal writing of |N| -is the concatenation |LR|. +See \autoref{ssec:floatingpoint} for more. -For |x| positive or null, |R| coincides with the |x| least -significant digits and is \emph{empty} if |x=0|. If |x| equals or -exceeds the length of |N| the first piece |L| is empty. +\begin{framed} + It is obviously much needed that the author improves its algorithms to avoid + going through the exact |2P| or |2P-1| digits before + throwing to the waste-bin half of those digits ! -When |x| is negative the first piece |L| contains the ($-x$) most -significant digits and the second piece the remaining ones. Hence |R| is -\emph{empty} if $|x|$ equals or exceeds the length of |N|. + % \xintname initially was purely an \emph{exact} arbitrary precision + % arithmetic machine, and the introduction of floating point numbers was an + % after-thought. I got it working in release |1.07 (2013/05/25)| and never had + % time to come back to it. +\end{framed} -{\footnotesize Breaking change with |1.2i|: formerly |N<0| was replaced by its - absolute value. Now, a sign (positive or negative) will create an error. - The N must consists only of digit tokens (after \fexpan sion). Leading - zeroes are allowed.\par} +\subsection{\csbh{xintFloatDiv}}\label{xintFloatDiv} -|\xintDecSplitL|\x\n\etype{\numx f} returns the first piece (unbraced) from -the \csa{xintDecSplit} output. +|\xintFloatDiv [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| +and |g| with their float approximations |f'| and |g'| to |P| (or +|\xinttheDigits|) significant places. It then correctly rounds +the fraction |f'/g'| to nearest |P|-float. -|\xintDecSplitR|\x\n\etype{\numx f} returns the second piece (unbraced) from -the \csa{xintDecSplit} output. +See \autoref{ssec:floatingpoint} for more. -\subsection{\csbh{xintiiE}}\label{xintiiE} +Notice in the special situation with |f| and |g| integers that |\xintFloatDiv +[P]{f}{g}| will \emph{not necessarily} give the correct rounding of the +exact fraction |f/g|. Indeed the macro arguments are each first individually +rounded to |P| digits of precision. The correct syntax to get the correctly +rounded integer fraction |f/g| is \csbxint{Float}|[P]{f/g}|. -|\xintiiE|\n\x\etype{f\numx } serves to add zeros to the right of |N|. +\subsection{\csbh{xintFloatPow}}\label{xintFloatPow} + +|\xintFloatPow [P]{f}{x}|\etype{{\upshape[\numx]}\Ff\numx} uses either the +optional argument |P| or in its absence the value of |\xinttheDigits|. It +computes a floating approximation to |f^x|. + +The exponent |x| will be handed over to a |\numexpr|, hence count registers are +accepted on input for this |x|. And the absolute value \verb+|x|+ must obey the +\TeX{} bound. + +The argument |f| is first rounded to |P| significant places to give +|f'|. The output |Z| is such that the exact |f'^x| differs from +|Z| by an absolute error less than |0.52 ulp(Z)|. \begin{everbatim*} -\xintiiE {123}{89} +\xintFloatPow [8]{3.1415}{1234567890} \end{everbatim*} +\subsection{\csbh{xintFloatPower}}\label{xintFloatPower} -%\pagebreak +\csa{xintFloatPower}|[P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Numf} computes a +floating point value |f^g| where the exponent |g| is not constrained to be at +most the \TeX{} bound \dtt{\number "7FFFFFFF}. It may even be a fraction +|A/B| but must simplify to a (possibly big) integer. The exponent of the +\emph{output} however \emph{must} at any rate obey the \TeX{} bound. -\clearpage -\section{Macros of the \xintfracname package} -\label{sec:frac} +The argument |f| is first rounded to |P| significant places to give +|f'|. The output |Z| is then such that the exact |f'^g| differs from +|Z| by an absolute error less than |0.52 ulp(Z)|. -\begin{framed} - This package loads automatically \xintname and \xintcorename, hence all - macros described in \autoref{sec:xint} and \autoref{sec:core} are - available. Note that macros of those packages whose names contain |ii| are - for integers only, not fractions. Those with a single |i| accept fractions - but truncate them to integers. -\end{framed} +This is the macro which is used for the |^| (or |**|) infix operators in +|\xintthefloatexpr...\relax|. In this context (but not directly with the +macro,) half-integer exponents are allowed. This is handled via an integer power +followed by a square-root extraction. The exponent is first rounded to nearest +integer or half-integer so that the computation never raises errors (except +naturally for negative exponent and zero |f|.) The |0.52 ulp(Z)| bound applies +with half-integer exponents too. -\localtableofcontents -\def\x{|{x}|} +Notice that this is a bound on the distance from |f'^g| to |Z|, as |f| always +gets rounded to |P| or \csbxint{theDigits} digits. The distance from |f^g| to +|Z| can be much worse if |g| is very large. Roughly, when |g| is negligible +compared to |10^P|, we get an extra difference of up to about |50g ulp(Z)| +which completely dwarfs the |0.52 ulp(Z)|. Thus, if |f| has strictly more than +|P| digits, then the computation must be done with an elevated working +precision |P'|. For example with |g=1000| we should use |P'=P+6| to achieve a +total error at worst slightly bigger than |0.55 ulp(Z)| after the final +rounding from |P'| to |P| digits to get |Z|. -This package was first included in release |1.03| (|2013/04/14|) of the -\xintname bundle. The general rule of the bundle that each macro first expands -(what comes first, fully) each one of its arguments applies. +Examples:% +% +\footnote{|\np| is formatting macro from the \url{http://ctan.org/pkg/numprint} + package.} +% +\begin{everbatim*} +\np{\xintFloatPower [8]{3.1415}{3e9}}\newline% Notice that 3e9>2^31 +\np{\xintFloatPower [48]{1.1547}{\xintiiPow {2}{35}}}\newline +\end{everbatim*}% +$2^{35}=\xintiiPow {2}{35}$ exceeds \TeX's bound, but what +counts is the exponent of the result which, while dangerously close to +$2^{31}$ is not quite there yet. -|f|\ntype{\Ff} stands for an integer or a fraction (see \autoref{sec:inputs} -for the accepted input formats) or something which expands to an integer or -fraction. It is possible to use in the numerator or the denominator of |f| count -registers and even expressions with infix arithmetic operators, under some rules -which are explained in the \autoref{sec:useofcount} section. +With expressions: +\begin{everbatim*} +{\xintDigits:=48;\np{\xintthefloatexpr 1.1547^(2^35)\relax}} +\end{everbatim*} -As in the \hyperref[sec:xint]{xint.sty} documentation, |x|\ntype{\numx} -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 -must expand to an integer obeying the \TeX{} bound. +There is a subtlety here that the |2^35| will be evaluated as a floating point +number but fortunately it only has \dtt{11} digits, hence the final evaluation +is done with a correct exponent. It would have been safer, and also more +efficient to code the above rather as: +\begin{everbatim} +\xintthefloatexpr 1.1547^\xintiiexpr 2^35\relax\relax +\end{everbatim} -The fraction format on output is the scientific notation for the `float' macros, -and the |A/B[n]| format for all other fraction macros, with the exception of -\csbxint{Trunc}, {\color{blue}\string\xint\-Round} (which produce decimal -numbers) and \csbxint{Irr}, \csbxint{Jrr}, \csbxint{RawWithZeros} (which returns -an |A/B| with no trailing |[n]|, and prints the |B| even if it is |1|), and -\csbxint{PRaw} which does not print the |[n]| if |n=0| or the |B| if |B=1|. +Here is an example with +|12^16| as exponent, which has $18$ digits (\dtt{={\xintiiPow{12}{16}}}). +\begin{everbatim*} +{\xintDigits:=12;\np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}}\newline +\np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}\newline +{\xintDigits:=27;\np{\xintthefloatexpr (1+1e-8)^(12^16)\relax}}\newline +{\xintDigits:=48;\np{\xintthefloatexpr (1+1e-8)^(12^16)\relax}} +\end{everbatim*} -To be certain to print an integer output without trailing |[n]| nor fraction -slash, one should use either |\xintPRaw {\xintIrr {f}}| or |\xintNum {f}| when -it is already known that |f| evaluates to a (big) integer. For example -|\xintPRaw {\xintAdd {2/5}{3/5}}| gives a perhaps disappointing -\dtt{\xintPRaw {\xintAdd {2/5}{3/5}}} -% +There is an important difference between |\xintFloatPower[Q]{X}{Y}| and +|\xintthefloatexpr[Q] X^Y\relax|: in the former case the computation is done +with |Q| digits or precision,% % +\footnote{if |X| and |Y| themselves stand for some +floating point macros with arguments, their respective evaluations obey the +precision |\xinttheDigits| or as set optionally in the macro calls +themselves.} % -whereas |\xintPRaw {\xintIrr {\xintAdd - {2/5}{3/5}}}| returns \dtt{\xintPRaw {\xintIrr {\xintAdd - {2/5}{3/5}}}}. As we knew the result was an integer we could have used -|\xintNum {\xintAdd {2/5}{3/5}}=|\xintNum {\xintAdd {2/5}{3/5}}. +whereas with \csbxint{thefloatexpr}|[Q]| the evaluation of the +expression proceeds with |\xinttheDigits| digits of precision, and the final +result is then rounded to |Q| digits: thus this makes real sense only if used +with |Q<\xinttheDigits|. -Some macros (such as \csbxint{iTrunc}, \csbxint{iRound}, and \csbxint{iFac}) -always produce integers on output. +\subsection{\csbh{xintFloatSqrt}}\label{xintFloatSqrt} +\csa{xintFloatSqrt}|[P]{f}|\etype{{\upshape[\numx]}\Ff} computes a floating +point approximation of $\sqrt{|f|}$, either using the optional precision |P| or +the value of |\xinttheDigits|. -Refer to \autoref{ssec:floatingpoint} for general background information on -how floating point numbers and evaluations are implemented. +More precisely since |1.2f| the macro achieves so-called \emph{correct + rounding}:\IMPORTANT{} the produced value is the rounding to |P| significant +places of the abstract exact value, \emph{if the input has itself at most |P| + digits} (and an arbitrary exponent). +\begin{everbatim*} +\xintFloatSqrt [89]{10}\newline +\xintFloatSqrt [89]{100}\newline +\xintFloatSqrt [89]{123456789}\par +\end{everbatim*} -\subsection{\csbh{xintNum}}\label{xintNum} +And now some tests to check that correct rounding applies correctly (sic): +\begin{everbatim*} +The argument has 16 digits, hence escapes initial rounding:\newline +\xintFloatSqrt {5625000075000001}\newline +This one gets rounded hence same value is computed:\newline +\xintFloatSqrt {5625000075000001.4}\newline +but actual value is more like:\newline +\xintFloatSqrt [24]{5625000075000001.4}\newline +\xintFloatSqrt [32]{5625000075000001.4}\newline +The argument has 48 digits, hence escapes initial rounding:\newline +\xintFloatSqrt [48]{562500000000000000000000750000000000000000000001}\newline +\xintFloatSqrt [64]{562500000000000000000000750000000000000000000001}\newline +\xintFloatSqrt [80]{562500000000000000000000750000000000000000000001}\newline +\end{everbatim*} +(we observe in passing illustrations that rounding to nearest is not +transitive.)\par -The macro\etype{f} from \xintname is made a synonym to \csbxint{TTrunc}.% -\footnote{In earlier releases than - |1.1|, \csbxint{Num} did \csbxint{Irr} and then complained if the - denominator was not |1|, else, it silently removed the denominator.} -The original (which -normalizes big integers to strict format) is still available as -\csbxint{iNum}. -It is imprudent to apply \csa{xintNum} to numbers with a large -power of ten given either in scientific notation or with the |[n]| notation, -as the macro will according to its definition add all the needed zeroes to -produce an explicit integer in strict format. -\subsection{\csbh{xintifInt}}\label{xintifInt} -\csa{xintifInt}|{f}{YES branch}{NO branch}|\etype{\Ff nn} expandably chooses -the |YES| branch if |f| reveals itself after expansion and simplification to -be an integer. As with the other \xintname conditionals, both branches must be -present although one of the two (or both, but why then?) may well be an empty -brace pair |{}|. Spaces in-between the braced things do not matter, but a -space after the closing brace of the |NO| branch is significant. -\subsection{\csbh{xintLen}}\label{xintLen} -The original macro\etype{\Ff} is extended to accept a fraction on input. -% -\leftedline {|\xintLen {201710/298219}|\dtt{=\xintLen {201710/298219}}, -|\xintLen {1234/1}|\dtt{=\xintLen {1234/1}}, |\xintLen {1234}|% - \dtt{=\xintLen {1234}}} +\subsection{\csbh{xintFloatFac}}\label{xintFloatFac} -\subsection{\csbh{xintRaw}}\label{xintRaw} +\csa{xintFloatFac}|[P]{f}|\etype{{\upshape[\numx]}\Numf} returns the +factorial with either \csa{xinttheDigits} or |P| digits of precision. -This macro `prints' the\etype{\Ff} -fraction |f| as it is received by the package after its parsing and -expansion, in a form |A/B[n]| equivalent to the internal -representation: the denominator |B| is always strictly positive and is -printed even if it has value |1|. -% -\leftedline{|\xintRaw{\the\numexpr 571*987\relax.123e-10/\the\numexpr - -201+59\relax e-7}=|} -% -\leftedline{\dtt{\xintRaw{\the\numexpr - 571*987\relax.123e-10/\the\numexpr -201+59\relax e-7}}} +% je devrais vérifier mais j'ai écrit cela fin novembre 2015 début décembre je +% suppose que je savais ce que je disais. -\subsection{\csbh{xintPRaw}}\label{xintPRaw} -|PRaw|\etype{\Ff} stands for ``pretty raw''. It does \emph{not} show the |[n]| -if |n=0| and does \emph{not} show the |B| if |B=1|. -% % -% -\leftedline{|\xintPRaw {123e10/321e10}=|\dtt{\xintPRaw {123e10/321e10}}, % -|\xintPRaw {123e9/321e10}=|\dtt{\xintPRaw {123e9/321e10}}} -% % -% -\leftedline{|\xintPRaw {\xintIrr{861/123}}=|\dtt{\xintPRaw{\xintIrr{861/123}}}\ vz.\ - |\xintIrr{861/123}=|\dtt{\xintIrr{861/123}}} -% % -See also \csbxint{Frac} (or \csbxint{FwOver}) for math mode. As is examplified -above the \csbxint{Irr} macro which puts the fraction into irreducible form -does not remove the |/1| if the fraction is an integer. One can use -|\xintNum{f}| or |\xintPRaw{\xintIrr{f}}| which produces the same output only -if |f| is an integer (after simplication). +The exact theoretical value differs from the calculated one |Y| by an absolute +error strictly less than |0.6 ulp(Y)|. -\subsection{\csbh{xintNumerator}}\label{xintNumerator} +\begin{everbatim*} +$1000!\approx{}$\xintFloatFac [30]{1000} +\end{everbatim*} +The computation proceeds via doing explicitely the product, as +the Stirling formula cannot be used for lack so far of |exp/log|. -This returns\etype{\Ff} the numerator corresponding to the internal -representation of a fraction, with positive powers of ten converted into zeroes -of this numerator: % -% -\leftedline{|\xintNumerator - {178000/25600000[17]}|\dtt{=\xintNumerator {178000/25600000[17]}}} -% -\leftedline{|\xintNumerator {312.289001/20198.27}|% - \dtt{=\xintNumerator {312.289001/20198.27}}} -% -\leftedline{|\xintNumerator {178000e-3/256e5}|\dtt{=\xintNumerator - {178000e-3/256e5}}} % -% -\leftedline{|\xintNumerator - {178.000/25600000}|\dtt{=\xintNumerator {178.000/25600000}}} As shown by -the examples, no simplification of the input is done. For a result uniquely -associated to the value of the fraction first apply \csa{xintIrr}. +The maximal allowed argument is $99999999$, but already $100000!$ currently +takes, for \dtt{16} digits of precision, a few seconds on my laptop (it +returns \dtt{2.824229407960348e456573}). -\subsection{\csbh{xintDenominator}}\label{xintDenominator} +The |factorial| function is available in \csbxint{floatexpr}: +\begin{everbatim*} +\xintthefloatexpr factorial(1000)\relax % same as 1000! +\end{everbatim*} -This returns\etype{\Ff} the denominator corresponding to the internal -representation of the fraction:% -% -\footnote{recall that the |[]| construct excludes - presence of a decimal point.} -% -\leftedline{|\xintDenominator - {178000/25600000[17]}|\dtt{=\xintDenominator {178000/25600000[17]}}} -% -\leftedline{|\xintDenominator {312.289001/20198.27}|% - \dtt{=\xintDenominator {312.289001/20198.27}}} -% -\leftedline{|\xintDenominator {178000e-3/256e5}|\dtt{=\xintDenominator - {178000e-3/256e5}}} % -% -\leftedline{|\xintDenominator - {178.000/25600000}|\dtt{=\xintDenominator {178.000/25600000}}} As shown -by the examples, no simplification of the input is done. The denominator looks -wrong in the last example, but the numerator was tacitly multiplied by $1000$ -through the removal of the decimal point. For a result uniquely associated to -the value of the fraction first apply \csa{xintIrr}. +\subsection{\csbh{xintFloatBinomial}}\label{xintFloatBinomial} -\subsection{\csbh{xintRawWithZeros}}\label{xintRawWithZeros} +\csa{xintFloatBinomial}|[P]{x}{y}|\etype{{\upshape[\numx]}\Numf\Numf} computes +binomial coefficients with either \csa{xinttheDigits} or |P| digits of +precision. -This macro `prints'\etype{\Ff} the -fraction |f| (after its parsing and expansion) in |A/B| form, with |A| -as returned by \csa{xintNumerator}|{f}| and |B| as returned by -\csa{xintDenominator}|{f}|. -% -\leftedline{|\xintRawWithZeros{\the\numexpr 571*987\relax.123e-10/\the\numexpr - -201+59\relax e-7}=|} -% -\leftedline{\dtt{\xintRawWithZeros{\the\numexpr - 571*987\relax.123e-10/\the\numexpr -201+59\relax e-7}}} +When |x<0| an out-of-range error is raised. Else (this was changed in |1.2h|, +see \autoref{xintiiBinomial}), if |y<0| or if |x binomial (9999.,5000.); +% 3008 +% 0.795895131768 10 % -\leftedline{|\xintREZ - {178000/25600000[17]}|\dtt{=\xintREZ {178000/25600000[17]}}} +% > Digits:=32; +% Digits := 32 % -\leftedline{|\xintREZ {1780000000000e30/2560000000000e15}|\dtt{=\xintREZ - {1780000000000e30/2560000000000e15}}} As shown by the example, it does not -otherwise simplify the fraction. +% > binomial (9999.,5000.); +% 3008 +% 0.795895131768 10 +% apparemment le binomial de Maple ne sait pas calculer avec plus de +% précision! +% et son dernier chiffre est faux! Pourtant GAMMA(9999.) fonctionne. Sauf si +% je n'ai pas compris quelque chose il me semble donc que le binomial de Maple +% est bogué...binomial(100.,50.); marche lui et binomial(4999.,2000.); aussi, +% bon clairement on a un bug de Maple ! oui binomial(8999.,5000.); ainsi que +% binomial(10999.,5000.); fonctionnent avec Digits:=32 mais **pas** +% binomial(9999.,5000.)... binomial(10000.,5000.); et binomial(9998.,5000.); +% sont OK. Est-ce qu'on gagne quelque chose pour un bug report ? +% > binomial(9999.,5000.); +% 3008 +% 0.795895131768 10 +% > binomial(10000.,5000.); +% 3009 +% 0.1591790263532438948337597273641521 10 +% > binomial(9998.,5000.); +% 3008 +% 0.3979077671466477799149739359402922 10 +% en plus je lui demande 32 chiffres et il m'en sort 34. + +The |binomial| function is available in \csbxint{floatexpr}: +\begin{everbatim*} +\xintthefloatexpr binomial(3000,1500)\relax +\end{everbatim*} + +The computation is based on the formula |(x-y+1)...x/y!| (here one arranges +|y<=x-y| naturally). + + +\subsection{\csbh{xintFloatPFactorial}}\label{xintFloatPFactorial} + +\csa{xintFloatPFactorial}|[P]{x}{y}|\etype{{\upshape[\numx]}\Numf\Numf} +computes the product |(x+1)...y|. + +The inputs |x| and |y| must evaluate to non-negative integers less in absolute +value than $10^8$. For |x=y| the product is considered empty hence the +returned value is |1|. + +It was a bit unfortunate with |1.2f| that the code deliberately raised an +error if the condition |0<=x<=y<10^8| was violated. See +\autoref{xintiiPFactorial} for the now prevailing rules.\CHANGED{1.2h} + +But only for the range |0<=x<=y<10^8| is it to be considered that the +behaviour is fixed and will not change in the future. + +The exact theoretical value differs from the calculated one |Y| by an absolute +error strictly less than |0.6 ulp(Y)|. + +The |pfactorial| function is available in \csbxint{floatexpr}: +\begin{everbatim*} +\xintthefloatexpr pfactorial(2500,5000)\relax +\end{everbatim*} + +\xintDigits:=16; \subsection{\csbh{xintFrac}}\label{xintFrac} @@ -11058,8 +10629,8 @@ denominator is omitted when it has value one, the number being separated from the power of ten by a |\cdot|. |$\xintFrac {178.000/25600000}$| gives $\xintFrac {178.000/25600000}$, |$\xintFrac {178.000/1}$| gives $\xintFrac {178.000/1}$, |$\xintFrac {3.5/5.7}$| gives $\xintFrac {3.5/5.7}$, and |$\xintFrac {\xintNum - {\xintiiFac{10}/|\allowbreak|\xintiSqr{\xintiiFac {5}}}}$| gives $\xintFrac -{\xintNum {\xintiiFac{10}/\xintiSqr{\xintiiFac {5}}}}$. As shown by the examples, + {\xintiiFac{10}/|\allowbreak|\xintiiSqr{\xintiiFac {5}}}}$| gives $\xintFrac +{\xintNum {\xintiiFac{10}/\xintiiSqr{\xintiiFac {5}}}}$. As shown by the examples, simplification of the input (apart from removing the decimal points and moving the minus sign to the numerator) is not done automatically and must be the result of macros such as |\xintIrr|, |\xintREZ|, or |\xintNum| (for fractions @@ -11069,11 +10640,10 @@ being in fact integers.) This is as \csbxint{Frac}\etype{\Ff} except that a negative fraction has the -sign put in front, not in the numerator. % -% -\leftedline{|\[\xintFrac - {-355/113}=\xintSignedFrac {-355/113}\]|} -\[\xintFrac {-355/113}=\xintSignedFrac {-355/113}\] +sign put in front, not in the numerator. +\begin{everbatim*} +\[\xintFrac{-355/113}=\xintSignedFrac {-355/113}\] +\end{everbatim*} \subsection{\csbh{xintFwOver}}\label{xintFwOver} @@ -11082,4218 +10652,4663 @@ primitive is used for the fraction (in case the denominator is not one; and a pair of braces contains the |A\over B| part). |$\xintFwOver {178.000/25600000}$| gives $\xintFwOver {178.000/25600000}$, |$\xintFwOver {178.000/1}$| gives $\xintFwOver {178.000/1}$, |$\xintFwOver {3.5/5.7}$| gives $\xintFwOver -{3.5/5.7}$, and |$\xintFwOver {\xintNum {\xintiiFac{10}/\xintiSqr{\xintiiFac - {5}}}}$| gives $\xintFwOver {\xintNum {\xintiiFac{10}/\xintiSqr{\xintiiFac +{3.5/5.7}$, and |$\xintFwOver {\xintNum {\xintiiFac{10}/\xintiiSqr{\xintiiFac + {5}}}}$| gives $\xintFwOver {\xintNum {\xintiiFac{10}/\xintiiSqr{\xintiiFac {5}}}}$. \subsection{\csbh{xintSignedFwOver}}\label{xintSignedFwOver} - This is as \csbxint{FwOver}\etype{\Ff} except that a negative fraction has the -sign put in front, not in the numerator. % -% -\leftedline{|\[\xintFwOver - {-355/113}=\xintSignedFwOver {-355/113}\]|} -\[\xintFwOver {-355/113}=\xintSignedFwOver {-355/113}\] - -\subsection{\csbh{xintIrr}}\label{xintIrr} +sign put in front, not in the numerator. +\begin{everbatim*} +\[\xintFwOver{-355/113}=\xintSignedFwOver {-355/113}\] +\end{everbatim*} -This puts the fraction\etype{\Ff} into its unique irreducible form: -% -\leftedline{|\xintIrr {178.256/256.178}|% - \dtt{=\xintIrr {178.256/256.178}}${}=\xintFrac{\xintIrr - {178.256/256.178}[0]}$} -% -Note that the current implementation does not cleverly first factor powers of 2 -and 5, so input such as |\xintIrr {2/3[100]}| will make \xintfracname do the -Euclidean division of |2|\raisebox{.5ex}{|.|}|10^{100}| by |3|, which is a bit -stupid. +\subsection{\csbh{xintLen}}\label{xintLenFrac} -Starting with release |1.08|, \csa{xintIrr} does not remove the trailing |/1| -when the output is an integer. This was deemed better for various (stupid?) -reasons and thus the output format is now \emph{always} |A/B| with |B>0|. Use -\csbxint{PRaw} on top of \csa{xintIrr} if it is needed to get rid of a possible -trailing |/1|. For display in math mode, use rather |\xintFrac{\xintIrr {f}}| or -|\xintFwOver{\xintIrr {f}}|. +The original \csbxint{Len} macro\etype{\Ff} is extended to accept a fraction +on input: the length of |A/B[n]| is the length of |A| plus the length of |B| +plus the absolute value of |n| and minus one (an integer input as |N| is +internally represented in a form equivalent to |N/1[0]| so the minus one means +that the extended \csa{xintLen} behaves the same as the original for +integers). +\begin{everbatim*} +\xintLen{201710/298219}=\xintLen{201710}+\xintLen{298219}-1\newline +\xintLen{1234/1}=\xintLen{1234}=\xintLen{1234[0]}=\xintiLen{1234}\newline +\xintLen{-1e3/5.425} (\xintRaw {-1e3/5.425})\par +\end{everbatim*} +The length is computed on the |A/B[n]| which would have been returned by +\csbxint{Raw}, as illustrated by the last example above. -\subsection{\csbh{xintJrr}}\label{xintJrr} +|\xintLen| is only for use with such (scientific) numbers or fractions. See +also \csbxint{NthElt} from \xinttoolsname. See also \csbxint{Length} (which +however does not expand its argument) from \xintkernelname for counting more +general tokens (or rather braced items). -This also puts the fraction\etype{\Ff} into its unique irreducible form: -% -\leftedline{|\xintJrr {178.256/256.178}|% - \dtt{=\xintJrr {178.256/256.178}}} -% -This is faster than \csa{xintIrr} for fractions having some big common -factor in the numerator and the denominator.\par -{\centering |\xintJrr {\xintiPow{\xintiiFac {15}}{3}/\xintiiPrd -{{\xintiiFac{10}}{\xintiiFac{30}}{\xintiiFac{5}}}}|\dtt{=% - \xintJrr {\xintiPow{\xintiiFac {15}}{3}/\xintiiPrd -{{\xintiiFac{10}}{\xintiiFac{30}}{\xintiiFac{5}}}}}\par} But to notice the -difference one would need computations with much bigger numbers than in this -example. -Starting with release |1.08|, \csa{xintJrr} does not remove the trailing |/1| -when the output is an integer. +\clearpage -\subsection{\csbh{xintTrunc}}\label{xintTrunc} +\section{Macros of the \xintexprname package}% +\label{sec:expr} -\csa{xintTrunc}|{x}{f}|\etype{\numx\Ff} returns the integral part, a dot, and -then the first |x| digits of the decimal expansion of the fraction |f|, except -when the fraction is (or evaluates to) zero, then it simply prints \dtt{0} -(with no dot). +\localtableofcontents -\begin{framed} - The argument |x| must be non-negative, the behavior is currently undefined - when |x<0| and will provoke errors. -\end{framed} +The \xintexprname package was first released with version |1.07| +(|2013/05/25|) of the \xintname bundle. It was substantially enhanced with +release |1.1| from |2014/10/28|. -Except when the input is (or evaluates to) exactly zero, the output contains -exactly |x| digits after the decimal mark, thus the output may be -\dtt{0.00...0} or \dtt{-0.00...0}, indicating that the original fraction was -positive, respectively negative. +Release |1.2| removed a limitation to numbers of at most $5000$ digits, and +there is now a float variant of the factorial. Also the ``pseudo-functions'' +|qint|, |qfrac|, |qfloat| (|'q'| for quick), were added to handle very big +inputs and avoid scanning it digit per digit. -\begin{framed} - \textbf{Warning:} \emph{it is not yet decided is this behavior is - definitive.} +The package loads automatically \xintfracname and \xinttoolsname (it is now +the only arithmetic package from the \xintname bundle which loads +\xinttoolsname). +\begin{itemize} +\item for using the |gcd| and |lcm| functions, it is necessary to load package + \xintgcdname. +\begin{everbatim*} +\xinttheexpr lcm (2^5*7*13^10*17^5,2^3*13^15*19^3,7^3*13*23^2)\relax +\end{everbatim*} +\item for allowing hexadecimal numbers (uppercase letters) on input, it is necessary + to load package \xintbinhexname. + \begin{everbatim*} +\xinttheexpr "A*"B*"C*"D*"D*"F, "FF.FF, reduce("FF.FFF + 16^-3)\relax +\end{everbatim*} +\end{itemize} - Currently \xintfracname has no notion of a positive zero or a negative zero. - Hence transitivity of \csbxint{Trunc} is broken for the case where the first - truncation gives on output \dtt{0.00...0} or \dtt{-0.00...0}: a second - truncation to less digits will then output \dtt{0}, whereas if it had been - applied directly to the initial input it would have produced \dtt{0.00...0} - or respectively \dtt{-0.00...0} (with less zeros). +Please refer to \autoref{sec:xintexprsyntax} for a more detailed description +of the syntax elements for expressions. - If \xintfracname distinguished zero, positive zero, and - negative zero it would be possible to maintain transitivity. +\subsection{The \csbh{xintexpr} expressions} +\label{xintexpr} +\label{xinttheexpr} +\label{thexintexpr} +\label{xintthe} - The problem would also be fixed, even without distinguishing a negative zero - on input, if \csbxint{Trunc} always produced \dtt{0.00...0} (with no sign) - when the mathematical result is zero, discarding the information on original - input being positive, zero, or negative. +An \xintexprname{}ession is a construct +\csbxint{expr}\meta{expandable\_expression}|\relax|\etype{x} where the +expandable expression is read and completely expanded from left to right. - I have multiple times hesitated about what to do and must postpone again - final decision. -\end{framed} -% -\leftedline{|\xintTrunc - {16}{-803.2028/20905.298}|\dtt{=\xintTrunc {16}{-803.2028/20905.298}}} -% -\leftedline{|\xintTrunc {20}{-803.2028/20905.298}|\dtt{=\xintTrunc - {20}{-803.2028/20905.298}}} -% -\leftedline{|\xintTrunc {10}{\xintPow {-11}{-11}}|\dtt{=\xintTrunc - {10}{\xintPow {-11}{-11}}}} -% -\leftedline{|\xintTrunc {12}{\xintPow {-11}{-11}}|\dtt{=\xintTrunc - {12}{\xintPow {-11}{-11}}}} -% -\leftedline{|\xintTrunc {12}{\xintAdd {-1/3}{3/9}}|\dtt{=\xintTrunc - {12}{\xintAdd {-1/3}{3/9}}}} The digits printed are exact up to and -including the last one. +An |\xintexpr...\relax| \emph{must} end in a |\relax| (which will be absorbed). +Like a |\numexpr| expression, it is not printable as is, nor can it be directly +employed as argument to the other package macros. For this one must use one +of the three equivalent forms: +\begin{itemize} +\item \csb{thexintexpr}\meta{expandable\_expression}|\relax|\etype{x}, or +\item \csb{xinttheexpr}\meta{expandable\_expression}|\relax|\etype{x}, or +\item \csb{xintthe}|\xintexpr|\meta{expandable\_expression}|\relax|.\etype{x} +\end{itemize} -The macro is more efficient since |1.2i| in the case where the |{f}| argument -is already a decimal number, and not a general fraction, as it avoids doing -then a division by a possibly big power of ten, replacing it by use of -\csbxint{DecSplit}. +The computations are done \emph{exactly}, and with no simplification of the +result. See \csbxint{floatexpr} for a similar parser which rounds each +operation inside the expression to \csbxint{theDigits} digits of precision. -\subsection{\csbh{xintiTrunc}}\label{xintiTrunc} +As an alternative and equivalent syntax to +\begin{everbatim} +\xintexpr round(, D)\relax +\end{everbatim} +there is\footnote{For truncation rather than rounding, one uses +|\xintexpr trunc(, D)\relax|.} +\begin{everbatim} +\xintiexpr [D] \relax +\end{everbatim} +The parameter |D| must be zero or positive.\footnote{|D=0| + corresponds to using |round()| not |round(,0)| which + would leave a trailing dot. Same for |trunc|. There is also function |float| + for floating point rounding to \csbxint{theDigits} or the given number of + significant digits as second argument.} Perhaps some future version will +give a meaning to using a negative |D|.\footnote{Thanks to KT for this + suggestion. Sorry for the delay in implementing it... matter of formatting + the output and corresponding choice of user interface are still in need of + some additional thinking.} -\csa{xintiTrunc}|{x}{f}|\etype{\numx\Ff} returns the integer equal to |10^x| -times what \csa{xintTrunc}|{x}{f}| would produce. -% -\leftedline{|\xintiTrunc - {16}{-803.2028/20905.298}|\dtt{=\xintiTrunc {16}{-803.2028/20905.298}}} -% -\leftedline{|\xintiTrunc {10}{\xintPow {-11}{-11}}|\dtt{=\xintiTrunc - {10}{\xintPow {-11}{-11}}}} -% -\leftedline{|\xintiTrunc {12}{\xintPow {-11}{-11}}|\dtt{=\xintiTrunc - {12}{\xintPow {-11}{-11}}}} -% -The difference between \csa{xintTrunc}|{0}{f}| and \csa{xintiTrunc}|{0}{f}| is -that the latter never has the decimal mark always present in the former except -for |f=0|. And \csa{xintTrunc}|{0}{-0.5}| returns ``\dtt{\xintTrunc - 0{-0.5}}'' whereas \csa{xintiTrunc}|{0}{-0.5}| simply returns -``\dtt{\xintiTrunc 0{-0.5}}''. +\begin{itemize} +\item the expression may contain arbitrarily many levels of nested parenthesized + sub-expressions, +\item the expression may contain explicitely or from a macro expansion a + sub-expression |\xintexpr...\relax|, which itself may contain a + sub-expressions etc\dots +\item to let sub-contents evaluate as a sub-unit it should thus be either + \begin{enumerate} + \item parenthesized, + \item or a sub-expression |\xintexpr...\relax|. + \end{enumerate} + \item to use an expression as argument to the other package macros, + or more generally to macros which expand their arguments, one must use the + |\xinttheexpr...\relax| or |\xintthe\xintexpr...\relax| forms. + \item similarly, + printing the result itself must be done with these forms. + \item one should not use |\xinttheexpr...\relax| as a sub-constituent of an + |\xintexpr...\relax| but only the + |\xintexpr...\relax| form which is more efficient in this context. + \item each \xintexprname{}ession, whether prefixed or not with |\xintthe|, is + completely expandable and obtains its result in two expansion steps. +\end{itemize} -\subsection{\csbh{xintTTrunc}}\label{xintTTrunc} +See \autoref{sec:xintexprsyntax} for the primary information on built-in +operators and functions. This section now adds some complementary information. + -\csa{xintTTrunc}|{f}|\etype{\Ff} truncates to an integer (truncation towards -zero). This is the same as |\xintiTrunc {0}{f}| and as \csbxint{Num}. +\begin{itemize}[parsep=0pt, labelwidth=\leftmarginii, + itemindent=0pt, listparindent=\leftmarginiii, leftmargin=\leftmarginii] +\item An expression is built the standard way with opening and closing + parentheses, infix operators, and (big) numbers, with possibly a fractional + part, and/or scientific notation (except for \csbxint{iiexpr} which only + admits big integers). All variants work with comma separated expressions. On + output each comma will be followed by a space. A decimal number must have + digits either before or after the decimal mark. -\subsection{\csbh{xintXTrunc}}\label{xintXTrunc} +\item As everything gets expanded, the characters |.|, |+|, |-|, |*|, |/|, |^|, + |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, |=|, |(|, |)|, |"|, |]|, |[|, |@| + and the comma |,| should not (if used in the expression) be active. For + example, the French language in |Babel| system, for pdf\LaTeX, activates |!|, + |?|, |;| and |:|. Turn off the activity before the expressions. + Alternatively the macro \csbxint{exprSafeCatcodes} resets all + characters potentially needed by \csbxint{expr} to their standard catcodes + and \csbxint{exprRestoreCatcodes} restores the status prevailing at the time + of the previous \csa{xintexprSafeCatcodes}. -\csa{xintXTrunc}|{x}{f}|\retype{\numx\Ff} is similar to \csbxint{Trunc} with -the following important differences: -\begin{itemize}[nosep] -\item it is completely expandable but not -\fexpan dable, as is indicated by the hollow star in the margin, -\item hence it can not be used as argument to the other package macros, but as - it \fexpan ds its |{f}| argument, it accepts arguments expressed with other - \xintfracname macros, -\item it requires |x>0|, -\item contrarily to \csbxint{Trunc} the number of digits on output is not - limited to about \dtt{19950} and may go well beyond \dtt{100000} (this is - mainly useful for outputting a decimal expansion to a file), -\item when the mathematical result is zero, it always prints it as - \dtt{0.00...0} or \dtt{-0.00...0} with |x| zeros after the decimal mark. -\end{itemize} +\item Count registers and |\numexpr|-essions are accepted (LaTeX{}'s counters + can be inserted using |\value|) natively without |\the| or |\number| as + prefix. Also dimen registers and control sequences, skip registers and + control sequences (\LaTeX{}'s lengths), |\dimexpr|-essions, + |\glueexpr|-essions are automatically unpacked using |\number|, discarding + the stretch and shrink components and giving the dimension value in |sp| + units ($1/65536$th of a \TeX{} point). Furthermore, tacit multiplication is + implied, when the (count or dimen or glue) register or variable, or the + (|\numexpr| or |\dimexpr| or |\glueexpr|) expression is immediately prefixed + by a (decimal) number. See \autoref{ssec:tacit multiplication} for the complete rules + of tacit multiplication.\IMPORTANT -\textbf{Warning:} -transitivity is broken too (see discussion of \csbxint{Trunc}), due to the -sign in the last item. Hence \emph{the definitive policy is yet to be fixed.} +\item With a macro |\x| defined like this: + % + \leftedline{|\def\x {\xintexpr \a + \b \relax}| or |\edef\x {\xintexpr + \a+\b\relax}|} + % + one may then do |\xintthe\x|, either for printing the result on the page or + to use it in some other macros expanding their arguments. The |\edef| does + the computation immediately but keeps it in an internal private format. + Naturally, the |\edef| is only possible if |\a| and |\b| are already + defined. With both approaches the |\x| can be inserted in other expressions, + as for example (assuming naturally as we use an |\edef| that in the + `yet-to-be computed' case the |\a| and |\b| now have some suitable meaning): + % + \leftedline {|\edef\y {\xintexpr \x^3\relax}|} -Transitivity is here in the sense of using a first |\edef| and then a second -one, because it is not possible to nest \csb{xintXTrunc} directly as argument -to itself. Besides, although the number of digits on output isn't limited, -nevertheless |x| should be less than about |19970| when the number of digits -of the input (assuming it is expressed as a decimal number) is even bigger: -|\xintXTrunc{30000}{\Z}| after |\edef\Z{\xintXTrunc{60000}{1/66049}| raises an -error in contrast with a direct |\xintXTrunc{30000}{1/66049}|. But -|\xintXTrunc{30000}{123.456789}| works, because here the number of digits -originally present is smaller than what is asked for, thus the routine only -has to add trailing zeros, and this has no limitation (apart from \TeX\ main -memory). +\item There is also \csbxint{boolexpr}| ... \relax| and + \csbxint{theboolexpr}| ... \relax|. Same as |\xintexpr| with the final + result converted to $1$ if it is not zero. See also + \csbxint{ifboolexpr} (\autoref{xintifboolexpr}) and the + \hyperlink{builtinfunc-bool}{|bool|} and \hyperlink{builtinfunc-togl}{|togl|} functions + in \autoref{sec:expr}. Here is an example: +\catcode`| 12 % +\begin{everbatim*} +\xintNewBoolExpr \AssertionA[3]{ #1 && (#2||#3) } +\xintNewBoolExpr \AssertionB[3]{ #1 || (#2&) } +\xintNewBoolExpr \AssertionC[3]{ xor(#1,#2,#3) } +{\centering\normalcolor\xintFor #1 in {0,1} \do {% + \xintFor #2 in {0,1} \do {% + \xintFor #3 in {0,1} \do {% + #1 AND (#2 OR #3) is \textcolor[named]{OrangeRed}{\AssertionA {#1}{#2}{#3}}\hfil + #1 OR (#2 AND #3) is \textcolor[named]{OrangeRed}{\AssertionB {#1}{#2}{#3}}\hfil + #1 XOR #2 XOR #3 is \textcolor[named]{OrangeRed}{\AssertionC {#1}{#2}{#3}}\\}}}} +\end{everbatim*}\catcode`| 13 + This example used for efficiency \csbxint{NewBoolExpr}. See also the + \autoref{xintNewExpr}. -\csbxint{XTrunc} will expand fully in an |\edef| or a |\write| (|\message|, -|\wlog|, \dots) or in an \csbxint{expr}-ession, or as list argument to -\csbxint{For*}. +\item There is \csbxint{floatexpr}| ... \relax| where the algebra is done + in floating point approximation (also for each intermediate result). Use the + syntax |\xintDigits:=N;| to set the precision. Default: $16$ digits. + % + \leftedline{|\xintthefloatexpr 2^100000\relax:| \dtt{\xintthefloatexpr + 2^100000\relax }} + % + The square-root operation can be used in |\xintexpr|, it is computed + as a float with the precision set by |\xintDigits| or by the optional + second argument: + % +\begin{everbatim*} +\xinttheexpr sqrt(2,60)\relax\newline +Here the [60] is to avoid truncation to |\xinttheDigits| of precision on output.\newline +\printnumber{\xintthefloatexpr [60] sqrt(2,60)\relax} +\end{everbatim*} + Floats are quickly indispensable when using the power function , as exact + results will easily have hundreds, if not thousands, of digits. + % +\begin{everbatim*} +\xintDigits:=48;\xintthefloatexpr 2^100000\relax +\end{everbatim*} -Here is an example session where the -user checks that the decimal expansion of $1/66049=1/257^2$ has the maximal -period length $257*256=65792$ (this period length must be a divisor of -$\phi(66049)$ and to check it is the maximal one it is enough to show that -neither $32896$ nor $256$ are periods.) + Only integer and (in |\xintfloatexpr...\relax|) half-integer exponents are + allowed. -\begingroup\small -\everb|@ -$ rlwrap etex -jobname worksheet-66049 -This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016) (preloaded format=etex) - restricted \write18 enabled. -**xintfrac.sty -entering extended mode -(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintfrac.sty -(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xint.sty -(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintcore.sty -(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xintkernel.sty)))) -*% we load xinttools for \xintKeep, etc... \xintXTrunc itself has no more +\item if one uses \emph{macros} within |\xintexpr..\relax| one should + obviously take into account that the parser will \emph{not} see the macro + arguments, hence once cannot use the syntax there, except if the arguments + are themselves wrapped as |\xinttheexpr...\relax| and assuming the macro + \fexpan ds these arguments. +\end{itemize} -*% any dependency on xinttools.sty since 1.2i -*\input xinttools.sty -(/usr/local/texlive/2016/texmf-dist/tex/generic/xint/xinttools.sty) -*\def\m#1;{\message{#1}} +\subsection{\texorpdfstring{\texttt{\protect\string\numexpr}}{\textbackslash + numexpr} or \texorpdfstring{\texttt{\protect\string\dimexpr}}{\textbackslash + dimexpr} expressions, count and dimension registers and variables} +\label{ssec:countinexpr} -*\m \the\numexpr 257*257\relax; -66049 -*\m \the\numexpr 257*256\relax; -65792 -*% Thus 1/66049 will have a period length dividing 65792. +Count registers, count control sequences, dimen registers, dimen control +sequences (like |\parindent|), skips and skip control sequences, |\numexpr|, +|\dimexpr|, |\glueexpr|, |\fontdimen| can be inserted directly, they will be +unpacked using |\number| which gives the internal value in terms of scaled +points for the dimensional variables: $1$\,|pt|${}=65536$\,|sp| (stretch and +shrink components are thus discarded). -*% Let us first check it is indeed periodical. +Tacit multiplication (see \autoref{ssec:tacit multiplication}) is implied, +when a number or decimal number prefixes such a register or control sequence. +\LaTeX{} lengths are skip control sequences and \LaTeX{} counters should be +inserted using |\value|. -*\edef\Z{\xintXTrunc{66000}{1/66049}} +Release |1.2| of the |\xintexpr| parser also recognizes and prefixes with +|\number| the |\ht|, |\dp|, and |\wd| \TeX{} primitives as well as the +|\fontcharht|, |\fontcharwd|, |\fontchardp| and |\fontcharic| \eTeX{} +primitives. -*% Let's display the first decimal digits. +In the case of numbered registers like |\count255| or |\dimen0| (or |\ht0|), +the resulting digits will be re-parsed, so for example |\count255 0| is like +|100| if |\the\count255| would give |10|. The same happens with inputs such +as |\fontdimen6\font|. And |\numexpr 35+52\relax| will be exactly as if |87| +as been encountered by the parser, thus more digits may follow: |\numexpr +35+52\relax 000| is like |87000|. If a new |\numexpr| follows, it is treated +as what would happen when |\xintexpr| scans a number and finds a non-digit: it +does a tacit multiplication. +\begin{everbatim*} +\xinttheexpr \numexpr 351+877\relax\numexpr 1000-125\relax\relax{} is the same +as \xinttheexpr 1228*875\relax. +\end{everbatim*} -*\m \xintXTrunc{208}{\Z}; +Control sequences however (such as |\parindent|) are picked up as a whole by +|\xintexpr|, and the numbers they define cannot be extended extra digits, a +syntax error is raised if the parser finds digits rather than a legal +operation after such a control sequence. -0.00001514027464458205271843631243470756559523989765174340262532362337052794137 -6856576178291874214598252812306015231116292449545034746930309315810988811337037 -6538630410755651107511090251177156353616254598858423 -*% let's now fetch the trailing digits +A token list variable must be prefixed by |\the|, it will not be unpacked +automatically (the parser will actually try |\number|, and thus fail). Do not +use |\the| but only |\number| with a dimen or skip, as the |\xintexpr| parser +doesn't understand |pt| and its presence is a syntax error. To use a dimension +expressed in terms of points or other \TeX{} recognized units, incorporate it in +|\dimexpr...\relax|. -*\m \xintKeep{65792-66000}{\Z};% 208 trailing digits +Regarding how dimensional expressions are converted by \TeX{} into scaled points +see also \autoref{sec:Dimensions}. -0000151402746445820527184363124347075655952398976517434026253236233705279413768 -5657617829187421459825281230601523111629244954503474693030931581098881133703765 -38630410755651107511090251177156353616254598858423 -*% yes they match! we now check that 65792/2 and 65792/257=256 aren't periods. +\subsection{Catcodes and spaces} -*\m \xintXTrunc{256}{\Z}; +Active characters may (and will) break the functioning of \csbxint{expr}. +Inside an expression one may prefix, for example a |:| with |\string|. Or, for +a more radical way, there is \csbxint{exprSafeCatcodes}. This is a +non-expandable step as it changes catcodes. -0.00001514027464458205271843631243470756559523989765174340262532362337052794137 -6856576178291874214598252812306015231116292449545034746930309315810988811337037 -6538630410755651107511090251177156353616254598858423291798513225029902042423049 -554118911717058547442 -*\m \xintXTrunc{256+256}{\Z}; +\subsubsection{\csbh{xintexprSafeCatcodes}} +\label{xintexprSafeCatcodes} -0.00001514027464458205271843631243470756559523989765174340262532362337052794137 -6856576178291874214598252812306015231116292449545034746930309315810988811337037 -6538630410755651107511090251177156353616254598858423291798513225029902042423049 -5541189117170585474420505987978621932201850141561567926842192917379521264515738 -3154930430438008145467758785144362518736089872670290239064936637950612424109373 -3440324607488379839210283274538600130206361943405653378552286938485064119063119 -8049932625777831609865402958409665551333 -*% now with 65792/2=32896. Problem: we can't do \xintXTrunc{32896+100}{\Z} +This macro sets the catcodes of the relevant characters to safe values. This +is used internally by \csbxint{NewExpr} (restoring the catcodes on exit), +hence \csa{xintNewExpr} does not have to be protected against active +characters. -*% but only direct \xintXTrunc{32896+100}{1/66049}. Anyway we want to nest it +Attention however that if the whole +\begin{everbatim} +\xintNewExpr \foo [N] {} +\end{everbatim} +has been fetched as a macro argument, it will be too late then for +\csa{xintNewExpr} to sanitize the catcodes of the (active) characters within +the expression. -*% hence let's do it all with (slower) \xintKeep, \xintKeepUnbraced. +\subsubsection{\csbh{xintexprRestoreCatcodes}} +\label{xintexprRestoreCatcodes} -*\m \xintKeep {-100}{\xintKeepUnbraced{2+65792/2+100}{\Z}}; +Restores the catcodes to the earlier state. -9999848597253554179472815636875652924344047601023482565973746763766294720586231 -434238217081257854017 -*% This confirms 32896 isn't a period length. +\bigskip -*% To conclude let's write the 66000 digits to the log. +Spaces inside an |\xinttheexpr...\relax| should mostly be +innocuous (except inside macro arguments). -*\wlog{\Z} +|\xintexpr| and |\xinttheexpr| are for the most part agnostic regarding +catcodes: (unbraced) digits, binary operators, minus and plus signs as +prefixes, dot as decimal mark, parentheses, may be indifferently of catcode +letter or other or subscript or superscript, ..., it doesn't matter.% +% +\footnote{Furthermore, although \csbxint{expr} uses \csa{string}, it is + escape-char agnostic. It should work with any \csa{escapechar} setting + including -1.} -*% We want always more digits: +The characters |+|, |-|, |*|, |/|, |^|, |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, +|=|, |(|, |)|, |"|, |[|, |]|, |;|, the dot and the comma should not be active if +in the expression, as everything is expanded along the way. If one of them is +active, it should be prefixed with |\string|. -*\wlog{\xintXTrunc{150000}{1/66049}} +The exclamation mark |!| should have its standard catcode: with catcode letter +it is used internally and hence will confuse the parsers if it comes from the +expression. -*\bye -| -\endgroup % $ à cause de fontification de AUCTeX. +Digits, slash, square brackets, minus sign, in the output from an +|\xinttheexpr| are all of catcode 12. For |\xintthefloatexpr| the `e' in the +output has its standard catcode ``letter''. -The acute observer will have noticed that there is something funny when one -compares the first digits with those after the middle-period: -\begin{everbatim} -0000151402746445820527184363124347075655952398976517434026253236233705279413768... -9999848597253554179472815636875652924344047601023482565973746763766294720586231... -\end{everbatim} -Mathematical exercise: can you explain why the two indeed add to |9999...9999|? +A macro with arguments will expand and grab its arguments before the +parser may get a chance to see them, so the situation with catcodes and spaces +is not the same within such macro arguments. -You can try your hands at this simpler one: -\begin{everbatim*} -1/49=\xintTrunc{42+5}{1/49}...\newline -\xintTrim{2}{\xintTrunc{21}{1/49}}\newline -\xintKeep{-21}{\xintTrunc{42}{1/49}} -\end{everbatim*} -This was again an example of the type |1/N| with |N| the square of a prime. -One can also find counter-examples within this class: |1/31^2| and |1/37^2| -have an odd period length (|465| and respectively |111|) hence they can not -exhibit the symmetry. -\begin{framed} - Mathematical challenge: prove generally that if the period length of the - decimal expansion of |1/p^r| (with |p| a prime distinct from |2| and |5| and - |r| a positive exponent) is even, then the above symmetry applies. -\end{framed} +\subsection{Expandability, \csh{xinteval}} +As is the case with all other package macros |\xintexpr| \fexpan ds (in two +steps) to its final (non-printable) result; and |\xinttheexpr| \fexpan ds (in +two steps) to the chain of digits (and possibly minus sign |-|, decimal mark +|.|, fraction slash |/|, scientific |e|, square brackets |[|, |]|) representing +the result. -Releases earlier than |1.2i| created a dependency of \xintfracname on -\xinttoolsname only for this macro, this dependency does not exist anymore. +Starting with |1.09j|, an |\xintexpr..\relax| can be inserted without +|\xintthe| prefix inside an |\edef|, or a |\write|. It expands to a private +more compact representation (five tokens) than |\xinttheexpr| or +|\xintthe\xintexpr|. +The material between |\xintexpr| and |\relax| should contain only expandable +material. -\subsection{\csbh{xintRound}}\label{xintRound} +The once expanded |\xintexpr| is |\romannumeral0\xinteval|. And there is +similarly |\xintieval|, |\xintiieval|, and |\xintfloateval|. For the other +cases one can use |\romannumeral-`0| as prefix. For an example of expandable +algorithms making use of chains of |\xinteval|-uations connected via +|\expandafter| see \autoref{ssec:fibonacci}. +An expression can only be legally finished by a |\relax| token, which +will be absorbed. -\csa{xintRound}|{x}{f}|\etype{\numx\Ff} returns the start of the decimal -expansion of the fraction |f|, rounded to |x| digits precision after the decimal -point. The argument |x| should be non-negative. Only when |f| evaluates exactly -to zero does \csa{xintRound} return |0| without decimal point. When |f| is not -zero, its sign is given in the output, also when the digits printed are all -zero. % -% -\leftedline{|\xintRound {16}{-803.2028/20905.298}|\dtt{=\xintRound - {16}{-803.2028/20905.298}}} -% -\leftedline{|\xintRound {20}{-803.2028/20905.298}|\dtt{=\xintRound - {20}{-803.2028/20905.298}}} -% -\leftedline{|\xintRound {10}{\xintPow {-11}{-11}}|\dtt{=\xintRound - {10}{\xintPow {-11}{-11}}}} -% -\leftedline{|\xintRound {12}{\xintPow {-11}{-11}}|\dtt{=\xintRound - {12}{\xintPow {-11}{-11}}}} -% -\leftedline{|\xintRound {12}{\xintAdd {-1/3}{3/9}}|\dtt{=\xintRound - {12}{\xintAdd {-1/3}{3/9}}}} The identity |\xintRound {x}{-f}=-\xintRound -{x}{f}| holds. And regarding $(-11)^{-11}$ here is some more of its expansion: -% -\leftedline{\dtt{\xintTrunc {50}{\xintPow {-11}{-11}}\dots}} +It is quite possible to nest expressions among themselves; for example, if one +needs inside an |\xintiiexpr...\relax| to do some computations with fractions, +rounding the final result to an integer, one just has to insert +|\xintiexpr...\relax|. The functioning of the infix operators will not be in +the least affected from the fact that the surrounding ``environment'' is the +|\xintiiexpr| one. -\subsection{\csbh{xintiRound}}\label{xintiRound} +\subsection{Memory considerations} +The parser creates an undefined control sequence for each intermediate +computation evaluation: addition, subtraction, etc\dots Thus, a moderately sized +expression might create 10, or 20 such control sequences. On my \TeX{} +installation, the memory available for such things is of circa \np{200000} +multi-letter control words. So this means that a document containing hundreds, +perhaps even thousands of expressions will compile with no problem. -\csa{xintiRound}|{x}{f}|\etype{\numx\Ff} returns the integer equal to |10^x| -times what \csa{xintRound}|{x}{f}| would return. % -% -\leftedline{|\xintiRound - {16}{-803.2028/20905.298}|\dtt{=\xintiRound {16}{-803.2028/20905.298}}} +Besides the hash table, also \TeX{} main memory is impacted. Thus, if +\xintexprname is used for computing plots% % -\leftedline{|\xintiRound {10}{\xintPow {-11}{-11}}|\dtt{=\xintiRound - {10}{\xintPow {-11}{-11}}}} +\footnote{this is not very probable as so far \xintname does not include + a mathematical library with floating point calculations, but provides + only the basic operations of algebra.}% % -Differences between \csa{xintRound}|{0}{f}| and \csa{xintiRound}|{0}{f}|: the -former cannot be used inside integer-only macros, and the latter removes the -decimal point, and never returns |-0| (and removes all superfluous leading -zeroes.) - -\subsection{\csbh{xintFloor}, \csbh{xintiFloor}} -\label{xintFloor}\label{xintiFloor} +, this may cause a problem. In my testing and with current |TL2015| memory +settings, I ran into problems after doing about \emph{ten thousand} +evaluations (for example |(#1+#2)*#3-#1*#3-#2*#3)|) each with number having +\emph{hundreds} of digits. Typical error message can be: +\begin{everbatim} +./testaleatoires.tex:243: TeX capacity exceeded, sorry [pool size=6134970]. + ...19140037877484848545931233090884903 +\end{everbatim} -|\xintFloor {f}|\etype{\Ff} returns the largest relative integer |N| with -|N|${}\leqslant{}$|f|. % -% -\leftedline{|\xintFloor {-2.13}|\dtt{=\xintFloor - {-2.13}}, |\xintFloor {-2}|\dtt{=\xintFloor {-2}}, |\xintFloor - {2.13}|\dtt{=\xintFloor {2.13}} -% -} - -|\xintiFloor {f}|\etype{\Ff} does the same but without adding the -|/1[0]|. -% -\leftedline{|\xintiFloor {-2.13}|\dtt{=\xintiFloor - {-2.13}}, |\xintiFloor {-2}|\dtt{=\xintiFloor {-2}}, |\xintiFloor - {2.13}|\dtt{=\xintiFloor {2.13}}} - -\subsection{\csbh{xintCeil}, \csbh{xintiCeil}} -\label{xintCeil}\label{xintiCeil} - -|\xintCeil {f}|\etype{\Ff} returns the smallest relative integer |N| with -|N|${}>{}$|f|. % -% -\leftedline{|\xintCeil {-2.13}|\dtt{=\xintCeil {-2.13}}, - |\xintCeil {-2}|\dtt{=\xintCeil {-2}}, |\xintCeil - {2.13}|\dtt{=\xintCeil {2.13}} +There is a (partial) solution.% % -} - -|\xintiCeil {f}|\etype{\Ff} does the same but without adding the -|/1[0]|. +\footnote{which convinced me that I could stick with the parser + implementation despite its potential impact on the hash-table and + other parts of \TeX{}'s memory.} +A document can possibly do tens of thousands of evaluations only if some +identical formulae are being used repeatedly, with varying arguments (from +previous computations possibly) or coming from data being fetched from a file. +Most certainly, there will be a a few dozens formulae at most, but they will +be used again and again with varying inputs. -\subsection{\csbh{xintTFrac}}\label{xintTFrac} +With the \csbxint{NewExpr} macro, it is possible to convert once and +for all an expression containing parameters into an expandable macro +with parameters. Only this initial definition of this macro actually +activates the \csbxint{expr} parser and will (very moderately) impact +the hash-table: once this unique parsing is done, a macro with +parameters is produced which is built-up recursively from the +\csbxint{Add}, \csbxint{Mul}, etc... macros, exactly as it would be +necessary to do without the facilities of the \xintexprname package. -\csa{xintTFrac}|{f}|\etype{\Ff} returns the fractional part, -|f=trunc(f)+frac(f)|. Thus if |f<0|, then |-10| one has -|0<= frac(f)<1|. The |T| stands for `Trunc', and there should exist also -similar macros associated respectively with `Round', `Floor', and `Ceil', each -type of rounding to an integer deserving arguably to be associated with a -fractional ``modulo''. By sheer laziness, the package currently implements -only the ``modulo'' associated with `Truncation'. Other types of modulo may be -obtained more cumbersomely via a combination of the rounding with a subsequent -subtraction from |f|. +Notice that since |1.2c| the \csbxint{deffunc} construct allows an alternative +to \csa{xintNewExpr} whose syntax uses arbitrary letters rather than macro +parameters |#1|, |#2|, ..., |#9|. The declared function must still be used +inside an expression, but its use will need only as many |\csname|'s as were +needed for the function arguments plus one more for encapsulating the function +result. -Notice that the result is filtered through \csbxint{REZ}, and will thus be of -the form |A/B[N]|, where neither |A| nor |B| has trailing zeros. But the -output fraction is not reduced to smallest terms.\MyMarginNote{\noindent - Do\-cu\-men\-ta\-tion updated.} +\subsection{The \csbh{xintNewExpr} macro} +\label{xintNewExpr} -The function call in expressions (\csbxint{expr}, \csbxint{floatexpr}) is -|frac|. Inside |\xintexpr..\relax|, the function |frac| is mapped to -\csa{xintTFrac}. Inside |\xintfloatexpr..\relax|, |frac| first applies -\csa{xintTFrac} to its argument (which may be an exact fraction with more -digits than the floating point precision) and only in a second stage makes the -conversion to a floating point number with the precision as set by |\xintDigits| -(default is \dtt{16}). +The macro is used as: % -\leftedline{|\xintTFrac {1235/97}|\dtt{=\xintTFrac {1235/97}}\quad - |\xintTFrac {-1235/97}|\dtt{=\xintTFrac {-1235/97}}} +\leftedline{|\xintNewExpr{\myformula}[n]|\marg{stuff}, where} +\begin{itemize} +\item \meta{stuff} will be inserted inside |\xinttheexpr . . . \relax|, +\item |n| is an integer between zero and nine, inclusive, which is the number + of parameters of |\myformula|, +\item the placeholders |#1|, |#2|, ..., |#n| are used inside \meta{stuff} in + their usual r\^ole,% % -\leftedline{|\xintTFrac {1235.973}|\dtt{=\xintTFrac {1235.973}}\quad - |\xintTFrac {-1235.973}|\dtt{=\xintTFrac {-1235.973}}} +\catcode`# 12 +\footnote{if \csa{xintNewExpr} is used inside a macro, + the |#|'s must be doubled as usual.} + \footnote{the |#|'s will in pratice have their usual + catcode, but category code other |#|'s are accepted too.} +\catcode`# 6 % -\leftedline{|\xintTFrac {1.122435727e5}|% - \dtt{=\xintTFrac {1.122435727e5}}} - -\subsection{\csbh{xintE}}\label{xintE} +\item the |[n]| is \emph{mandatory}, even for |n=0|.% +\footnote{there is some use for \csa{xintNewExpr}|[0]| compared to an + \csa{edef} as \csa{xintNewExpr} has some built-in catcode protection.} +\item the macro |\myformula| is defined without checking if it already exists, + \LaTeX{} users might prefer to do first |\newcommand*\myformula {}| to get a + reasonable error message in case |\myformula| already exists, +\item the protection against active characters is done automatically (as long + as the whole thing has not already been fetched as a macro argument and + the catcodes correspondingly already frozen). +\end{itemize} -|\xintE {f}{x}|\etype{\Ff\numx} multiplies the fraction |f| by $10^x$. The -\emph{second} argument |x| must obey the \TeX{} bounds. Example: -% -\leftedline{|\count 255 123456789 \xintE {10}{\count 255}|\dtt{->\count - 255 123456789 \xintE {10}{\count 255}}} Be careful that for obvious reasons -such gigantic numbers should not be given to \csbxint{Num}, or added to -something with a widely different order of magnitude, as the package always -works to get the \emph{exact} result. There is \emph{no problem} using them for -\emph{float} operations:% -% -\leftedline{|\xintFloatAdd - {1e1234567890}{1}|\dtt{=\xintFloatAdd {1e1234567890}{1}}} +It will be a completely expandable macro entirely built-up using |\xintAdd|, +|\xintSub|, |\xintMul|, |\xintDiv|, |\xintPow|, etc\dots as corresponds to the +expression written with the infix operators. +Macros created by |\xintNewExpr| can thus be nested. -\subsection{\csbh{xintAdd}}\label{xintAdd} +\begin{everbatim*} + \xintNewFloatExpr \FA [2]{(#1+#2)^10} + \xintNewFloatExpr \FB [2]{sqrt(#1*#2)} +\begin{enumerate}[nosep] + \item \FA {5}{5} + \item \FB {30}{10} + \item \FA {\FB {30}{10}}{\FB {40}{20}} +\end{enumerate} +\end{everbatim*} -Computes the addition\etype{\Ff\Ff} of two fractions. To keep for integers the -integer format on output use \csbxint{iAdd}. + The use of \csbxint{NewExpr} circumvents the impact of the |\xintexpr| + parsers on \TeX's memory: it is useful if one has a formula which has to be + re-evaluated thousands of times with distinct inputs each with dozens, or + hundreds of digits. -Checks if one denominator is a multiple of the other. Else multiplies the -denominators. + A ``formula'' created by |\xintNewExpr| is thus a macro whose parameters are + given to a possibly very complicated combination of the various macros of + \xintname and \xintfracname. Consequently, one can not use at all any infix + notation in the inputs, but only the formats which are recognized by the + \xintfracname macros. -\subsection{\csbh{xintSub}}\label{xintSub} + This is thus quite different from a macro with parameters which one would + have defined via a simple |\def| or |\newcommand| as for example: + % + \leftedline{|\newcommand\myformula [1]{\xinttheexpr (#1)^3\relax}|} + % + Such a macro |\myformula|, if it was used tens of thousands of times with + various big inputs would end up populating large parts of \TeX's memory. It + would thus be better for such use cases to go for: + % + \leftedline{|\xintNewExpr\myformula [1]{#1^3\relax}|} + % + Here naturally the situation is over-simplified and it would be even simpler + to go directly for the use of the macro |\xintPow| or |\xintPower|. -Computes the difference\etype{\Ff\Ff} of two fractions (|\xintSub{F}{G}| -computes |F-G|). To keep for integers the integer format on output use -\csbxint{iSub}. -Checks if one denominator is a multiple of the other. Else multiplies the -denominators. +|\xintNewExpr| tries to do as many evaluations as are possible at the time the +macro parameters are still parameters. Let's see a few examples. For this I +will use |\meaning| which reveals the contents of a macro. -\subsection{\csbh{xintMul}}\label{xintMul} +\begin{enumerate} +\item the examples use a mysterious |\fixmeaning| macro, which is there to get + in the display |\romannumeral`^^@| rather than the frankly cabalistic + |\romannumeral``| which made the admiration of the readers of the + documentation dated |2015/10/19| (the second |`| stood for an ascii code + zero token as per |T1| encoded |newtxtt| font). Thus the true meaning is + ``fixed'' to display something different which is how the macro could be + defined in a standard |tex| source file (modulo, as one can see in example, + the use of characters such as |:| as letters in control sequence names). + Prior to |1.2a|, the meaning would have started with a more mundane + |\romannumeral-`0|, but I decided at the time of releasing |1.2a| to imitate + the serious guys and switch for the more hacky yet |\romannumeral`^^@| + everywhere in the source code (not only in the macros produced by + \csbxint{NewExpr}), or to be more precise for an equivalent as the caret has + catcode letter in \xintname's source code, and I had to use another + character. +\item the meaning reveals the use of some private macros from the \xintname + bundle, which should not be directly used. If the things look a bit + complicated, it is because they have to cater for many possibilities. +\item the point of showing the meaning is also to see what has already been + evaluated in the construction of the macros. +\end{enumerate} -Computes the product\etype{\Ff\Ff} of two fractions. To keep for integers the -integer format on output use \csbxint{iMul}. +\begin{everbatim*} +\xintNewIIExpr\FA [1]{13*25*78*#1+2826*292}\fixmeaning\FA +\end{everbatim*} +\smallskip -No reduction attempted. +\begin{everbatim*} +\xintNewIExpr\FA [2]{(3/5*9/7*13/11*#1-#2)*3^7} +\printnumber{\fixmeaning\FA} +\end{everbatim*} -\subsection{\csbh{xintSqr}}\label{xintSqr} +\smallskip -Computes the square\etype{\Ff} of one fraction. To maintain for integer input -an integer format on output use \csbxint{iSqr}. +\begin{everbatim*} +% an example with optional parameter +\xintNewIExpr\FA [3]{[24] (#1+#2)/(#1-#2)^#3} +\printnumber{\fixmeaning\FA} +\end{everbatim*} -\subsection{\csbh{xintDiv}}\label{xintDiv} +\smallskip -Computes the quotient \etype{\Ff\Ff} of two fractions. -(|\xintDiv{F}{G}| computes |F/G|). To keep for integers the integer format on -output use \csbxint{iMul}. +\begin{everbatim*} +\xintNewFloatExpr\FA [2]{[12] 3.1415^3*#1-#2^5} +\printnumber{\fixmeaning\FA} +\end{everbatim*} -No reduction attempted. +\smallskip -\subsection{\csbh{xintDivTrunc}, \csbh{xintDivRound}} -\label{xintDivTrunc} -\label{xintDivRound} +\begin{everbatim*} +\xintNewExpr\DET[9]{ #1*#5*#9+#2*#6*#7+#3*#4*#8-#1*#6*#8-#2*#4*#9-#3*#5*#7 } +\printnumber{\fixmeaning\DET} +\end{everbatim*} -Computes the quotient \etype{\Ff\Ff} of the two arguments then either -truncates or rounds to an integer. +\unless\ifxetex +Notice that since |1.2c| it is perhaps more natural to do: +\begin{everbatim*} +% attention that «ad» would try to use non-existent variable "ad" +\xintdeffunc det2(a, b, c, d) := a*d - b*c ; +% This is impossible because we must use single letters : +% \xintdeffunc det3(x_11, x_12, x_13, x_21, x_22, x_23, x_31, x_32, x_33) := +% x_11 * det2 (x_22, x_23, x_32, x_33) + x_21 * det2 (x_32, x_33, x_12, x_13) +% + x_31 * det2 (x_12, x_13, x_22, x_23); +\xintdeffunc det3 (a, b, c, u, v, w, x, y, z) := a*v*z + b*w*x + c*u*y - b*u*z - c*v*x - a*w*y ; +\xinttheexpr det3 (1,1,1,1,2,4,1,3,9), det3 (1,10,100,1,100,10000,1,1000,1000000), + 90*900*990, reduce(det3 (1,1/2,1/3,1/2,1/3,1/4,1/3,1/4,1/5))\relax\newline +\xintdeffunc det3bis (a, b, c, u, v, w, x, y, z) := + a*det2(v,w,y,z)-b*det2(u,w,x,z)+c*det2(u,v,x,y); +\pdfsetrandomseed 123456789 % xint.pdf should be predictable from xint.dtx ! +\xinttheexpr subs(subs(subs(subs(subs(subs(subs(subs(subs( +% we use one extra pair of parentheses to hide the commas from the subs + (a, b, c, u, v, w, x, y, z, det3 (a, b, c, u, v, w, x, y, z), + det3bis (a, b, c, u, v, w, x, y, z)), + z=\pdfuniformdeviate 1000), y=\pdfuniformdeviate 1000), x=\pdfuniformdeviate 1000), + w=\pdfuniformdeviate 1000), v=\pdfuniformdeviate 1000), u=\pdfuniformdeviate 1000), + c=\pdfuniformdeviate 1000), b=\pdfuniformdeviate 1000), a=\pdfuniformdeviate 1000)\relax +\end{everbatim*} -\subsection{\csbh{xintiFac}}\label{xintiFac} -With \xintfracname loaded |\xintiFac|\etype{\Numf} is extended to allow a -fraction |f| as input, it will be truncated first to an integer |n| before the -evaluation of the factorial. The output is an integer in strict format, -without a trailing |/1[0]|. See the \hyperref[xintiiFac]{\csa{xintiiFac} doc} -for more info. +The last computation with its nine nested |subs| can be coded more +economically (and efficiently), exploiting the fact that a single dummy +variable can expand to a whole list: +\begin{everbatim*} +\pdfsetrandomseed 123456789 % xint.pdf should be predictable from xint.dtx ! +\xinttheexpr subs((L, det3(L), det3bis(L)), % parentheses used to hide the inner commas + L=\pdfuniformdeviate 1000, \pdfuniformdeviate 1000, \pdfuniformdeviate 1000, + \pdfuniformdeviate 1000, \pdfuniformdeviate 1000, \pdfuniformdeviate 1000, + \pdfuniformdeviate 1000, \pdfuniformdeviate 1000, \pdfuniformdeviate 1000)\relax +\end{everbatim*} +\fi % de pas de xetex -\subsection{\csbh{xintiBinomial}}\label{xintiBinomial} +With |\xintverbosetrue| we will find in the log: -With \xintfracname loaded |\xintiBinomial|\etype{\Numf\Numf} is extended to -allow fractional inputs which will be truncated to integers before the -evaluation of the binomial. The output is an integer in strict format, without -a trailing |/1[0]|. See the -\hyperref[xintiiBinomial]{\csa{xintiiBinomial} doc} for the current allowable -range. +\begin{everbatim} + Function det3 for \xintexpr parser associated to \XINT_expr_userfunc_det3 w +ith meaning macro:#1,#2,#3,#4,#5,#6,#7,#8,#9,->\xintSub {\xintSub {\xintSub {\x +intAdd {\xintAdd {\xintMul {\xintMul {#1}{#5}}{#9}}{\xintMul {\xintMul {#2}{#6} +}{#7}}}{\xintMul {\xintMul {#3}{#4}}{#8}}}{\xintMul {\xintMul {#2}{#4}}{#9}}}{\ +xintMul {\xintMul {#3}{#5}}{#7}}}{\xintMul {\xintMul {#1}{#6}}{#8}} +Package xintexpr Info: (on line 11) + Function det3bis for \xintexpr parser associated to \XINT_expr_userfunc_det +3bis with meaning macro:#1,#2,#3,#4,#5,#6,#7,#8,#9,->\xintAdd {\xintSub {\xintM +ul {#1}{\xintSub {\xintMul {#5}{#9}}{\xintMul {#6}{#8}}}}{\xintMul {#2}{\xintSu +b {\xintMul {#4}{#9}}{\xintMul {#6}{#7}}}}}{\xintMul {#3}{\xintSub {\xintMul {# +4}{#8}}{\xintMul {#5}{#7}}}} +\end{everbatim} -\subsection{\csbh{xintiPFactorial}}\label{xintiPFactorial} -% fait 2015/11/29 pour 1.2f. -With \xintfracname loaded |\xintiPFactorial|\etype{\Numf\Numf} is extended to -allow fractional inputs which will be truncated to integers before the -evaluation of the partial factorial. The output is an integer in strict -format, without a trailing |/1[0]|. See the -\hyperref[xintiiPFactorial]{\csa{xintiiPFactorial} doc} for more info. -\subsection{\csbh{xintPow}}\label{xintPow} +\medskip +Lists, including Python-like selectors, are compatible with +\csa{xintNewExpr}:% +% +\footnote{The |\empty| token is optional here, but it would + be needed in case of \csbxint{NewFloatExpr} or \csbxint{NewIExpr}.} +% +\begin{everbatim*} +\xintNewExpr\Foo[5]{\empty[#1..[#2]..#3][#4:#5]} +\begin{itemize}[nosep] +\item |\Foo{1}{3}{90}{20}{30}|->\Foo{1}{3}{90}{20}{30} +\item |\Foo{1}{3}{90}{-40}{-15}|->\Foo{1}{3}{90}{-40}{-15} +\item |\Foo{1.234}{-0.123}{-10}{3}{7}|->\Foo{1.234}{-0.123}{-10}{3}{7} +\end{itemize} +\fdef\test {\Foo {0}{10}{100}{3}{6}}\meaning\test +++ +\end{everbatim*} -\csa{xintPow}{|{f}{x}|}:\etype{\Ff\Numf} computes |f^x| with |f| a fraction and -|x| possibly also, but |x| will first get truncated to a (positive or negative) -integer. +In this last example the macro |\Foo| will not be able to handle an empty |#4| +or |#5|: this is only possible in an expression, because the parser identifies +|][:| or |:]| and handles them appropriately. During the construction of |\Foo| +the parser will find |][#4:| and not |][:|. -The output will now always be in the form |A/B[n]| (even when the exponent -vanishes: |\xintPow {2/3}{0}|\dtt{=\xintPow{2/3}{0}}). +\begin{framed} + The \csbxint{deffunc}, \csbxint{defiifunc}, \csbxint{deffloatfunc} + declarators added to \xintexprname since release |1.2c| are based on the + same underlying mechanism as \csa{xintNewExpr}, \csa{xintNewIIExpr}, ... The + discussion that follows applies to them too. +\end{framed} -The macro handling only integers is available as \csbxint{iPow}. Only -\csa{xintPow} accepts negative exponent, as this produces fractions. +\subsubsection {Conditional operators and \csbh{NewExpr}} +\label{sssec:cond} +The |?| and |??| conditional operators cannot be parsed by |\xintNewExpr| when +they contain macro parameters |#1|,\dots, |#9| within their scope. However +replacing them with the functions |if| and, respectively |ifsgn|, the parsing +should succeed. And the created macro will \emph{not evaluate the branches to + be skipped}, thus behaving exactly like |?| and |??| would have in the +|\xintexpr|. -Within an \csbxint{iiexpr}|..\relax| the infix operator |^| is mapped to -\csa{xintiiPow}; within an \csbxint{expr}-ession it is mapped to -\csa{xintPow}. +\begin{everbatim*} +\xintNewExpr\Formula [3]{ if((#1>#2) && (#2>#3), sqrt(#1-#2)*sqrt(#2-#3), #1^2+#3/#2) }% +\printnumber{\fixmeaning\Formula } +\end{everbatim*} +This formula (with its |\xintiiifNotZero|) will gobble the false branch without +evaluating it when used with given arguments. -\subsection{\csbh{xintSum}}\label{xintSum} +Remark: the meaning above reveals some of the private macros used by the +package. They are not for direct use. -This\etype{f{$\to$}{\lowast\Ff}} computes the sum of fractions. The output -will now always be in the form |A/B[n]|. The original, for big integers only -(in strict format), is available as \csa{xintiiSum}. +Another example \begin{everbatim*} -\xintSum {{1282/2196921}{-281710/291927}{4028/28612}} +\xintNewExpr\myformula[3]{ ifsgn(#1,#2/#3,#2-#3,#2*#3) }% +\fixmeaning\myformula \end{everbatim*} -No simplification attempted. +Again, this macro gobbles the false branches, as would have the operator |??| +inside an |\xintexpr|-ession. -\subsection{\csbh{xintPrd}}\label{xintPrd} +\subsubsection{External macros and \csbh{xintNewExpr}; the protect function} +\label{sssec:protect} -TThis\etype{f{$\to$}{\lowast\Ff}} computes the product of fractions. The output -will now always be in the form |A/B[n]|. The original, for big integers only -(in strict format), is available as \csa{xintiiPrd}. +For macros within such a created \xintname-formula macro, there +are two cases: +\begin{itemize} +\item the macro does not involve the numbered parameters in its arguments: it + may then be left as is, and will be evaluated once during the construction of + the formula, +\item it does involve at least one of the macro parameters as argument. Then: + \begin{snugframed} + the whole thing (macro + argument) should be |protect|-ed, not in the + \LaTeX{} sense (!), but in the following way: |protect(\macro {#1})|.\IMPORTANT + \end{snugframed} +\end{itemize} + +Here is a silly example illustrating the general principle: the macros here have +equivalent functional forms which are more convenient; but some of the more +obscure package macros of \xintname dealing with integers do not have functions +pre-defined to be in correspondance with them, use this mechanism could be +applied to them. \begin{everbatim*} -\xintPrd {{1282/2196921}{-281710/291927}{4028/28612}} +\xintNewExpr\formulaA[2]{protect(\xintRound{#1}{#2}) - protect(\xintTrunc{#1}{#2})}% +\printnumber{\fixmeaning\formulaA} + +\xintNewIIExpr\formulaB [3]{rem(#1,quo(protect(\the\numexpr #2\relax),#3))}% +\noindent\printnumber{\fixmeaning\formulaB } \end{everbatim*} -No simplification attempted. +Only macros involving the |#1|, |#2|, etc\dots should be protected in this +way; the |+|, |*|, etc\dots symbols, the functions from the \csbxint{expr} +syntax, none should ever be included in a protected string. -\subsection{\csbh{xintCmp}}\label{xintCmp} -This\etype{\Ff\Ff} compares two fractions |F| and |G| and produces -|-1|, |0|, or |1| according to |FG|. +\subsubsection{Limitations of \csbxint{NewExpr} and \csbxint{deffunc}} +\label{sssec:limitations} -For choosing branches according to the result of comparing |f| and |g|, see -\csbxint{ifCmp}. +\csa{xintNewExpr} will pre-evaluate everything as long as it does not contain +the macro parameters |#1|, |#2|, ... and the special measures to take when +these are inside branches to |?| and |??| (replace these operators by |if| and +|ifsgn|) or as arguments to macros external to \xintexprname (use |protect|) +were discussed in \autoref{sssec:cond} and \autoref{sssec:protect}. + +The main remaining limitation is that expressions with dummy variables are +compatible with \csa{xintNewExpr} only to the extent that the iterated-over +list of values does not depend on the macro parameters |#1|, |#2|, ... For +example, this works: +\begin{everbatim*} +\xintNewExpr \FA [2] {reduce(add((t+#1)/(t+#2), t=0..5))} +\FA {1}{1}, \FA {1}{2}, \FA {2}{3} +\end{everbatim*} +but the |5| can not be abstracted into a third argument |#3|. + +There are no restriction on using macro parameters |#1|, |#2|, ... with list +constructs. For example, this works: +\begin{everbatim*} +\xintNewIExpr \FB [3] {[4] `+`([1/3..[#1/3]..#2]*#3)} +\begin{itemize}[nosep] +\item \FB {1}{10/3}{100} % (1/3+2/3+...+10/3)*100 +\item \FB {5}{5}{20} % (1/3+6/3+11/3)*20 +\item \FB {3}{4}{1} % (1/3+4/3+7/3+10/3)*1 +\end{itemize} +\end{everbatim*} -\subsection{\csbh{xintIsOne}} +Some simple expressions with |add| or |mul| can be also expressed with |`+`| +and |`*`| and list operations. But there is no hope for |seq|, |iter|, etc... +if the |#1|, |#2|, ... are used inside the list argument: +|seq(x(x+#1)(x+#2),x=1..#3)| is currently not compatible with +\csa{xintNewExpr}. But |seq(x(x+#1)(x+#2), x=1..10)| has no problem. -This\etype{\Ff} returns |1| if the fraction is |1| and |0| if not. +All the preceeding applies identically for \csbxint{deffunc}, \csbxint{defiifunc}, +\csbxint{deffloatfunc} which share the same routines as \csa{xintNewExpr}, +\csa{xintNewIIExpr}, ..., replacing the |#1|, |#2|, ... in the discussion by +the letters used as function arguments. +There is a final syntax restriction which however applies only to +\csa{xintNewExpr} et. al., and not to \csa{xintdeffunc}, \csa{xintdefiifunc}, +\csa{xintdeffloatfunc} : it is possible to use sub-expressions only if they use +\csa{xintexpr}, those with \csa{xinttheexpr} are illegal. +\begin{everbatim*} +\xintNewExpr \FC [4] {#1+\xintexpr #2*#3\relax + #4} +\printnumber{\fixmeaning\FC} +\end{everbatim*}\newline +works, but already +\begin{everbatim} +\xintNewExpr \FD [1] {#1+\xinttheexpr 1\relax} +\end{everbatim} +doesn't. On the other hand +\begin{everbatim*} +\xintdeffunc FD(t) := t + \xinttheexpr 1\relax ; +\end{everbatim*} +and even \begin{everbatim*} -\xintIsOne {21921379213/21921379213} but \xintIsOne {1.00000000000000000000000000000001} +\xintdeffunc FE(t,u) := t + \xinttheexpr u\relax ; \end{everbatim*} +have no issue. Anyway, one should never use |\xinttheexpr| for sub-expressions +but only |\xintexpr|, so this restriction on the \csa{xintNewExpr} syntax +isn't really one. -\subsection{\csbh{xintGeq}}\label{xintGeq} +\subsection{The \csbh{xintNewFunction} macro} -This\etype{\Ff\Ff} compares the \emph{absolute values} of two -fractions.|\xintGeq{f}{g}| returns |1| if {\catcode`| 12 $|f|\geqslant|g|$} and |0| -if not. +See \autoref{xintNewFunction} for its documentation.\NewWith{1.2h} -May be used for expandably branching as: -\verb+\xintSgnFork{\xintGeq{f}{g}}{}{code for |f|<|g|}{code for - |f|+$\geqslant$\verb+|g|}+ +\subsection{\csbh{xintiexpr}, \csbh{xinttheiexpr}} +\label{xintiexpr}\label{xinttheiexpr}\label{thexintiexpr} -\subsection{\csbh{xintMax}}\label{xintMax} +Equivalent\etype{x} to doing |\xintexpr round(...)\relax| (more precisely, +|round| is applied to each one of the evaluated values, if the expression was +comma separated). Thus, only the \emph{final result value} is rounded to an +integer. Half integers are rounded towards $+\infty$ for positive numbers and +towards $-\infty$ for negative ones. -The maximum of two fractions.\etype{\Ff\Ff} But now |\xintMax {2}{3}| -returns \dtt{\xintMax {2}{3}}. The original, for use with (possibly big) -integers only with no need of normalization, is available as \csbxint{iiMax}: -|\xintiiMax {2}{3}=|\dtt{\xintiMax {2}{3}}.\etype{ff} +An optional parameter |d>0| within brackets, immediately after |\xintiexpr| +is allowed: it instructs the expression to do its final rounding to the +nearest value with that many digits after the decimal mark, \emph{i.e.}, +|\xintiexpr [d] \relax| is equivalent (in case of a single +expression) to |\xintexpr round(, d)\relax|. -There is also \csbxint{iMax}\etype{\Numf\Numf} which works with fractions but -first truncates them to integers. +|\xintiexpr [0] ...| is the same as |\xintiexpr ...|.\footnote{Incidentally + using |round(...,0)| in place of |round(...)| in |\xintexpr| would leave a + trailing dot in the produced value.} -\begin{everbatim*} -\xintMax {2.5}{7.2} but \xintiMax {2.5}{7.2} -\end{everbatim*} +If truncation rather than rounding is needed use (in case of a single +expression, naturally) |\xintexpr trunc(...)\relax| for truncation to an +integer or |\xintexpr trunc(...,d)\relax| for truncation to a decimal number +with |d>0| digits after the decimal mark. -\subsection{\csbh{xintMin}}\label{xintMin} +Perhaps in the future some meaning will be given to using negative value for +the optional parameter |d|.\footnote{Thanks to KT for this suggestion.} -The maximum of two fractions.\etype{\Ff\Ff} The original, for use with (possibly big) -integers only with no need of normalization, is available as \csbxint{iiMin}: -|\xintiiMin {2}{3}=|\dtt{\xintiMin {2}{3}}.\etype{ff} +|\thexintiexpr| is synonym to |\xinttheiexpr|.\NewWith{1.2h} -There is also \csbxint{iMin}\etype{\Numf\Numf} which works with fractions but first -truncates them to integers. +\subsection{\csbh{xintiiexpr}, \csbh{xinttheiiexpr}} +\label{xintiiexpr}\label{xinttheiiexpr}\label{thexintiiexpr} -\begin{everbatim*} -\xintMin {2.5}{7.2} but \xintiMin {2.5}{7.2} -\end{everbatim*} +This variant\etype{x} does not know fractions. It deals almost only with long +integers. Comma separated lists of expressions are allowed. -\subsection{\csbh{xintMaxof}}\label{xintMaxof} +\begin{framed} + It maps |/| to the \emph{rounded} quotient. The operator + |//| is, like in |\xintexpr...\relax|, mapped to \emph{truncated} division. + The euclidean quotient (which for positive operands is like the truncated + quotient) was, prior to release |1.1|, associated to |/|. The function + |quo(a,b)| can still be employed. +\end{framed} + +The \csbxint{iiexpr}-essions use the `ii' macros for addition, subtraction, +multiplication, power, square, sums, products, euclidean quotient and +remainder. + +The |round|, |trunc|, |floor|, |ceil| functions are still available, and are +about the only places where fractions can be used, but |/| within, if not +somehow hidden will be executed as integer rounded division. To avoid this one +can wrap the input in \dtt{qfrac}: this means however that none of the normal +expression parsing will be executed on the argument. + +To understand the illustrative examples, recall that |round| and |trunc| have +a second (non negative) optional argument. In a normal \csbxint{expr}-essions, +|round| and |trunc| are mapped to \csbxint{Round} and \csbxint{Trunc}, in +\csbxint{iiexpr}-essions, they are mapped to \csbxint{iRound} and +\csbxint{iTrunc}. -The maximum of any number of fractions, each within braces, and the whole -thing within braces. \etype{f{$\to$}{\lowast\Ff}} \begin{everbatim*} -\xintMaxof {{1.23}{1.2299}{1.2301}} and \xintMaxof {{-1.23}{-1.2299}{-1.2301}} +\xinttheiiexpr 5/3, round(5/3,3), trunc(5/3,3), trunc(\xintDiv {5}{3},3), +trunc(\xintRaw {5/3},3)\relax{} are problematic, but +% +\xinttheiiexpr 5/3, round(qfrac(5/3),3), trunc(qfrac(5/3),3), floor(qfrac(5/3)), +ceil(qfrac(5/3))\relax{} work! \end{everbatim*} -\subsection{\csbh{xintMinof}}\label{xintMinof} +On the other hand decimal numbers and scientific numbers can be used directly +as arguments to the |num|, |round|, or any function producing an integer. -The minimum of any number of fractions, each within braces, and the whole -thing within braces. \etype{f{$\to$}{\lowast\Ff}} +\begin{framed} + Scientific numbers will be + represented with as many zeroes as necessary, thus one does not want to + insert \dtt{num(1e100000)} for example in an \csa{xintiiexpr}ession ! +\end{framed} +% \begin{everbatim*} -\xintMinof {{1.23}{1.2299}{1.2301}} and \xintMinof {{-1.23}{-1.2299}{-1.2301}} +\xinttheiiexpr num(13.4567e3)+num(10000123e-3)\relax % should (num truncates) compute 13456+10000 \end{everbatim*} +% -\subsection{\csbh{xintAbs}}\label{xintAbs} +The |reduce| function is not available and will raise un error. The |frac| +function also. The |sqrt| function is mapped to \csbxint{iiSqrt} which gives +a truncated square root. The |sqrtr| function is mapped to \csbxint{iiSqrtR} +which gives a rounded square root. -The absolute value\etype{\Ff}. Note that |\xintAbs {-2}|\dtt{=\xintAbs {-2}} -whereas |\xintiAbs {-2}|\dtt{=\xintiAbs {-2}}. +One can use the Float macros if one is careful to use |num|, or |round| +etc\dots on their output. -\subsection{\csbh{xintSgn}}\label{xintSgn} +\begin{everbatim*} +\xinttheiiexpr \xintFloatSqrt [20]{2}, \xintFloatSqrt [20]{3}\relax % no operations -The sign of a fraction.\etype{\Ff} +\noindent The next example requires the |round|, and one could not put the |+| inside it: -\subsection{\csbh{xintOpp}}\label{xintOpp} +\xinttheiiexpr round(\xintFloatSqrt [20]{2},19)+round(\xintFloatSqrt [20]{3},19)\relax -The opposite of a fraction.\etype{\Ff} -Note that |\xintOpp {3}| now outputs \dtt{\xintOpp - {3}} whereas |\xintiOpp {3}| returns \dtt{\xintiOpp {3}}. +(the second argument of |round| and |trunc| tells how many digits from after the +decimal mark one should keep.) +\end{everbatim*} -\subsection{\csbh{xintDigits}, \csbh{xinttheDigits}} -\label{xintDigits} -\label{xinttheDigits} +The whole point of \csbxint{iiexpr} is to gain some speed in +\emph{integer-only} algorithms, and the above explanations related to how to +nevertheless use fractions therein are a bit peripheral. We observed +(2013/12/18) of the order of $30$\% speed gain when dealing with numbers with +circa one hundred digits (1.2: this info may be obsolete). -The syntax |\xintDigits := D;| (where spaces do not matter) assigns the -value of |D| to the number of digits to be used by floating point -operations. The default is |16|. The maximal value is |32767|. The macro -|\xinttheDigits|\etype{} serves to print the current value. -\subsection{\csbh{xintFloat}}\label{xintFloat} +|\thexintiiexpr| is synonym to |\xinttheiiexpr|.\NewWith{1.2h} +\subsection{\csbh{xintboolexpr}, + \csbh{xinttheboolexpr}} +\label{xintboolexpr}\label{xinttheboolexpr}\label{thexintboolexpr} -The macro |\xintFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} has an optional -argument |P| which replaces the current value of |\xinttheDigits|. The -fraction |f| is then printed in scientific notation with a rounding to |P| digits. - -That is, on output: the first digit is from |1| to |9|, it is possibly -prefixed by a minus sign and is followed by a dot and |P-1| digits, then a -lower case |e| and an exponent |N|. The trailing zeroes are not trimmed. -\begin{framed} - There is currently one exceptional case: the zero value, which gets output - as \dtt{\xintFloat{0}}. It is yet to be decided what the final policy will be. -\end{framed} +Equivalent\etype{x} to doing |\xintexpr ...\relax| and returning $1$ if the +result does not vanish, and $0$ is the result is zero. As |\xintexpr|, this +can be used on comma separated lists of expressions, and will return a +comma separated list of $0$'s and $1$'s. -Starting with |1.2k|,\NewWith{1.2k} when the input is a fraction |AeN/BeM| -the output always is the \emph{correct rounding} to |P| digits. Formerly, this -was guaranteed only when |A| and |B| had at most |P+2| digits, or when |B| was -|1| and |A| was arbitrary, but in other cases it was only guaranteed that the -difference between the original fraction and the rounding was at most -\dtt{0.6} unit in the last place (of the output), hence the output could -differ in the last digit (and earlier ones in case of chains of zeros or -nines) from the correct rounding. +|\thexintboolexpr| is synonym to |\xinttheboolexpr|.\NewWith{1.2h} -Also:\CHANGED{1.2k} for releases |1.2j| and earlier, in the special case when -|A/B| ended up being rounded up to the next power of ten, the output was with -a mantissa of the shape |10.0...0eN|. However, this worked only for |B=1| or -when both |A| and |B| had at most |P+2| digits, because the detection of the -rounding-up to next power of ten was done not on original |A/B| but on an -approximation |A'/B'|, and it could happen that |A'/B'| was itself being -rounded \emph{down} to a power of ten which however was a rounding \emph{up} -of original |A/B|. With the |1.2j| refactoring which achieves correct rounding -in all cases, it was decided not to add to the code the extra overhead of -detecting with 100\% fiability the rounding up to next power of ten (such -overhead would necessitate alterations of the algorithm and as a result we -would end up with a slightly less efficient one; it would make sense in a -model where inputs have their intrinsic precisions which is obeyed by the -implementation of the basic operations, but currently the design decision for -the floating point macros is that when the target precision is |P| the inputs -are rounded first to |P| digits before further processing.) +There is slight quirk in case it is used as a sub-expression: the boolean +expression needs at least one logic operation else the value is not +standardized to |1| or |0|, for example we get from \begin{everbatim*} -{\def\x{99999999999999994999999999999999/99999999999999999999999999999999}% -\xintFor #1 in {13, 14, 15, 16, 17, 18, 19, 47, 48, 49, 50, 79, 80, 81} -\do{#1: \xintFloat[#1]{\x}\xintifForLast{\par}{\newline}}}% -\end{everbatim*} -As an aside, which is illustrated by the above, rounding is not -transitive in the number of kept digits. +\xinttheexpr \xintboolexpr 1.23\relax\relax\newline +\end{everbatim*}which is to be compared with \begin{everbatim*} -{\def\x{137893789173289739179317/13890138013801398}% -\xintFor* #1 in {\xintSeq{4}{20}} -\do{#1: \xintFloat[#1]{\x}\newline}}% -\xintFloat{5/9999999999999999}\newline -\xintFloat[32]{5/9999999999999999}\newline -\xintFloat[48]{5/9999999999999999}\par +\xinttheboolexpr 1.23\relax \end{everbatim*} +A related issue existed with +|\xinttheexpr \xintiexpr 1.23\relax\relax|, which was fixed with |1.1| +release, and I decided back then not to add the needed overhead also to the +|\xintboolexpr| context, as one only needs to use |?(1.23)| for example or +involve the |1.23| in any logic operation like |1.23 'and' 3.45|, or involve +the |\xintboolexpr ..\relax | itself with any logical operation, contrarily to +the sub-|\xintiexpr| case where |\xinttheexpr 1+\xintiexpr 1.23\relax\relax| +did behave contrarily to expectations until |1.1|. -\subsection{\csbh{xintPFloat}}\label{xintPFloat} - -The macro |\xintPFloat [P]{f}|\etype{{\upshape[\numx]}\Ff} is like -\csbxint{Float} but ``pretty-prints'' the output. Its behaviour has changed -with release |1.2f|\IMPORTANT{}: there is only one simplification rule now -which is that decimal notation (with possibly needed extra zeros) is used in -place of scientific notation when the exponent would end up being between -\dtt{-5} and \dtt{5} inclusive. - -If the input vanishes the output will be \dtt{\xintPFloat{0}} with a a decimal -mark.% -% -\footnote{Currently there are no subnormal numbers, and no underflow - because the exponent is only limited by the maximal \TeX\ number; thus - underflow situations would manifest themselves via low-level arithmetic - overflow errors.} +\subsection{\csbh{xintfloatexpr}, + \csbh{xintthefloatexpr}} +\label{xintfloatexpr}\label{xintthefloatexpr}\label{thexintfloatexpr} -\csbxint{thefloatexpr} applies this macro to its output (or each of -its outputs, if comma separated). +\csbxint{floatexpr}|...\relax|\etype{x} is exactly like |\xintexpr...\relax| +but with the four binary operations and the power function are mapped to +\csa{xintFloatAdd}, \csa{xintFloatSub}, \csa{xintFloatMul}, \csa{xintFloatDiv} +and \csa{xintFloatPower}, respectively.\footnote{Since |1.2f| the \string^ + handles half-integer exponents, contrarily to \csa{xintFloatPower}.} -Currently trailing zeros are not trimmed. +The target precision for the computation is from the +current setting of |\xintDigits|. Comma separated lists of expressions are +allowed. -\begin{everbatim*} -\begingroup\def\test #1{#1${}\to{}$\xintPFloat{#1}}% -\string\xintDigits\ at \xinttheDigits -\begin{itemize}[nosep] -\item \test {0} -\item \test {1.23456789e-7} -\item \test {1.23456789e-6} -\item \test {1.23456789e-5} -\item \test {1.23456789e-4} -\item \test {1.23456789e-3} -\item \test {1.23456789e-2} -\item \test {1.23456789e-1} -\item \test {1.23456789e0} -\item \test {1.23456789e1} -\item \test {1.23456789e2} -\item \test {1.23456789e3} -\item \test {1.23456789e4} -\item \test {1.23456789e5} -\item \test {1.23456789e6} -\item \test {1.23456789e7} -\end{itemize} -\endgroup -\end{everbatim*} +An optional (positive) parameter within brackets is allowed: the final float +will have that many digits of precision. This is provided to get rid of +possibly irrelevant last digits, thus makes sense only if this parameter is +less than the |\xinttheDigits| precision. +Since |1.2f| all float operations first round their arguments; a parsed number +is not rounded prior to its use as operand to such a float operation. -\subsection{\csbh{xintFloatE}}\label{xintFloatE} +|\thexintfloatexpr| is synonym to |\xintthefloatexpr|.\NewWith{1.2h} -|\xintFloatE [P]{f}{x}|\etype{{\upshape[\numx]}\Ff\numx} multiplies the input -|f| by $10^x$, and -converts it to float format according to the optional first argument or current -value of |\xinttheDigits|. +|\xintDigits:=36;|\xintDigits:=36; +% +\leftedline{|\xintthefloatexpr + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax|} +% +\leftedline{\dtt{\xintthefloatexpr + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax}} +% 0.00564487459334466559166166079096852897 +% +\leftedline{|\xintthefloatexpr\xintexpr + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax\relax|} % -\leftedline{|\xintFloatE {1.23e37}{53}|\dtt{=\xintFloatE {1.23e37}{53}}} +\leftedline{\dtt{\xintthefloatexpr\xintexpr + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax\relax}} -\subsection{\csbh{xintFloatAdd}}\label{xintFloatAdd} +\xintDigits := 16; +The latter is the rounding of the exact result. The former one has +its last three digits wrong due to the cumulative effect of rounding errors +in the intermediate computations, as compared to exact evaluations. -|\xintFloatAdd [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| -and |g| with their float approximations |f'| and |g'| to |P| significant -places or to the precision from |\xintDigits|. It then produces -the sum |f'+g'|, correctly rounded to nearest with the same number of -significant places. -\subsection{\csbh{xintFloatSub}}\label{xintFloatSub} +I recall here from \autoref{ssec:floatingpoint} that with release |1.2f| the +float macros for addition, subtraction, multiplication and division round +their arguments first to |P| significant places with |P| the asked-for +precision of the output; and similarly the power macros and the +square root macro. This does not modify anything for computations with +arguments having at most |P| significant places already. -|\xintFloatSub [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| -and |g| with their float approximations |f'| and |g'| to |P| significant -places or to the precision from |\xintDigits|. It then produces -the difference |f'-g'| correctly rounded to nearest |P|-float. +\subsection{Using an expression parser within another one} +This was already illustrated before. In the following: +\begin{everbatim*} +\xintthefloatexpr \xintexpr add(1/i, i=1234..1243)\relax ^100\relax +\end{everbatim*}, +the inner sum is computed exactly. Then it will be rounded to |\xinttheDigits| +significant digits, and then its power will be evaluated as a float operation. +One should avoid the "|\xintthe|" parsers in inner positions as this induces +digit by digit parsing of the inner computation result by the outer parser. +Here is the same computation done with floats all the way: +\begin{everbatim*} +\xintthefloatexpr add(1/i, i=1234..1243)^100\relax +\end{everbatim*} -\subsection{\csbh{xintFloatMul}}\label{xintFloatMul} +Not surprisingly this differs from the previous one which was exact until +raising to the |100|th power. +The fact that the inner expression occurs inside a bigger one has nil +influence on its behaviour. There is the limitation though that the outputs +from \csbxint{expr} and \csbxint{floatexpr} can not be used directly in +\csbxint{theiiexpr} integer-only parser. But one can do: +\begin{everbatim*} +\xinttheiiexpr round(\xintfloatexpr 3.14^10\relax)\relax % or trunc +\end{everbatim*} -|\xintFloatMul [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| -and |g| with their float approximations |f'| and |g'| to |P| (or -|\xinttheDigits|) significant places. It then correctly rounds -the product |f'*g'| to nearest |P|-float. -See \autoref{ssec:floatingpoint} for more. +\subsection{The \csbh{xintthecoords} macro} +\label{xintthecoords} -\begin{framed} - It is obviously much needed that the author improves its algorithms to avoid - going through the exact |2P| or |2P-1| digits before - throwing to the waste-bin half of those digits ! +It converts a comma separated list into the format for list of coordinates as +expected by the |TikZ| |coordinates| syntax. The code had to work around the +problem that |TikZ| seemingly allows only a maximal number of about one +hundred expansion steps for the list to be entirely produced. Presumably to +catch an infinite loop. +\begin{everbatim*} +\begin{figure}[htbp] +\centering\begin{tikzpicture}[scale=10]\xintDigits:=8; + \clip (-1.1,-.25) rectangle (.3,.25); + \draw [blue] (-1.1,0)--(1,0); + \draw [blue] (0,-1)--(0,+1); + \draw [red] plot[smooth] coordinates {% + \xintthecoords % (converts what is next into (x1, y1) (x2, y2)... format) + \xintfloatexpr seq((x^2-1,mul(x-t,t=-1+[0..4]/2)),x=-1.2..[0.1]..+1.2) \relax }; +\end{tikzpicture} +\caption{Coordinates with \cs{xintthecoords}.} +\end{figure} +\end{everbatim*} - % \xintname initially was purely an \emph{exact} arbitrary precision - % arithmetic machine, and the introduction of floating point numbers was an - % after-thought. I got it working in release |1.07 (2013/05/25)| and never had - % time to come back to it. -\end{framed} +% Notice: if x goes no take exactly value 1 or -1, the origin appears slightly +% off the curve, not MY fault!!! -\subsection{\csbh{xintFloatDiv}}\label{xintFloatDiv} +\csbxint{thecoords} should be followed immediately by \csbxint{floatexpr} or +\csbxint{iexpr} or \csbxint{iiexpr}, but not |\xintthefloatexpr|, etc\dots +Besides, as |TikZ| will not understand the |A/B[N]| format which is used on +output by |\xintexpr|, |\xintexpr| is not really usable with |\xintthecoords| +for a |TikZ| picture, but one may use it on its own, and the reason for the +spaces in and between coordinate pairs is to allow if necessary to print on +the page for examination with about correct line-breaks. -|\xintFloatDiv [P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Ff} first replaces |f| -and |g| with their float approximations |f'| and |g'| to |P| (or -|\xinttheDigits|) significant places. It then correctly rounds -the fraction |f'/g'| to nearest |P|-float. +\begin{everbatim*} +\edef\x{\xintthecoords \xintexpr rrseq(1/2,1/3; @1+@2, x=1..20)\relax } +\meaning\x +++ +\end{everbatim*} -See \autoref{ssec:floatingpoint} for more. -Notice in the special situation with |f| and |g| integers that |\xintFloatDiv -[P]{f}{g}| will \emph{not necessarily} give the correct rounding of the -exact fraction |f/g|. Indeed the macro arguments are each first individually -rounded to |P| digits of precision. The correct syntax to get the correctly -rounded integer fraction |f/g| is \csbxint{Float}|[P]{f/g}|. +\subsection{\csbh{xintifboolexpr}}\label{xintifboolexpr} -\subsection{\csbh{xintFloatFac}}\label{xintFloatFac} +\csh{xintifboolexpr}|{}{YES}{NO}|\etype{xnn} does |\xinttheexpr +\relax| and then executes the |YES| or the |NO| branch depending on +whether the outcome was non-zero or zero. || can involve various |&| and +\verb+|+, parentheses, |all|, |any|, |xor|, the |bool| or |togl| operators, but +is not limited to them: the most general computation can be done, the test is on +whether the outcome of the computation vanishes or not. -\csa{xintFloatFac}|[P]{f}|\etype{{\upshape[\numx]}\Numf} returns the -factorial with either \csa{xinttheDigits} or |P| digits of precision. +Will not work on an expression composed of comma separated sub-expressions. -% je devrais vérifier mais j'ai écrit cela fin novembre 2015 début décembre je -% suppose que je savais ce que je disais. +\subsection{\csbh{xintifboolfloatexpr}}\label{xintifboolfloatexpr} +\csh{xintifboolfloatexpr}|{}{YES}{NO}|\etype{xnn} does |\xintthefloatexpr +\relax| and then executes the |YES| or the |NO| branch depending on +whether the outcome was non zero or zero. -The exact theoretical value differs from the calculated one |Y| by an absolute -error strictly less than |0.6 ulp(Y)|. +\subsection{\csbh{xintifbooliiexpr}}\label{xintifbooliiexpr} -\begin{everbatim*} -$1000!\approx{}$\xintFloatFac [30]{1000} -\end{everbatim*} -The computation proceeds via doing explicitely the product, as -the Stirling formula cannot be used for lack so far of |exp/log|. +\csh{xintifbooliiexpr}|{}{YES}{NO}|\etype{xnn} does |\xinttheiiexpr +\relax| and then executes the |YES| or the |NO| branch depending on +whether the outcome was non zero or zero. -The maximal allowed argument is $99999999$, but already $100000!$ currently -takes, for \dtt{16} digits of precision, a few seconds on my laptop (it -returns \dtt{2.824229407960348e456573}). +\subsection{\csbh{xintNewFloatExpr}}\label{xintNewFloatExpr} + +This is exactly like \csbxint{NewExpr} except that the created formulas are +set-up to use |\xintthefloatexpr|. The precision used for the computation will +be the one given by |\xinttheDigits| at the time of use of the created formulas. +However, the numbers hard-wired in the original expression will have been +evaluated with the then current setting for |\xintDigits|. -The |factorial| function is available in \csbxint{floatexpr}: \begin{everbatim*} -\xintthefloatexpr factorial(1000)\relax % same as 1000! -\end{everbatim*} +\xintNewFloatExpr \f [1] {sqrt(#1)} +\f {2} (with \xinttheDigits{} of precision). -\subsection{\csbh{xintFloatBinomial}}\label{xintFloatBinomial} +{\xintDigits := 32;\f {2} (with \xinttheDigits{} of precision).} -\csa{xintFloatBinomial}|[P]{x}{y}|\etype{{\upshape[\numx]}\Numf\Numf} computes -binomial coefficients with either \csa{xinttheDigits} or |P| digits of -precision. +\xintNewFloatExpr \f [1] {sqrt(#1)*sqrt(2)} +\f {2} (with \xinttheDigits {} of precision). -When |x<0| an out-of-range error is raised. Else (this was changed in |1.2h|, -see \autoref{xintiiBinomial}), if |y<0| or if |x binomial (9999.,5000.); -% 3008 -% 0.795895131768 10 -% -% > Digits:=32; -% Digits := 32 -% -% > binomial (9999.,5000.); -% 3008 -% 0.795895131768 10 -% apparemment le binomial de Maple ne sait pas calculer avec plus de -% précision! -% et son dernier chiffre est faux! Pourtant GAMMA(9999.) fonctionne. Sauf si -% je n'ai pas compris quelque chose il me semble donc que le binomial de Maple -% est bogué...binomial(100.,50.); marche lui et binomial(4999.,2000.); aussi, -% bon clairement on a un bug de Maple ! oui binomial(8999.,5000.); ainsi que -% binomial(10999.,5000.); fonctionnent avec Digits:=32 mais **pas** -% binomial(9999.,5000.)... binomial(10000.,5000.); et binomial(9998.,5000.); -% sont OK. Est-ce qu'on gagne quelque chose pour un bug report ? -% > binomial(9999.,5000.); -% 3008 -% 0.795895131768 10 -% > binomial(10000.,5000.); -% 3009 -% 0.1591790263532438948337597273641521 10 -% > binomial(9998.,5000.); -% 3008 -% 0.3979077671466477799149739359402922 10 -% en plus je lui demande 32 chiffres et il m'en sort 34. +Like \csbxint{NewExpr} but using |\xinttheiexpr|. -The |binomial| function is available in \csbxint{floatexpr}: -\begin{everbatim*} -\xintthefloatexpr binomial(3000,1500)\relax -\end{everbatim*} -The computation is based on the formula |(x-y+1)...x/y!| (here one arranges -|y<=x-y| naturally). +\subsection{\csbh{xintNewIIExpr}}\label{xintNewIIExpr} +Like \csbxint{NewExpr} but using |\xinttheiiexpr|. -\subsection{\csbh{xintFloatPFactorial}}\label{xintFloatPFactorial} +\subsection{\csbh{xintNewBoolExpr}}\label{xintNewBoolExpr} -\csa{xintFloatPFactorial}|[P]{x}{y}|\etype{{\upshape[\numx]}\Numf\Numf} -computes the product |(x+1)...y|. +Like \csbxint{NewExpr} but using |\xinttheboolexpr|. -The inputs |x| and |y| must evaluate to non-negative integers less in absolute -value than $10^8$. For |x=y| the product is considered empty hence the -returned value is |1|. +\xintDigits:= 16; -It was a bit unfortunate with |1.2f| that the code deliberately raised an -error if the condition |0<=x<=y<10^8| was violated. See -\autoref{xintiiPFactorial} for the now prevailing rules.\CHANGED{1.2h} +\subsection{Technicalities} -But only for the range |0<=x<=y<10^8| is it to be considered that the -behaviour is fixed and will not change in the future. +As already mentioned \csa{xintNewExpr}|\myformula[n]| does not check the prior +existence of a macro |\myformula|. And the number of parameters |n| given as +mandatory argument within square brackets should be (at least) equal +to the number of parameters in the expression. -The exact theoretical value differs from the calculated one |Y| by an absolute -error strictly less than |0.6 ulp(Y)|. +Obviously I should mention that \csa{xintNewExpr} itself can not be used in an +expansion-only context, as it creates a macro. -The |pfactorial| function is available in \csbxint{floatexpr}: +The |\escapechar| setting may be arbitrary when using |\xintexpr|. + +The format of the output of +|\xintexpr|\meta{stuff}|\relax| is a |!| (with catcode 11) followed by various things: \begin{everbatim*} -\xintthefloatexpr pfactorial(2500,5000)\relax +\edef\f {\xintexpr 1.23^10\relax }\meaning\f \end{everbatim*} -\subsection{\csbh{xintFloatPow}}\label{xintFloatPow} +\begin{framed} + Note that |\xintexpr| expands in an |\edef|, contrarily + to |\numexpr| which is non-expandable, if not prefixed by |\the|, |\number|, + or |\romannumeral| or in some other context where \TeX{} is building a number. See + \autoref{ssec:fibonacci} for some illustration. +\end{framed} -|\xintFloatPow [P]{f}{x}|\etype{{\upshape[\numx]}\Ff\numx} uses either the -optional argument |P| or in its absence the value of |\xinttheDigits|. It -computes a floating approximation to |f^x|. +I decided to put all intermediate results (from each evaluation of an infix +operators, or of a parenthesized subpart of the expression, or from application +of the minus as prefix, or of the exclamation sign as postfix, or any +encountered braced material) inside |\csname...\endcsname|, as this can be done +expandably and encapsulates an arbitrarily long fraction in a single token (left +with undefined meaning), thus providing tremendous relief to the programmer in +his/her expansion control. -The exponent |x| will be handed over to a |\numexpr|, hence count registers are -accepted on input for this |x|. And the absolute value \verb+|x|+ must obey the -\TeX{} bound. +\begin{framed} + As the |\xintexpr| computations corresponding to functions and infix + or postfix operators are done inside |\csname...\endcsname|, the + \fexpan dability could possibly be dropped and one could imagine + implementing the basic operations with expandable but not \fexpan + dable macros (as \csbxint{XTrunc}.) I have not investigated that + possibility. +\end{framed} -The argument |f| is first rounded to |P| significant places to give -|f'|. The output |Z| is such that the exact |f'^x| differs from -|Z| by an absolute error less than |0.52 ulp(Z)|. +Syntax errors in the input such as using a one-argument function with two +arguments will generate low-level \TeX{} processing unrecoverable errors, with +cryptic accompanying message. -% -\leftedline{|\xintFloatPow [8]{3.1415}{1234567890}|% - \dtt{=\xintFloatPow [8]{3.1415}{1234567890}}} +Some other problems will give rise to `error messages' macros giving some +indication on the location and nature of the problem. Mainly, an attempt has +been made to handle gracefully missing or extraneous parentheses. -\subsection{\csbh{xintFloatPower}}\label{xintFloatPower} +However, this mechanism is completely inoperant for parentheses involved in +the syntax of the |seq|, |add|, |mul|, |subs|, |rseq| and |rrseq| functions, +and missing parentheses may cause the parser to fetch tokens beyond the ending +|\relax| necessarily ending up in cryptic low-level \TeX-errors. -\csa{xintFloatPower}|[P]{f}{g}|\etype{{\upshape[\numx]}\Ff\Numf} computes a -floating point value |f^g| where the exponent |g| is not constrained to be at -most the \TeX{} bound \dtt{\number "7FFFFFFF}. It may even be a fraction -|A/B| but must simplify to a (possibly big) integer. The exponent of the -\emph{output} however \emph{must} at any rate obey the \TeX{} bound. +Note that the |,=| part must be visible, it can not arise from +expansion (the equal sign does not have to be an equal sign, it can be any +token and will be gobbled).\IMPORTANT{} However for |iter|, |iterr|, |rseq|, +|rrseq|, the initial values delimited by a |;| are parsed in the normal way, +and in particular may be braced or arise from expansion. This is useful as the +|;| may be hidden from \csa{xintdeffunc} as |{;}| for example. Again, this +remark does \emph{not} apply to the comma |,| which precedes the |=| +part. The comma will be fetched by delimited macros and must be there. Nesting +is handled by checking (again using suitable delimited macros) that +parentheses are suitably balanced. -The argument |f| is first rounded to |P| significant places to give -|f'|. The output |Z| is then such that the exact |f'^g| differs from -|Z| by an absolute error less than |0.52 ulp(Z)|. -This is the macro which is used for the |^| (or |**|) infix operators in -|\xintthefloatexpr...\relax|. In this context (but not directly with the -macro,) half-integer exponents are allowed. This is handled via an integer power -followed by a square-root extraction. The exponent is first rounded to nearest -integer or half-integer so that the computation never raises errors (except -naturally for negative exponent and zero |f|.) The |0.52 ulp(Z)| bound applies -with half-integer exponents too. +Note that |\relax| is \emph{mandatory} (contrarily to the situation for |\numexpr|). +\subsection{Acknowledgements (2013/05/25)} -Notice that this is a bound on the distance from |f'^g| to |Z|, as |f| always -gets rounded to |P| or \csbxint{theDigits} digits. The distance from |f^g| to -|Z| can be much worse if |g| is very large. Roughly, when |g| is negligible -compared to |10^P|, we get an extra difference of up to about |50g ulp(Z)| -which completely dwarfs the |0.52 ulp(Z)|. Thus, if |f| has strictly more than -|P| digits, then the computation must be done with an elevated working -precision |P'|. For example with |g=1000| we should use |P'=P+6| to achieve a -total error at worst slightly bigger than |0.55 ulp(Z)| after the final -rounding from |P'| to |P| digits to get |Z|. +I was greatly helped in my preparatory thinking, prior to producing such an +expandable parser, by the commented source of the +\href{http://www.ctan.org/pkg/l3kernel}{l3fp} package, specifically the +|l3fp-parse.dtx| file (in the version of April-May 2013; I think there was in +particular a text called ``roadmap'' which was helpful). Also the source of the +|calc| package was instructive, despite the fact that here for |\xintexpr| the +principles are necessarily different due to the aim of achieving expandability. -Examples:% -% -\footnote{|\np| is formatting macro from the \url{http://ctan.org/pkg/numprint} - package.} -% -\begin{everbatim*} -\np{\xintFloatPower [8]{3.1415}{3e9}}\newline% Notice that 3e9>2^31 -\np{\xintFloatPower [48]{1.1547}{\xintiiPow {2}{35}}}\newline -\end{everbatim*}% -$2^{35}=\xintiiPow {2}{35}$ exceeds \TeX's bound, but what -counts is the exponent of the result which, while dangerously close to -$2^{31}$ is not quite there yet. -With expressions: -\begin{everbatim*} -{\xintDigits:=48;\np{\xintthefloatexpr 1.1547^(2^35)\relax}} -\end{everbatim*} +\clearpage +\section{Macros of the \xintbinhexname package} +\label{sec:binhex} -There is a subtlety here that the |2^35| will be evaluated as a floating point -number but fortunately it only has \dtt{11} digits, hence the final evaluation -is done with a correct exponent. It would have been safer, and also more -efficient to code the above rather as: -\begin{everbatim} -\xintthefloatexpr 1.1547^\xintiiexpr 2^35\relax\relax -\end{everbatim} +\localtableofcontents -Here is an example with -|12^16| as exponent, which has $18$ digits (\dtt{={\xintiiPow{12}{16}}}). -\begin{everbatim*} -{\xintDigits:=12;\np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}}\newline -\np{\xintthefloatexpr (1+1e-8)^\xintiiexpr 12^16\relax\relax}\newline -{\xintDigits:=27;\np{\xintthefloatexpr (1+1e-8)^(12^16)\relax}}\newline -{\xintDigits:=48;\np{\xintthefloatexpr (1+1e-8)^(12^16)\relax}} -\end{everbatim*} +This package provides expandable conversions of (big) integers to +and from binary and hexadecimal. -There is an important difference between |\xintFloatPower[Q]{X}{Y}| and -|\xintthefloatexpr[Q] X^Y\relax|: in the former case the computation is done -with |Q| digits or precision,% -% -\footnote{if |X| and |Y| themselves stand for some -floating point macros with arguments, their respective evaluations obey the -precision |\xinttheDigits| or as set optionally in the macro calls -themselves.} -% -whereas with \csbxint{thefloatexpr}|[Q]| the evaluation of the -expression proceeds with |\xinttheDigits| digits of precision, and the final -result is then rounded to |Q| digits: thus this makes real sense only if used -with |Q<\xinttheDigits|. +First version of this package was in the |1.08| (|2013/06/07|) release of +\xintname. Its routines remained un-modified until their complete rewrite at +release |1.2m| (|2017/07/31|). The new macros are faster, using techniques +from the |1.2| (|2015/10/10|) release of \xintcorename. But the inputs are now +limited to a few thousand digits, whereas the |1.08| could handle (slowly...) +tens of thousands of digits. -\subsection{\csbh{xintFloatSqrt}}\label{xintFloatSqrt} +\autoref{tab:binhexsizes} recapitulates the maximal allowed sizes (they got +increased at |1.2n|)\CHANGED{1.2n}: +for macro |\xintFooToBar| in the first column, the value in the second column +is the maximal |N| such that |\edef\X{\xintFooToBar{}}| does not +raise an error with standard \TeX\ memory parameters (input stack +size=\dtt{5000}, expansion depth=\dtt{10000}, parameter stack +size=\dtt{10000}). The tests were done with TL2017 and |etex|. Nested calls +will allow slightly lesser values only. The third column gives the +corresponding maximal size of output. The fourth column gives the \TeX\ +parameter cited in the error message when trying with |N+1| digits. -\csa{xintFloatSqrt}|[P]{f}|\etype{{\upshape[\numx]}\Ff} computes a floating -point approximation of $\sqrt{|f|}$, either using the optional precision |P| or -the value of |\xinttheDigits|. +\begin{table}[htbp] +\capstart + \centering +\def\E#1#2!{\edef\F{\the\numexpr(#1-\xintLength{#2})/2}% + \relax\romannumeral\xintreplicate{\F}{ }#2% + \romannumeral\xintreplicate{#1-\F-\xintLength{#2}}{ }\relax}% +% non satisfactory because depends on #1 oddness, but well. Temporary destined +% to stay... +\begin{tabular}{r>{\E{19}}c<{!}>{\E{19}}c<{!}r} + \hline + &Max\ length\ of\ input&->\ length\ of\ output&Limiting factor\\ + \csbxint{DecToHex}&6014&4995&input stack size=5000\\ + \csbxint{DecToBin}&6014&19979&input stack size=5000\\ + \csbxint{HexToDec}&8298&9992&input stack size=5000\\ + \csbxint{BinToDec}&19988&6017&input stack size=5000\\ + \csbxint{BinToHex}&19988&4997&input stack size=5000\\ + \csbxint{HexToBin}&4996&19984&input stack size=5000\\ + \csbxint{CHexToBin}&4997&19988&input stack size=5000\\ + \hline +\end{tabular} +\caption{Maximal sizes of inputs (at \texttt{1.2n}) for \xintbinhexname macros}\label{tab:binhexsizes} +\end{table} -More precisely since |1.2f| the macro achieves so-called \emph{correct - rounding}:\IMPORTANT{} the produced value is the rounding to |P| significant -places of the abstract exact value, \emph{if the input has itself at most |P| - digits} (and an arbitrary exponent). -\begin{everbatim*} -\xintFloatSqrt [89]{10}\newline -\xintFloatSqrt [89]{100}\newline -\xintFloatSqrt [89]{123456789}\par -\end{everbatim*} +Roughly, base |10| numbers are limited to \dtt{6000} digits, hexadecimal +numbers to (almost) \dtt{5000} digits, and binary numbers to (almost) +\dtt{20000} digits. With the surprising exception of \csbxint{HexToDec} which +allows almost \dtt{8300} hexadecimal digits on input.\CHANGED{1.2n} -And now some tests to check that correct rounding applies correctly (sic): -\begin{everbatim*} -The argument has 16 digits, hence escapes initial rounding:\newline -\xintFloatSqrt {5625000075000001}\newline -This one gets rounded hence same value is computed:\newline -\xintFloatSqrt {5625000075000001.4}\newline -but actual value is more like:\newline -\xintFloatSqrt [24]{5625000075000001.4}\newline -\xintFloatSqrt [32]{5625000075000001.4}\newline -The argument has 48 digits, hence escapes initial rounding:\newline -\xintFloatSqrt [48]{562500000000000000000000750000000000000000000001}\newline -\xintFloatSqrt [64]{562500000000000000000000750000000000000000000001}\newline -\xintFloatSqrt [80]{562500000000000000000000750000000000000000000001}\newline -\end{everbatim*} -(we observe in passing illustrations that rounding to nearest is not -transitive.)\par +The argument is first \fexpan ded. +It may optionally have a unique leading minus sign (a plus sign is not +allowed), and leading zeroes. +An input (possibly signed) with no leading zeroes is guaranteed to give an +output without leading zero, with the sole, deliberate, exception of +\csbxint{CHexToBin}: from |N| hexadecimal digits it produces |4N| binary +digits,\CHANGED{1.2m} hence possibly with up to three leading zeroes (if the +input had none.) +Inputs with leading zeroes usually produce outputs with an unspecified, +case-dependent, number of leading zeroes (\csbxint{BinToHex} always uses the +minimal number of hexadecimal digits needed to represent the binary digits, +inclusive of leading zeroes if present.) +The macros\CHANGED{1.2m} converting from binary or decimal are robust against +non terminated inputs like |\the\numexpr 2+3| or |\the\mathcode`\-|. The macro +\csbxint{HexToDec} also but not \csbxint{HexToBin} and \csbxint{CHexToBin} +(anyway there are no primitive in (e)-\TeX\ to my knowledge which will +generate hexadecimal digits and may force expansion of next token). +Hexadecimal digits |A..F| must be in uppercase. Category code for them on +input may be \emph{letter} or \emph{other}. On output they are of category +code \emph{letter}, and in uppercase. +Low-level unrecoverable errors will happen if for example a supposedly binary +input contains other digits than |0| and |1|. Inputs can not start with a +|0b|, |0x|, |#x|, |"| or similar prefix: only digits/letters according to the +binary, decimal, or hexadecimal notation. -\xintDigits:=16; -\subsection{\csbh{xintiDivision}, \csbh{xintiQuo}, \csbh{xintiRem}, - \csbh{xintFDg}, \csbh{xintLDg}, \csbh{xintMON}, \csbh{xintMMON}, - \csbh{xintOdd}} +With this package loaded additionally to \xintexprname, hexadecimal input is +possible in expressions: simply by using the prefix |"|. Such hexadecimal +numbers may have a fractional part. Lowercase hexadecimal letters are +currently \emph{not} recognized as such in expressions. +Currently the |p| postfix notation from standard programming languages +standing for an extra +power of two multiplicand is not implemented. -These macros\etype{\Ff\Ff} accept a fraction (or two) on input but will -truncate it (them) to an integer using \csbxint{Num} (which is the same as -\csbxint{TTrunc}). On output they produce integers without |/| nor |[N]|. +% \clearpage -All have variants from package \xintname whose names start with |xintii| -rather than |xint|; these variants accept on input only integers in the strict -format (they do not use \csbxint{Num}). They thus have less overhead, and may -be used when one is dealing exclusively with (big) integers. +\subsection{\csbh{xintDecToHex}}\label{xintDecToHex} -% -\leftedline{|\xintNum {1e80}|} -% -\leftedline{\dtt{\xintNum{1e80}}} +Converts from decimal to hexadecimal.\etype{f} -%\etocdepthtag.toc {xintexpr} +\texttt{\string\xintDecToHex \string{\printnumber{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}\string}}\endgraf\noindent\dtt{->\printnumber{\xintDecToHex{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}}} -\clearpage -\section{Macros of the \xintexprname package}% -\label{sec:expr} +\subsection{\csbh{xintDecToBin}}\label{xintDecToBin} -\localtableofcontents +Converts from decimal to binary.\etype{f} -The \xintexprname package was first released with version |1.07| -(|2013/05/25|) of the \xintname bundle. It was substantially enhanced with -release |1.1| from |2014/10/28|. +\texttt{\string\xintDecToBin \string{\printnumber{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}\string}}\endgraf\noindent\dtt{->\printnumber{\xintDecToBin{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}}} -Release |1.2| removed a limitation to numbers of at most $5000$ digits, and -there is now a float variant of the factorial. Also the ``pseudo-functions'' -|qint|, |qfrac|, |qfloat| (|'q'| for quick), were added to handle very big -inputs and avoid scanning it digit per digit. +\subsection{\csbh{xintHexToDec}}\label{xintHexToDec} -The package loads automatically \xintfracname and \xinttoolsname (it is now -the only arithmetic package from the \xintname bundle which loads -\xinttoolsname). -\begin{itemize} -\item for using the |gcd| and |lcm| functions, it is necessary to load package - \xintgcdname. -\begin{everbatim*} -\xinttheexpr lcm (2^5*7*13^10*17^5,2^3*13^15*19^3,7^3*13*23^2)\relax -\end{everbatim*} -\item for allowing hexadecimal numbers (uppercase letters) on input, it is necessary - to load package \xintbinhexname. - \begin{everbatim*} -\xinttheexpr "A*"B*"C*"D*"D*"F, "FF.FF, reduce("FF.FFF + 16^-3)\relax -\end{everbatim*} -\end{itemize} +Converts from hexadecimal to decimal.\etype{f} -Please refer to \autoref{sec:xintexprsyntax} for a more detailed description -of the syntax elements for expressions. +\texttt{\string\xintHexToDec + \string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent +\dtt{->\printnumber{\xintHexToDec{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}} -\subsection{The \csbh{xintexpr} expressions} -\label{xintexpr} -\label{xinttheexpr} -\label{thexintexpr} -\label{xintthe} +\subsection{\csbh{xintBinToDec}}\label{xintBinToDec} -An \xintexprname{}ession is a construct -\csbxint{expr}\meta{expandable\_expression}|\relax|\etype{x} where the -expandable expression is read and completely expanded from left to right. +Converts from binary to decimal.\etype{f} -An |\xintexpr...\relax| \emph{must} end in a |\relax| (which will be absorbed). -Like a |\numexpr| expression, it is not printable as is, nor can it be directly -employed as argument to the other package macros. For this one must use one -of the three equivalent forms: -\begin{itemize} -\item \csb{thexintexpr}\meta{expandable\_expression}|\relax|\etype{x}, or -\item \csb{xinttheexpr}\meta{expandable\_expression}|\relax|\etype{x}, or -\item \csb{xintthe}|\xintexpr|\meta{expandable\_expression}|\relax|.\etype{x} -\end{itemize} +\texttt{\string\xintBinToDec + \string{\printnumber{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}\string}}\endgraf\noindent +\dtt{->\printnumber{\xintBinToDec{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}}} -The computations are done \emph{exactly}, and with no simplification of the -result. See \csbxint{floatexpr} for a similar parser which rounds each -operation inside the expression to \csbxint{theDigits} digits of precision. +\subsection{\csbh{xintBinToHex}}\label{xintBinToHex} -As an alternative and equivalent syntax to -\begin{everbatim} -\xintexpr round(, D)\relax -\end{everbatim} -there is\footnote{For truncation rather than rounding, one uses -|\xintexpr trunc(, D)\relax|.} -\begin{everbatim} -\xintiexpr [D] \relax -\end{everbatim} -The parameter |D| must be zero or positive.\footnote{|D=0| - corresponds to using |round()| not |round(,0)| which - would leave a trailing dot. Same for |trunc|. There is also function |float| - for floating point rounding to \csbxint{theDigits} or the given number of - significant digits as second argument.} Perhaps some future version will -give a meaning to using a negative |D|.\footnote{Thanks to KT for this - suggestion. Sorry for the delay in implementing it... matter of formatting - the output and corresponding choice of user interface are still in need of - some additional thinking.} +Converts from binary to hexadecimal.\etype{f} The input is first zero-filled +to |4N| binary digits, hence the output will have |N| hexadecimal digits +(thus, if the input did not have a leading zero, the output will not either). -\begin{itemize} -\item the expression may contain arbitrarily many levels of nested parenthesized - sub-expressions, -\item the expression may contain explicitely or from a macro expansion a - sub-expression |\xintexpr...\relax|, which itself may contain a - sub-expressions etc\dots -\item to let sub-contents evaluate as a sub-unit it should thus be either - \begin{enumerate} - \item parenthesized, - \item or a sub-expression |\xintexpr...\relax|. - \end{enumerate} - \item to use an expression as argument to the other package macros, - or more generally to macros which expand their arguments, one must use the - |\xinttheexpr...\relax| or |\xintthe\xintexpr...\relax| forms. - \item similarly, - printing the result itself must be done with these forms. - \item one should not use |\xinttheexpr...\relax| as a sub-constituent of an - |\xintexpr...\relax| but only the - |\xintexpr...\relax| form which is more efficient in this context. - \item each \xintexprname{}ession, whether prefixed or not with |\xintthe|, is - completely expandable and obtains its result in two expansion steps. -\end{itemize} +\texttt{\string\xintBinToHex + \string{\printnumber{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}\string}}\endgraf\noindent +\dtt{->\printnumber{\xintBinToHex{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}}} -See \autoref{sec:xintexprsyntax} for the primary information on built-in -operators and functions. This section now adds some complementary information. - +\subsection{\csbh{xintHexToBin}}\label{xintHexToBin} -\begin{itemize}[parsep=0pt, labelwidth=\leftmarginii, - itemindent=0pt, listparindent=\leftmarginiii, leftmargin=\leftmarginii] -\item An expression is built the standard way with opening and closing - parentheses, infix operators, and (big) numbers, with possibly a fractional - part, and/or scientific notation (except for \csbxint{iiexpr} which only - admits big integers). All variants work with comma separated expressions. On - output each comma will be followed by a space. A decimal number must have - digits either before or after the decimal mark. +Converts from hexadecimal to binary. Up to three leading zeroes of the output +are trimmed.\etype{f} -\item As everything gets expanded, the characters |.|, |+|, |-|, |*|, |/|, |^|, - |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, |=|, |(|, |)|, |"|, |]|, |[|, |@| - and the comma |,| should not (if used in the expression) be active. For - example, the French language in |Babel| system, for pdf\LaTeX, activates |!|, - |?|, |;| and |:|. Turn off the activity before the expressions. +\texttt{\string\xintHexToBin + \string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent +\dtt{->\printnumber{\xintHexToBin{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}} - Alternatively the macro \csbxint{exprSafeCatcodes} resets all - characters potentially needed by \csbxint{expr} to their standard catcodes - and \csbxint{exprRestoreCatcodes} restores the status prevailing at the time - of the previous \csa{xintexprSafeCatcodes}. +\subsection{\csbh{xintCHexToBin}}\label{xintCHexToBin} -\item Count registers and |\numexpr|-essions are accepted (LaTeX{}'s counters - can be inserted using |\value|) natively without |\the| or |\number| as - prefix. Also dimen registers and control sequences, skip registers and - control sequences (\LaTeX{}'s lengths), |\dimexpr|-essions, - |\glueexpr|-essions are automatically unpacked using |\number|, discarding - the stretch and shrink components and giving the dimension value in |sp| - units ($1/65536$th of a \TeX{} point). Furthermore, tacit multiplication is - implied, when the (count or dimen or glue) register or variable, or the - (|\numexpr| or |\dimexpr| or |\glueexpr|) expression is immediately prefixed - by a (decimal) number. See \autoref{ssec:tacit multiplication} for the complete rules - of tacit multiplication.\IMPORTANT +Converts from hexadecimal to binary.\etype{f} Same as \csbxint{HexToBin}, but +an input with |N| hexadecimal digits will give an output with exactly |4N| +binary digits, leading zeroes are not trimmed.\CHANGED{1.2m} -\item With a macro |\x| defined like this: - % - \leftedline{|\def\x {\xintexpr \a + \b \relax}| or |\edef\x {\xintexpr - \a+\b\relax}|} - % - one may then do |\xintthe\x|, either for printing the result on the page or - to use it in some other macros expanding their arguments. The |\edef| does - the computation immediately but keeps it in an internal private format. - Naturally, the |\edef| is only possible if |\a| and |\b| are already - defined. With both approaches the |\x| can be inserted in other expressions, - as for example (assuming naturally as we use an |\edef| that in the - `yet-to-be computed' case the |\a| and |\b| now have some suitable meaning): - % - \leftedline {|\edef\y {\xintexpr \x^3\relax}|} +\texttt{\string\xintCHexToBin + \string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent +\dtt{->\printnumber{\xintCHexToBin{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}} -\item There is also \csbxint{boolexpr}| ... \relax| and - \csbxint{theboolexpr}| ... \relax|. Same as |\xintexpr| with the final - result converted to $1$ if it is not zero. See also - \csbxint{ifboolexpr} (\autoref{xintifboolexpr}) and the - \hyperlink{builtinfunc-bool}{|bool|} and \hyperlink{builtinfunc-togl}{|togl|} functions - in \autoref{sec:expr}. Here is an example: -\catcode`| 12 % -\begin{everbatim*} -\xintNewBoolExpr \AssertionA[3]{ #1 && (#2||#3) } -\xintNewBoolExpr \AssertionB[3]{ #1 || (#2&) } -\xintNewBoolExpr \AssertionC[3]{ xor(#1,#2,#3) } -{\centering\normalcolor\xintFor #1 in {0,1} \do {% - \xintFor #2 in {0,1} \do {% - \xintFor #3 in {0,1} \do {% - #1 AND (#2 OR #3) is \textcolor[named]{OrangeRed}{\AssertionA {#1}{#2}{#3}}\hfil - #1 OR (#2 AND #3) is \textcolor[named]{OrangeRed}{\AssertionB {#1}{#2}{#3}}\hfil - #1 XOR #2 XOR #3 is \textcolor[named]{OrangeRed}{\AssertionC {#1}{#2}{#3}}\\}}}} -\end{everbatim*}\catcode`| 13 +This can be combined with \csbxint{BinToHex} for round-trips preserving +leading zeroes for |4N| binary digits numbers, whereas using +\csbxint{HexToBin} gives reproducing round-trips only for |4N| binary numbers +numbers not starting with |0000|. +\begin{everbatim*} +This zero-fills to 4N digits the input, hence gives here a leading zero in output: +\xintBinToHex{0001111}\newline +Chaining, we end up with 4N-3 digits, as three binary zeroes are trimmed: +\xintHexToBin{\xintBinToHex{0001111}}\newline +But this will always reproduce the initial input zero-filled to length 4N: +\xintCHexToBin{\xintBinToHex{0001111}}\par +Another example (visible space characters manually inserted):\newline +$000000001111101001010001\xrightarrow{\text{\string\xintBinToHex}} +\xintBinToHex{000000001111101001010001}\xrightarrow{\text{\string\xintHexToBin\hphantom{X}}} +\text{\textvisiblespace\textvisiblespace\textvisiblespace} +\xintHexToBin{\xintBinToHex{000000001111101001010001}}$\newline +$000000001111101001010001\xrightarrow{\text{\string\xintBinToHex}} +\xintBinToHex{000000001111101001010001}\xrightarrow{\text{\string\xintCHexToBin}} +\xintCHexToBin{\xintBinToHex{000000001111101001010001}}$ +\par +\end{everbatim*} +\clearpage +\section{Macros of the \xintgcdname package} +\label{sec:gcd} - This example used for efficiency \csbxint{NewBoolExpr}. See also the - \autoref{xintNewExpr}. +\localtableofcontents -\item There is \csbxint{floatexpr}| ... \relax| where the algebra is done - in floating point approximation (also for each intermediate result). Use the - syntax |\xintDigits:=N;| to set the precision. Default: $16$ digits. - % - \leftedline{|\xintthefloatexpr 2^100000\relax:| \dtt{\xintthefloatexpr - 2^100000\relax }} - % - The square-root operation can be used in |\xintexpr|, it is computed - as a float with the precision set by |\xintDigits| or by the optional - second argument: - % -\begin{everbatim*} -\xinttheexpr sqrt(2,60)\relax\newline -Here the [60] is to avoid truncation to |\xinttheDigits| of precision on output.\newline -\printnumber{\xintthefloatexpr [60] sqrt(2,60)\relax} -\end{everbatim*} +This package was included in the original release |1.0| (|2013/03/28|) of the +\xintname bundle. - Floats are quickly indispensable when using the power function , as exact - results will easily have hundreds, if not thousands, of digits. - % -\begin{everbatim*} -\xintDigits:=48;\xintthefloatexpr 2^100000\relax -\end{everbatim*} +Since release |1.09a| the macros filter their inputs through the \csbxint{Num} +macro, so one can use count registers, or fractions as long as they reduce to +integers. - Only integer and (in |\xintfloatexpr...\relax|) half-integer exponents are - allowed. +Since release |1.1|, the two ``|typeset|'' macros require the explicit +loading by the user of package \xinttoolsname. -\item if one uses \emph{macros} within |\xintexpr..\relax| one should - obviously take into account that the parser will \emph{not} see the macro - arguments, hence once cannot use the syntax there, except if the arguments - are themselves wrapped as |\xinttheexpr...\relax| and assuming the macro - \fexpan ds these arguments. -\end{itemize} +%% \clearpage -\subsection{\texorpdfstring{\texttt{\protect\string\numexpr}}{\textbackslash - numexpr} or \texorpdfstring{\texttt{\protect\string\dimexpr}}{\textbackslash - dimexpr} expressions, count and dimension registers and variables} -\label{ssec:countinexpr} +\subsection{\csbh{xintGCD}, \csbh{xintiiGCD}}\label{xintGCD}\label{xintiiGCD} -Count registers, count control sequences, dimen registers, dimen control -sequences (like |\parindent|), skips and skip control sequences, |\numexpr|, -|\dimexpr|, |\glueexpr|, |\fontdimen| can be inserted directly, they will be -unpacked using |\number| which gives the internal value in terms of scaled -points for the dimensional variables: $1$\,|pt|${}=65536$\,|sp| (stretch and -shrink components are thus discarded). +|\xintGCD|\n\m\etype{\Numf\Numf} computes the greatest common divisor. It is +positive, except when both |N| and |M| vanish, in which case the macro returns +zero. +% +\leftedline{\csa{xintGCD}|{10000}{1113}|\dtt{=\xintGCD{10000}{1113}}} +% +\leftedline{|\xintiiGCD{123456789012345}{9876543210321}=|\dtt + {\xintiiGCD{123456789012345}{9876543210321}}} -Tacit multiplication (see \autoref{ssec:tacit multiplication}) is implied, -when a number or decimal number prefixes such a register or control sequence. -\LaTeX{} lengths are skip control sequences and \LaTeX{} counters should be -inserted using |\value|. +\csa{xintiiGCD} skips the \csbxint{Num} overhead.\etype{ff} -Release |1.2| of the |\xintexpr| parser also recognizes and prefixes with -|\number| the |\ht|, |\dp|, and |\wd| \TeX{} primitives as well as the -|\fontcharht|, |\fontcharwd|, |\fontchardp| and |\fontcharic| \eTeX{} -primitives. +\subsection{\csbh{xintGCDof}}\label{xintGCDof} -In the case of numbered registers like |\count255| or |\dimen0| (or |\ht0|), -the resulting digits will be re-parsed, so for example |\count255 0| is like -|100| if |\the\count255| would give |10|. The same happens with inputs such -as |\fontdimen6\font|. And |\numexpr 35+52\relax| will be exactly as if |87| -as been encountered by the parser, thus more digits may follow: |\numexpr -35+52\relax 000| is like |87000|. If a new |\numexpr| follows, it is treated -as what would happen when |\xintexpr| scans a number and finds a non-digit: it -does a tacit multiplication. -\begin{everbatim*} -\xinttheexpr \numexpr 351+877\relax\numexpr 1000-125\relax\relax{} is the same -as \xinttheexpr 1228*875\relax. -\end{everbatim*} +\csa{xintGCDof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast\Numf}} computes the greatest common divisor of all +integers |a|, |b|, \dots{} The list argument +may be a macro, it is \fexpan ded first and must contain at least one item. -Control sequences however (such as |\parindent|) are picked up as a whole by -|\xintexpr|, and the numbers they define cannot be extended extra digits, a -syntax error is raised if the parser finds digits rather than a legal -operation after such a control sequence. +\subsection{\csbh{xintLCM}, \csbh{xintiiLCM}}\label{xintLCM}\label{xintiiLCM} -A token list variable must be prefixed by |\the|, it will not be unpacked -automatically (the parser will actually try |\number|, and thus fail). Do not -use |\the| but only |\number| with a dimen or skip, as the |\xintexpr| parser -doesn't understand |pt| and its presence is a syntax error. To use a dimension -expressed in terms of points or other \TeX{} recognized units, incorporate it in -|\dimexpr...\relax|. +|\xintGCD|\n\m\etype{\Numf\Numf} computes the least common multiple. It is +|0| if one of the two integers vanishes. -Regarding how dimensional expressions are converted by \TeX{} into scaled points -see also \autoref{sec:Dimensions}. +\csa{xintiiLCM} skips the \csbxint{Num} overhead.\etype{ff} -\subsection{Catcodes and spaces} +\subsection{\csbh{xintLCMof}}\label{xintLCMof} -Active characters may (and will) break the functioning of \csbxint{expr}. -Inside an expression one may prefix, for example a |:| with |\string|. Or, for -a more radical way, there is \csbxint{exprSafeCatcodes}. This is a -non-expandable step as it changes catcodes. +\csa{xintLCMof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast\Numf}} computes the least +common multiple of all integers |a|, |b|, \dots{} The list argument may be a +macro, it is \fexpan ded first and must contain at least one item. -\subsubsection{\csbh{xintexprSafeCatcodes}} -\label{xintexprSafeCatcodes} +\subsection{\csbh{xintBezout}}\label{xintBezout} -This macro sets the catcodes of the relevant characters to safe values. This -is used internally by \csbxint{NewExpr} (restoring the catcodes on exit), -hence \csa{xintNewExpr} does not have to be protected against active -characters. +|\xintBezout|\n\m\etype{\Numf\Numf} returns five numbers |A|, |B|, |U|, |V|, +|D| within braces. |A| is the first (expanded, as usual) input number, |B| the +second, |D| is the GCD, and \dtt{UA - VB = D}. +\begin{everbatim*} +\oodef\X{\xintBezout {10000}{1113}}\meaning\X\par +\xintAssign {\xintBezout {10000}{1113}}\to\A\B\U\V\D +A: \meaning\A\newline +B: \meaning\B\newline +U: \meaning\U\newline +V: \meaning\V\newline +D: \meaning\D\par +\xintAssign {\xintBezout {123456789012345}{9876543210321}}\to\A\B\U\V\D +A: \meaning\A\newline +B: \meaning\B\newline +U: \meaning\U\newline +V: \meaning\V\newline +D: \meaning\D\par +\end{everbatim*} -Attention however that if the whole -\begin{everbatim} -\xintNewExpr \foo [N] {} -\end{everbatim} -has been fetched as a macro argument, it will be too late then for -\csa{xintNewExpr} to sanitize the catcodes of the (active) characters within -the expression. +\subsection{\csbh{xintEuclideAlgorithm}}\label{xintEuclideAlgorithm} -\subsubsection{\csbh{xintexprRestoreCatcodes}} -\label{xintexprRestoreCatcodes} +|\xintEuclideAlgorithm|\n\m\etype{\Numf\Numf} applies the Euclide algorithm +and keeps a copy of all quotients and remainders. +\begin{everbatim*} +\edef\X{\xintEuclideAlgorithm {10000}{1113}}\meaning\X +\end{everbatim*} -Restores the catcodes to the earlier state. +The first token is the number of steps, the second is |N|, the +third is the GCD, the fourth is |M| then the first quotient and +remainder, the second quotient and remainder, \dots until the +final quotient and last (zero) remainder. -\bigskip +\subsection{\csbh{xintBezoutAlgorithm}}\label{xintBezoutAlgorithm} -Spaces inside an |\xinttheexpr...\relax| should mostly be -innocuous (except inside macro arguments). +|\xintBezoutAlgorithm|\n\m\etype{\Numf\Numf} applies the Euclide algorithm +and keeps a copy of all quotients and remainders. Furthermore it computes the +entries of the successive products of the 2 by 2 matrices +$\left(\vcenter{\halign {\,#&\,#\cr q & 1 \cr 1 & 0 \cr}}\right)$ formed from +the quotients arising in the algorithm. +\begin{everbatim*} +\edef\X{\xintBezoutAlgorithm {10000}{1113}}\printnumber{\meaning\X} +\end{everbatim*} -|\xintexpr| and |\xinttheexpr| are for the most part agnostic regarding -catcodes: (unbraced) digits, binary operators, minus and plus signs as -prefixes, dot as decimal mark, parentheses, may be indifferently of catcode -letter or other or subscript or superscript, ..., it doesn't matter.% -% -\footnote{Furthermore, although \csbxint{expr} uses \csa{string}, it is - escape-char agnostic. It should work with any \csa{escapechar} setting - including -1.} +The first token is the number of steps, the second is |N|, then +|0|, |1|, the GCD, |M|, |1|, |0|, the first quotient, the first +remainder, the top left entry of the first matrix, the bottom left +entry, and then these four things at each step until the end. -The characters |+|, |-|, |*|, |/|, |^|, |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, -|=|, |(|, |)|, |"|, |[|, |]|, |;|, the dot and the comma should not be active if -in the expression, as everything is expanded along the way. If one of them is -active, it should be prefixed with |\string|. +\subsection{\csbh{xintTypesetEuclideAlgorithm}}\label{xintTypesetEuclideAlgorithm} -The exclamation mark |!| should have its standard catcode: with catcode letter -it is used internally and hence will confuse the parsers if it comes from the -expression. +Requires explicit loading by the user of package \xinttoolsname. -Digits, slash, square brackets, minus sign, in the output from an -|\xinttheexpr| are all of catcode 12. For |\xintthefloatexpr| the `e' in the -output has its standard catcode ``letter''. +This macro is just an example of how to organize the data returned by +\csa{xintEuclideAlgorithm}.\ntype{\Numf\Numf} Copy the source code to a new +macro and modify it to what is needed. +% +\leftedline{|\xintTypesetEuclideAlgorithm {123456789012345}{9876543210321}|} +\xintTypesetEuclideAlgorithm {123456789012345}{9876543210321} -A macro with arguments will expand and grab its arguments before the -parser may get a chance to see them, so the situation with catcodes and spaces -is not the same within such macro arguments. +\subsection{\csbh{xintTypesetBezoutAlgorithm}}% +\label{xintTypesetBezoutAlgorithm} +Requires explicit loading by the user of package \xinttoolsname. +This macro is just an example of how to organize the data returned by +\csa{xintBezoutAlgorithm}.\ntype{\Numf\Numf} Copy the source code to a new +macro and modify it to what is needed. +% +\leftedline{|\xintTypesetBezoutAlgorithm {10000}{1113}|} +\xintTypesetBezoutAlgorithm {10000}{1113} -\subsection{Expandability, \csh{xinteval}} +\clearpage +\section{Macros of the \xintseriesname package} +\label{sec:series} -As is the case with all other package macros |\xintexpr| \fexpan ds (in two -steps) to its final (non-printable) result; and |\xinttheexpr| \fexpan ds (in -two steps) to the chain of digits (and possibly minus sign |-|, decimal mark -|.|, fraction slash |/|, scientific |e|, square brackets |[|, |]|) representing -the result. +\localtableofcontents -Starting with |1.09j|, an |\xintexpr..\relax| can be inserted without -|\xintthe| prefix inside an |\edef|, or a |\write|. It expands to a private -more compact representation (five tokens) than |\xinttheexpr| or -|\xintthe\xintexpr|. - -The material between |\xintexpr| and |\relax| should contain only expandable -material. - -The once expanded |\xintexpr| is |\romannumeral0\xinteval|. And there is -similarly |\xintieval|, |\xintiieval|, and |\xintfloateval|. For the other -cases one can use |\romannumeral-`0| as prefix. For an example of expandable -algorithms making use of chains of |\xinteval|-uations connected via -|\expandafter| see \autoref{ssec:fibonacci}. +This package was first released with version |1.03| (|2013/04/14|) of the +\xintname bundle. -An expression can only be legally finished by a |\relax| token, which -will be absorbed. +The \Ff{} expansion type of various macro arguments is only a \Numf{} if only +\xintname but not \xintfracname is loaded. The macro \csbxint{iSeries} is +special and expects summing big integers obeying the strict format, even if +\xintfracname is loaded. -It is quite possible to nest expressions among themselves; for example, if one -needs inside an |\xintiiexpr...\relax| to do some computations with fractions, -rounding the final result to an integer, one just has to insert -|\xintiexpr...\relax|. The functioning of the infix operators will not be in -the least affected from the fact that the surrounding ``environment'' is the -|\xintiiexpr| one. +The arguments serving as indices are of the \numx{} expansion type. -\subsection{Memory considerations} +In some cases one or two of the macro arguments are only expanded at a later +stage not immediately. -The parser creates an undefined control sequence for each intermediate -computation evaluation: addition, subtraction, etc\dots Thus, a moderately sized -expression might create 10, or 20 such control sequences. On my \TeX{} -installation, the memory available for such things is of circa \np{200000} -multi-letter control words. So this means that a document containing hundreds, -perhaps even thousands of expressions will compile with no problem. +%% \clearpage -Besides the hash table, also \TeX{} main memory is impacted. Thus, if -\xintexprname is used for computing plots% -% -\footnote{this is not very probable as so far \xintname does not include - a mathematical library with floating point calculations, but provides - only the basic operations of algebra.}% -% -, this may cause a problem. In my testing and with current |TL2015| memory -settings, I ran into problems after doing about \emph{ten thousand} -evaluations (for example |(#1+#2)*#3-#1*#3-#2*#3)|) each with number having -\emph{hundreds} of digits. Typical error message can be: -\begin{everbatim} -./testaleatoires.tex:243: TeX capacity exceeded, sorry [pool size=6134970]. - ...19140037877484848545931233090884903 -\end{everbatim} +\subsection{\csbh{xintSeries}}\label{xintSeries} -There is a (partial) solution.% +\csa{xintSeries}|{A}{B}{\coeff}|\etype{\numx\numx\Ff} computes +$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|. The initial and final indices +must obey the |\numexpr| constraint of expanding to numbers at most |2^31-1|. +The |\coeff| macro must be a one-parameter \fexpan dable macro, taking on +input an explicit number |n| and producing some number or fraction |\coeff{n}|; +it is expanded at the time it is +needed.% % -\footnote{which convinced me that I could stick with the parser - implementation despite its potential impact on the hash-table and - other parts of \TeX{}'s memory.} -A document can possibly do tens of thousands of evaluations only if some -identical formulae are being used repeatedly, with varying arguments (from -previous computations possibly) or coming from data being fetched from a file. -Most certainly, there will be a a few dozens formulae at most, but they will -be used again and again with varying inputs. - -With the \csbxint{NewExpr} macro, it is possible to convert once and -for all an expression containing parameters into an expandable macro -with parameters. Only this initial definition of this macro actually -activates the \csbxint{expr} parser and will (very moderately) impact -the hash-table: once this unique parsing is done, a macro with -parameters is produced which is built-up recursively from the -\csbxint{Add}, \csbxint{Mul}, etc... macros, exactly as it would be -necessary to do without the facilities of the \xintexprname package. - -Notice that since |1.2c| the \csbxint{deffunc} construct allows an alternative -to \csa{xintNewExpr} whose syntax uses arbitrary letters rather than macro -parameters |#1|, |#2|, ..., |#9|. The declared function must still be used -inside an expression, but its use will need only as many |\csname|'s as were -needed for the function arguments plus one more for encapsulating the function -result. - -\subsection{The \csbh{xintNewExpr} macro} -\label{xintNewExpr} - -The macro is used as: -% -\leftedline{|\xintNewExpr{\myformula}[n]|\marg{stuff}, where} -\begin{itemize} -\item \meta{stuff} will be inserted inside |\xinttheexpr . . . \relax|, -\item |n| is an integer between zero and nine, inclusive, which is the number - of parameters of |\myformula|, -\item the placeholders |#1|, |#2|, ..., |#n| are used inside \meta{stuff} in - their usual r\^ole,% -% -\catcode`# 12 -\footnote{if \csa{xintNewExpr} is used inside a macro, - the |#|'s must be doubled as usual.} - \footnote{the |#|'s will in pratice have their usual - catcode, but category code other |#|'s are accepted too.} -\catcode`# 6 -% -\item the |[n]| is \emph{mandatory}, even for |n=0|.% -\footnote{there is some use for \csa{xintNewExpr}|[0]| compared to an - \csa{edef} as \csa{xintNewExpr} has some built-in catcode protection.} -\item the macro |\myformula| is defined without checking if it already exists, - \LaTeX{} users might prefer to do first |\newcommand*\myformula {}| to get a - reasonable error message in case |\myformula| already exists, -\item the protection against active characters is done automatically (as long - as the whole thing has not already been fetched as a macro argument and - the catcodes correspondingly already frozen). -\end{itemize} +\begin{everbatim*} +\def\coeff #1{\xintiiMON{#1}/#1.5} % (-1)^n/(n+1/2) +\fdef\w {\xintSeries {0}{50}{\coeff}} % we want to re-use it +\fdef\z {\xintJrr {\w}[0]} % the [0] for a microsecond gain. +% \xintJrr preferred to \xintIrr: a big common factor is suspected. +% But numbers much bigger would be needed to show the greater efficiency. +\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} = \xintFrac\z \] +\end{everbatim*} -It will be a completely expandable macro entirely built-up using |\xintAdd|, -|\xintSub|, |\xintMul|, |\xintDiv|, |\xintPow|, etc\dots as corresponds to the -expression written with the infix operators. -Macros created by |\xintNewExpr| can thus be nested. +The definition of |\coeff| as |\xintiiMON{#1}/#1.5| is quite suboptimal. It +allows |#1| to be a big integer, but anyhow only small integers are accepted +as initial and final indices (they are of the \numx{} type). Second, when the +\xintfracname parser sees the |#1.5| it will remove the dot hence create a +denominator with one digit more. For example |1/3.5| turns internally into +|10/35| whereas it would be more efficient to have |2/7|. For info here is the +non-reduced |\w|: +\[\xintFrac\w\] +It would have been bigger still in releases earlier than |1.1|: now, the +\xintfracname \csbxint{Add} routine does not multiply blindly denominators +anymore, it checks if one is a multiple of the other. However it does not +practice systematic reduction to lowest terms. +A more efficient way to code |\coeff| is illustrated next. \begin{everbatim*} - \xintNewFloatExpr \FA [2]{(#1+#2)^10} - \xintNewFloatExpr \FB [2]{sqrt(#1*#2)} -\begin{enumerate}[nosep] - \item \FA {5}{5} - \item \FB {30}{10} - \item \FA {\FB {30}{10}}{\FB {40}{20}} -\end{enumerate} +\def\coeff #1{\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}% +% The [0] in \coeff is a tiny optimization: in its presence the \xintfracname parser +% sees something which is already in internal format. +\fdef\w {\xintSeries {0}{50}{\coeff}} +\[\sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12}=\xintFrac\w\] \end{everbatim*} +The reduced form |\z| as displayed above only differs from this one by a +factor of \dtt{\xintNum {\xintDenominator\w/\xintDenominator\z}}. - The use of \csbxint{NewExpr} circumvents the impact of the |\xintexpr| - parsers on \TeX's memory: it is useful if one has a formula which has to be - re-evaluated thousands of times with distinct inputs each with dozens, or - hundreds of digits. +\setlength{\columnsep}{0pt} +\everb|@ +\def\coeffleibnitz #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]} +\cnta 1 +\loop % in this loop we recompute from scratch each partial sum! +% we can afford that, as \xintSeries is fast enough. +\noindent\hbox to 2em{\hfil\texttt{\the\cnta.} }% + \xintTrunc {12}{\xintSeries {1}{\cnta}{\coeffleibnitz}}\dots +\endgraf +\ifnum\cnta < 30 \advance\cnta 1 \repeat +| - A ``formula'' created by |\xintNewExpr| is thus a macro whose parameters are - given to a possibly very complicated combination of the various macros of - \xintname and \xintfracname. Consequently, one can not use at all any infix - notation in the inputs, but only the formats which are recognized by the - \xintfracname macros. +\begin{multicols}{3} + \def\coeffleibnitz #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]} \cnta 1 + \loop + \noindent\hbox to 2em{\hfil\dtt{\the\cnta.} }% + \xintTrunc {12}{\xintSeries {1}{\cnta}{\coeffleibnitz}}\dots + \endgraf + \ifnum\cnta < 30 \advance\cnta 1 \repeat +\end{multicols} - This is thus quite different from a macro with parameters which one would - have defined via a simple |\def| or |\newcommand| as for example: - % - \leftedline{|\newcommand\myformula [1]{\xinttheexpr (#1)^3\relax}|} - % - Such a macro |\myformula|, if it was used tens of thousands of times with - various big inputs would end up populating large parts of \TeX's memory. It - would thus be better for such use cases to go for: - % - \leftedline{|\xintNewExpr\myformula [1]{#1^3\relax}|} - % - Here naturally the situation is over-simplified and it would be even simpler - to go directly for the use of the macro |\xintPow| or |\xintPower|. +\subsection{\csbh{xintiSeries}}\label{xintiSeries} +\def\coeff #1{\xintiTrunc {40} + {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% -|\xintNewExpr| tries to do as many evaluations as are possible at the time the -macro parameters are still parameters. Let's see a few examples. For this I -will use |\meaning| which reveals the contents of a macro. +\csa{xintiSeries}|{A}{B}{\coeff}|\etype{\numx\numx f} computes + $\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}| where |\coeff{n}| + must \fexpan d to a (possibly long) integer in the strict format. +\everb|@ +\def\coeff #1{\xintiTrunc {40}{\xintiiMON{#1}/#1.5}}% +% better: +\def\coeff #1{\xintiTrunc {40} + {\the\numexpr 2*\xintiiMON{#1}\relax/\the\numexpr 2*#1+1\relax [0]}}% +% better still: +\def\coeff #1{\xintiTrunc {40} + {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% +% (-1)^n/(n+1/2) times 10^40, truncated to an integer. +\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx + \xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\dots\] +| -\begin{enumerate} -\item the examples use a mysterious |\fixmeaning| macro, which is there to get - in the display |\romannumeral`^^@| rather than the frankly cabalistic - |\romannumeral``| which made the admiration of the readers of the - documentation dated |2015/10/19| (the second |`| stood for an ascii code - zero token as per |T1| encoded |newtxtt| font). Thus the true meaning is - ``fixed'' to display something different which is how the macro could be - defined in a standard |tex| source file (modulo, as one can see in example, - the use of characters such as |:| as letters in control sequence names). - Prior to |1.2a|, the meaning would have started with a more mundane - |\romannumeral-`0|, but I decided at the time of releasing |1.2a| to imitate - the serious guys and switch for the more hacky yet |\romannumeral`^^@| - everywhere in the source code (not only in the macros produced by - \csbxint{NewExpr}), or to be more precise for an equivalent as the caret has - catcode letter in \xintname's source code, and I had to use another - character. -\item the meaning reveals the use of some private macros from the \xintname - bundle, which should not be directly used. If the things look a bit - complicated, it is because they have to cater for many possibilities. -\item the point of showing the meaning is also to see what has already been - evaluated in the construction of the macros. -\end{enumerate} +\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx \xintTrunc +{40}{\xintiSeries {0}{50}{\coeff}[-40]}\] -\begin{everbatim*} -\xintNewIIExpr\FA [1]{13*25*78*#1+2826*292}\fixmeaning\FA -\end{everbatim*} -\smallskip +We should have cut out at +least the last two digits: truncating errors originating with the first +coefficients of the sum will never go away, and each truncation +introduces an uncertainty in the last digit, so as we have 40 terms, we +should trash the last two digits, or at least round at 38 digits. It is +interesting to compare with the computation where rounding rather than +truncation is used, and with the decimal +expansion of the exactly computed partial sum of the series: +\everb|@ +\def\coeff #1{\xintiRound {40} % rounding at 40 + {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% +% (-1)^n/(n+1/2) times 10^40, rounded to an integer. +\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx + \xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\] +\def\exactcoeff #1% + {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}% +\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} + = \xintTrunc {50}{\xintSeries {0}{50}{\exactcoeff}}\dots\] +| -\begin{everbatim*} -\xintNewIExpr\FA [2]{(3/5*9/7*13/11*#1-#2)*3^7} -\printnumber{\fixmeaning\FA} -\end{everbatim*} +\def\coeff #1{\xintiRound {40} + {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% +% (-1)^n/(n+1/2) times 10^40, rounded to an integer. +\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx + \xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\] +\def\exactcoeff #1% + {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}% +\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} + = \xintTrunc {50}{\xintSeries {0}{50}{\exactcoeff}}\dots\] +This shows indeed that our sum of truncated terms +estimated wrongly the 39th and 40th digits of the exact result% +% +\footnote{as the series is alternating, we can roughly expect an error + of $\sqrt{40}$ and the last two digits are off by 4 units, which is + not contradictory to our expectations.} +% +and that the sum of rounded terms fared a bit better. -\smallskip +\subsection{\csbh{xintRationalSeries}}\label{xintRationalSeries} -\begin{everbatim*} -% an example with optional parameter -\xintNewIExpr\FA [3]{[24] (#1+#2)/(#1-#2)^#3} -\printnumber{\fixmeaning\FA} -\end{everbatim*} -\smallskip +\noindent \csa{xintRationalSeries}|{A}{B}{f}{\ratio}|\etype{\numx\numx\Ff\Ff} +evaluates $\sum_{\text{|n=A|}}^{\text{|n=B|}}$|F(n)|, where |F(n)| is specified +indirectly via the data of |f=F(A)| and the one-parameter macro |\ratio| which +must be such that |\macro{n}| expands to |F(n)/F(n-1)|. The name indicates that +\csa{xintRationalSeries} was designed to be useful in the cases where +|F(n)/F(n-1)| is a rational function of |n| but it may be anything expanding to +a fraction. The macro |\ratio| must be an expandable-only compatible macro and +expand to its value after iterated full expansion of its first token. |A| and +|B| are fed to a |\numexpr| hence may be count registers or arithmetic +expressions built with such; they must obey the \TeX{} bound. The initial term +|f| may be a macro |\f|, it will be expanded to its value representing |F(A)|. \begin{everbatim*} -\xintNewFloatExpr\FA [2]{[12] 3.1415^3*#1-#2^5} -\printnumber{\fixmeaning\FA} +\def\ratio #1{2/#1[0]}% 2/n, to compute exp(2) +\cnta 0 % previously declared count +\begin{quote} +\loop \fdef\z {\xintRationalSeries {0}{\cnta}{1}{\ratio }}% +\noindent$\sum_{n=0}^{\the\cnta} \frac{2^n}{n!}= + \xintTrunc{12}\z\dots= + \xintFrac\z=\xintFrac{\xintIrr\z}$\vtop to 5pt{}\par +\ifnum\cnta<20 \advance\cnta 1 \repeat +\end{quote} \end{everbatim*} -\smallskip - \begin{everbatim*} -\xintNewExpr\DET[9]{ #1*#5*#9+#2*#6*#7+#3*#4*#8-#1*#6*#8-#2*#4*#9-#3*#5*#7 } -\printnumber{\fixmeaning\DET} +\def\ratio #1{-1/#1[0]}% -1/n, comes from the series of exp(-1) +\cnta 0 % previously declared count +\begin{quote} +\loop +\fdef\z {\xintRationalSeries {0}{\cnta}{1}{\ratio }}% +\noindent$\sum_{n=0}^{\the\cnta} \frac{(-1)^n}{n!}= + \xintTrunc{20}\z\dots=\xintFrac{\z}=\xintFrac{\xintIrr\z}$% + \vtop to 5pt{}\par +\ifnum\cnta<20 \advance\cnta 1 \repeat +\end{quote} \end{everbatim*} -\unless\ifxetex -Notice that since |1.2c| it is perhaps more natural to do: + + \def\ratioexp #1#2{\xintDiv{#1}{#2}}% #1/#2 + +\medskip We can incorporate an indeterminate if we define |\ratio| to be +a macro with two parameters: |\def\ratioexp + #1#2{\xintDiv{#1}{#2}}|\texttt{\%}| x/n: x=#1, n=#2|. +Then, if |\x| expands to some fraction |x|, the +macro % +% +\leftedline{|\xintRationalSeries {0}{b}{1}{\ratioexp{\x}}|} +will compute $\sum_{n=0}^{n=b} x^n/n!$:\par \begin{everbatim*} -% attention that «ad» would try to use non-existent variable "ad" -\xintdeffunc det2(a, b, c, d) := a*d - b*c ; -% This is impossible because we must use single letters : -% \xintdeffunc det3(x_11, x_12, x_13, x_21, x_22, x_23, x_31, x_32, x_33) := -% x_11 * det2 (x_22, x_23, x_32, x_33) + x_21 * det2 (x_32, x_33, x_12, x_13) -% + x_31 * det2 (x_12, x_13, x_22, x_23); -\xintdeffunc det3 (a, b, c, u, v, w, x, y, z) := a*v*z + b*w*x + c*u*y - b*u*z - c*v*x - a*w*y ; -\xinttheexpr det3 (1,1,1,1,2,4,1,3,9), det3 (1,10,100,1,100,10000,1,1000,1000000), - 90*900*990, reduce(det3 (1,1/2,1/3,1/2,1/3,1/4,1/3,1/4,1/5))\relax\newline -\xintdeffunc det3bis (a, b, c, u, v, w, x, y, z) := - a*det2(v,w,y,z)-b*det2(u,w,x,z)+c*det2(u,v,x,y); -\pdfsetrandomseed 123456789 % xint.pdf should be predictable from xint.dtx ! -\xinttheexpr subs(subs(subs(subs(subs(subs(subs(subs(subs( -% we use one extra pair of parentheses to hide the commas from the subs - (a, b, c, u, v, w, x, y, z, det3 (a, b, c, u, v, w, x, y, z), - det3bis (a, b, c, u, v, w, x, y, z)), - z=\pdfuniformdeviate 1000), y=\pdfuniformdeviate 1000), x=\pdfuniformdeviate 1000), - w=\pdfuniformdeviate 1000), v=\pdfuniformdeviate 1000), u=\pdfuniformdeviate 1000), - c=\pdfuniformdeviate 1000), b=\pdfuniformdeviate 1000), a=\pdfuniformdeviate 1000)\relax +\cnta 0 +\def\ratioexp #1#2{\xintDiv{#1}{#2}}% #1/#2 +\loop +\noindent +$\sum_{n=0}^{\the\cnta} (.57)^n/n! = \xintTrunc {50} + {\xintRationalSeries {0}{\cnta}{1}{\ratioexp{.57}}}\dots$ + \vtop to 5pt {}\endgraf +\ifnum\cnta<50 \advance\cnta 10 \repeat \end{everbatim*} +Observe that in this last example the |x| was directly inserted; if it +had been a more complicated explicit fraction it would have been +worthwile to use |\ratioexp\x| with |\x| defined to expand to its value. +In the further situation where this fraction |x| is not explicit but +itself defined via a complicated, and time-costly, formula, it should be +noted that \csa{xintRationalSeries} will do again the evaluation of |\x| +for each term of the partial sum. The easiest is thus when |x| can be +defined as an |\edef|. If however, you are in an expandable-only context +and cannot store in a macro like |\x| the value to be used, a variant of +\csa{xintRationalSeries} is needed which will first evaluate this |\x| and then +use this result without recomputing it. This is \csbxint{RationalSeriesX}, +documented next. - -The last computation with its nine nested |subs| can be coded more -economically (and efficiently), exploiting the fact that a single dummy -variable can expand to a whole list: +Here is a slightly more complicated evaluation: \begin{everbatim*} -\pdfsetrandomseed 123456789 % xint.pdf should be predictable from xint.dtx ! -\xinttheexpr subs((L, det3(L), det3bis(L)), % parentheses used to hide the inner commas - L=\pdfuniformdeviate 1000, \pdfuniformdeviate 1000, \pdfuniformdeviate 1000, - \pdfuniformdeviate 1000, \pdfuniformdeviate 1000, \pdfuniformdeviate 1000, - \pdfuniformdeviate 1000, \pdfuniformdeviate 1000, \pdfuniformdeviate 1000)\relax +\cnta 1 +\begin{multicols}{2} +\loop \fdef\z {\xintRationalSeries + {\cnta} + {2*\cnta-1} + {\xintiiPow {\the\cnta}{\cnta}/\xintiiFac{\cnta}} + {\ratioexp{\the\cnta}}}% +\fdef\w {\xintRationalSeries {0}{2*\cnta-1}{1}{\ratioexp{\the\cnta}}}% +\noindent +$\sum_{n=\the\cnta}^{\the\numexpr 2*\cnta-1\relax} \frac{\the\cnta^n}{n!}/% + \sum_{n=0}^{\the\numexpr 2*\cnta-1\relax} \frac{\the\cnta^n}{n!} = + \xintTrunc{8}{\xintDiv\z\w}\dots$ \vtop to 5pt{}\endgraf +\ifnum\cnta<20 \advance\cnta 1 \repeat +\end{multicols} \end{everbatim*} -\fi % de pas de xetex -With |\xintverbosetrue| we will find in the log: -\begin{everbatim} - Function det3 for \xintexpr parser associated to \XINT_expr_userfunc_det3 w -ith meaning macro:#1,#2,#3,#4,#5,#6,#7,#8,#9,->\xintSub {\xintSub {\xintSub {\x -intAdd {\xintAdd {\xintMul {\xintMul {#1}{#5}}{#9}}{\xintMul {\xintMul {#2}{#6} -}{#7}}}{\xintMul {\xintMul {#3}{#4}}{#8}}}{\xintMul {\xintMul {#2}{#4}}{#9}}}{\ -xintMul {\xintMul {#3}{#5}}{#7}}}{\xintMul {\xintMul {#1}{#6}}{#8}} -Package xintexpr Info: (on line 11) - Function det3bis for \xintexpr parser associated to \XINT_expr_userfunc_det -3bis with meaning macro:#1,#2,#3,#4,#5,#6,#7,#8,#9,->\xintAdd {\xintSub {\xintM -ul {#1}{\xintSub {\xintMul {#5}{#9}}{\xintMul {#6}{#8}}}}{\xintMul {#2}{\xintSu -b {\xintMul {#4}{#9}}{\xintMul {#6}{#7}}}}}{\xintMul {#3}{\xintSub {\xintMul {# -4}{#8}}{\xintMul {#5}{#7}}}} -\end{everbatim} +\subsection{\csbh{xintRationalSeriesX}}\label{xintRationalSeriesX} +\noindent\csa{xintRationalSeriesX}|{A}{B}{\first}{\ratio}{\g}|% +\etype{\numx\numx\Ff\Ff f} is a parametrized version of \csa{xintRationalSeries} +where |\first| is now a one-parameter macro such that |\first{\g}| gives the +initial term and |\ratio| is a two-parameter macro such that |\ratio{n}{\g}| +represents the ratio of one term to the previous one. The parameter |\g| is +evaluated only once at the beginning of the computation, and can thus itself be +the yet unevaluated result of a previous computation. -\medskip -Lists, including Python-like selectors, are compatible with -\csa{xintNewExpr}:% +Let |\ratio| be such a two-parameter macro; note the subtle differences +between% % -\footnote{The |\empty| token is optional here, but it would - be needed in case of \csbxint{NewFloatExpr} or \csbxint{NewIExpr}.} +\leftedline{|\xintRationalSeries {A}{B}{\first}{\ratio{\g}}|} % +\leftedline{and |\xintRationalSeriesX {A}{B}{\first}{\ratio}{\g}|.} First the +location of braces differ... then, in the former case |\first| is a +\emph{no-parameter} macro expanding to a fractional number, and in the latter, +it is a +\emph{one-parameter} macro which will use |\g|. Furthermore the |X| variant +will expand |\g| at the very beginning whereas the former non-|X| former variant +will evaluate it each time it needs it (which is bad if this +evaluation is time-costly, but good if |\g| is a big explicit fraction +encapsulated in a macro). + +The example will use the macro \csbxint{PowerSeries} which computes +efficiently exact partial sums of power series, and is discussed in the +next section. \begin{everbatim*} -\xintNewExpr\Foo[5]{\empty[#1..[#2]..#3][#4:#5]} -\begin{itemize}[nosep] -\item |\Foo{1}{3}{90}{20}{30}|->\Foo{1}{3}{90}{20}{30} -\item |\Foo{1}{3}{90}{-40}{-15}|->\Foo{1}{3}{90}{-40}{-15} -\item |\Foo{1.234}{-0.123}{-10}{3}{7}|->\Foo{1.234}{-0.123}{-10}{3}{7} -\end{itemize} -\fdef\test {\Foo {0}{10}{100}{3}{6}}\meaning\test +++ +\def\firstterm #1{1[0]}% first term of the exponential series +% although it is the constant 1, here it must be defined as a +% one-parameter macro. Next comes the ratio function for exp: +\def\ratioexp #1#2{\xintDiv {#1}{#2}}% x/n +% These are the (-1)^{n-1}/n of the log(1+h) series: +\def\coefflog #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]}% +% Let L(h) be the first 10 terms of the log(1+h) series and +% let E(t) be the first 10 terms of the exp(t) series. +% The following computes E(L(a/10)) for a=1,...,12. +\begin{multicols}{3}\raggedcolumns +\cnta 0 +\loop +\noindent\xintTrunc {18}{% + \xintRationalSeriesX {0}{9}{\firstterm}{\ratioexp} + {\xintPowerSeries{1}{10}{\coefflog}{\the\cnta[-1]}}}\dots +\endgraf +\ifnum\cnta < 12 \advance \cnta 1 \repeat +\end{multicols} \end{everbatim*} -In this last example the macro |\Foo| will not be able to handle an empty |#4| -or |#5|: this is only possible in an expression, because the parser identifies -|][:| or |:]| and handles them appropriately. During the construction of |\Foo| -the parser will find |][#4:| and not |][:|. - -\begin{framed} - The \csbxint{deffunc}, \csbxint{defiifunc}, \csbxint{deffloatfunc} - declarators added to \xintexprname since release |1.2c| are based on the - same underlying mechanism as \csa{xintNewExpr}, \csa{xintNewIIExpr}, ... The - discussion that follows applies to them too. -\end{framed} -\subsubsection {Conditional operators and \csbh{NewExpr}} -\label{sssec:cond} +These completely exact operations rapidly create numbers with many digits. Let +us print in full the raw fractions created by the operation illustrated above: -The |?| and |??| conditional operators cannot be parsed by |\xintNewExpr| when -they contain macro parameters |#1|,\dots, |#9| within their scope. However -replacing them with the functions |if| and, respectively |ifsgn|, the parsing -should succeed. And the created macro will \emph{not evaluate the branches to - be skipped}, thus behaving exactly like |?| and |??| would have in the -|\xintexpr|. +\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} +{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1[-1]}}} -\begin{everbatim*} -\xintNewExpr\Formula [3]{ if((#1>#2) && (#2>#3), sqrt(#1-#2)*sqrt(#2-#3), #1^2+#3/#2) }% -\printnumber{\fixmeaning\Formula } -\end{everbatim*} +|E(L(1[-1]))=|\dtt{\printnumber{\z}} (length of numerator: +\xintLen {\xintNumerator \z}) -This formula (with its |\xintiiifNotZero|) will gobble the false branch without -evaluating it when used with given arguments. +\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} +{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{12[-2]}}} -Remark: the meaning above reveals some of the private macros used by the -package. They are not for direct use. +|E(L(12[-2]))=|\dtt{\printnumber{\z}} (length of numerator: +\xintLen {\xintNumerator \z}) -Another example +\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} +{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{123[-3]}}} -\begin{everbatim*} -\xintNewExpr\myformula[3]{ ifsgn(#1,#2/#3,#2-#3,#2*#3) }% -\fixmeaning\myformula -\end{everbatim*} +|E(L(123[-3]))=|\dtt{\printnumber{\z}} (length of numerator: +\xintLen {\xintNumerator \z}) -Again, this macro gobbles the false branches, as would have the operator |??| -inside an |\xintexpr|-ession. +We see that the denominators here remain the same, as our input only had various +powers of ten as denominators, and \xintfracname efficiently assemble (some +only, as we can see) powers of ten. Notice that 1 more digit in an input +denominator seems to mean 90 more in the raw output. We can check that with some +other test cases: -\subsubsection{External macros and \csbh{NewExpr}; the protect function} -\label{sssec:protect} +\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} +{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/7}}} -For macros within such a created \xintname-formula macro, there -are two cases: -\begin{itemize} -\item the macro does not involve the numbered parameters in its arguments: it - may then be left as is, and will be evaluated once during the construction of - the formula, -\item it does involve at least one of the macro parameters as argument. Then: - \begin{snugframed} - the whole thing (macro + argument) should be |protect|-ed, not in the - \LaTeX{} sense (!), but in the following way: |protect(\macro {#1})|.\IMPORTANT - \end{snugframed} -\end{itemize} +|E(L(1/7))=|\dtt{\printnumber{\z}} (length of numerator: +\xintLen {\xintNumerator \z}; length of denominator: +\xintLen {\xintDenominator \z}) -Here is a silly example illustrating the general principle: the macros here have -equivalent functional forms which are more convenient; but some of the more -obscure package macros of \xintname dealing with integers do not have functions -pre-defined to be in correspondance with them, use this mechanism could be -applied to them. +\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} +{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/71}}} -\begin{everbatim*} -\xintNewExpr\formulaA[2]{protect(\xintRound{#1}{#2}) - protect(\xintTrunc{#1}{#2})}% -\printnumber{\fixmeaning\formulaA} +|E(L(1/71))=|\dtt{\printnumber{\z}} (length of numerator: +\xintLen {\xintNumerator \z}; length of denominator: +\xintLen {\xintDenominator \z}) -\xintNewIIExpr\formulaB [3]{rem(#1,quo(protect(\the\numexpr #2\relax),#3))}% -\noindent\printnumber{\fixmeaning\formulaB } -\end{everbatim*} +\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} +{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/712}}} -Only macros involving the |#1|, |#2|, etc\dots should be protected in this -way; the |+|, |*|, etc\dots symbols, the functions from the \csbxint{expr} -syntax, none should ever be included in a protected string. +|E(L(1/712))=|\dtt{\printnumber{\z}} (length of numerator: +\xintLen {\xintNumerator \z}; length of denominator: +\xintLen {\xintDenominator \z}) -\subsubsection{Limitations of \csbxint{NewExpr} and \csbxint{deffunc}} -\label{sssec:limitations} +Thus +decimal numbers such as |0.123| (equivalently +|123[-3]|) give less computing intensive tasks than fractions such as |1/712|: +in the case of decimal numbers the (raw) denominators originate in the +coefficients of the series themselves, powers of ten of the input within +brackets being treated separately. And even then the +numerators will grow with the size of the input in a sort of linear way, the +coefficient being given by the order of series: here 10 from the log and 9 from +the exp, so 90. One more digit in the input means 90 more digits in the +numerator of the output: obviously we can not go on composing such partial sums +of series and hope that \xintname will joyfully do all at the speed of light! -\csa{xintNewExpr} will pre-evaluate everything as long as it does not contain -the macro parameters |#1|, |#2|, ... and the special measures to take when -these are inside branches to |?| and |??| (replace these operators by |if| and -|ifsgn|) or as arguments to macros external to \xintexprname (use |protect|) -were discussed in \autoref{sssec:cond} and \autoref{sssec:protect}. +Hence, truncating the output (or better, rounding) is the only way to go if one +needs a general calculus of special functions. This is why the package +\xintseriesname provides, besides \csbxint{Series}, \csbxint{RationalSeries}, or +\csbxint{PowerSeries} which compute \emph{exact} sums, +\csbxint{FxPtPowerSeries} for fixed-point computations and a (tentative naive) +\csbxint{FloatPowerSeries}. + +\subsection{\csbh{xintPowerSeries}}\label{xintPowerSeries} + +\csa{xintPowerSeries}|{A}{B}{\coeff}{f}|\etype{\numx\numx\Ff\Ff} +evaluates the sum +$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot |f|^{\text{|n|}}$. The +initial and final indices are given to a |\numexpr| expression. The |\coeff| +macro (which, as argument to \csa{xintPowerSeries} is expanded only at the time +|\coeff{n}| is needed) should be defined as a one-parameter expandable macro, +its input will be an explicit number. + +The |f| can be either a fraction directly input or a macro |\f| expanding to +such a fraction. It is actually more efficient to encapsulate an explicit +fraction |f| in such a macro, if it has big numerators and denominators (`big' +means hundreds of digits) as it will then take less space in the processing +until being (repeatedly) used. + +This macro computes the \emph{exact} result (one can use it also for +polynomial evaluation), using a Horner scheme which helps avoiding a +denominator build-up (this problem however, even if using a naive additive +approach, is much less acute since release |1.1| and its new policy regarding +\csbxint{Add}). -The main remaining limitation is that expressions with dummy variables are -compatible with \csa{xintNewExpr} only to the extent that the iterated-over -list of values does not depend on the macro parameters |#1|, |#2|, ... For -example, this works: \begin{everbatim*} -\xintNewExpr \FA [2] {reduce(add((t+#1)/(t+#2), t=0..5))} -\FA {1}{1}, \FA {1}{2}, \FA {2}{3} +\def\geom #1{1[0]} % the geometric series +\def\f {5/17[0]} +\[ \sum_{n=0}^{n=20} \Bigl(\frac 5{17}\Bigr)^n + =\xintFrac{\xintIrr{\xintPowerSeries {0}{20}{\geom}{\f}}} + =\xintFrac{\xinttheexpr (17^21-5^21)/12/17^20\relax}\] \end{everbatim*} -but the |5| can not be abstracted into a third argument |#3|. -There are no restriction on using macro parameters |#1|, |#2|, ... with list -constructs. For example, this works: \begin{everbatim*} -\xintNewIExpr \FB [3] {[4] `+`([1/3..[#1/3]..#2]*#3)} -\begin{itemize}[nosep] -\item \FB {1}{10/3}{100} % (1/3+2/3+...+10/3)*100 -\item \FB {5}{5}{20} % (1/3+6/3+11/3)*20 -\item \FB {3}{4}{1} % (1/3+4/3+7/3+10/3)*1 -\end{itemize} +\def\coefflog #1{1/#1[0]}% 1/n +\def\f {1/2[0]}% +\[ \log 2 \approx \sum_{n=1}^{20} \frac1{n\cdot 2^n} + = \xintFrac {\xintIrr {\xintPowerSeries {1}{20}{\coefflog}{\f}}}\] +\[ \log 2 \approx \sum_{n=1}^{50} \frac1{n\cdot 2^n} + = \xintFrac {\xintIrr {\xintPowerSeries {1}{50}{\coefflog}{\f}}}\] \end{everbatim*} -Some simple expressions with |add| or |mul| can be also expressed with |`+`| -and |`*`| and list operations. But there is no hope for |seq|, |iter|, etc... -if the |#1|, |#2|, ... are used inside the list argument: -|seq(x(x+#1)(x+#2),x=1..#3)| is currently not compatible with -\csa{xintNewExpr}. But |seq(x(x+#1)(x+#2), x=1..10)| has no problem. - -All the preceeding applies identically for \csbxint{deffunc}, \csbxint{defiifunc}, -\csbxint{deffloatfunc} which share the same routines as \csa{xintNewExpr}, -\csa{xintNewIIExpr}, ..., replacing the |#1|, |#2|, ... in the discussion by -the letters used as function arguments. -There is a final syntax restriction which however applies only to -\csa{xintNewExpr} et. al., and not to \csa{xintdeffunc}, \csa{xintdefiifunc}, -\csa{xintdeffloatfunc} : it is possible to use sub-expressions only if they use -\csa{xintexpr}, those with \csa{xinttheexpr} are illegal. -\begin{everbatim*} -\xintNewExpr \FC [4] {#1+\xintexpr #2*#3\relax + #4} -\printnumber{\fixmeaning\FC} -\end{everbatim*}\newline -works, but already -\begin{everbatim} -\xintNewExpr \FD [1] {#1+\xinttheexpr 1\relax} -\end{everbatim} -doesn't. On the other hand \begin{everbatim*} -\xintdeffunc FD(t) := t + \xinttheexpr 1\relax ; +\setlength{\columnsep}{0pt} +\begin{multicols}{3} +\cnta 1 % previously declared count +\loop % in this loop we recompute from scratch each partial sum! +% we can afford that, as \xintPowerSeries is fast enough. +\noindent\hbox to 2em{\hfil\texttt{\the\cnta.} }% + \xintTrunc {12} + {\xintPowerSeries {1}{\cnta}{\coefflog}{\f}}\dots +\endgraf +\ifnum \cnta < 30 \advance\cnta 1 \repeat +\end{multicols} \end{everbatim*} -and even + + \begin{everbatim*} -\xintdeffunc FE(t,u) := t + \xinttheexpr u\relax ; +\def\coeffarctg #1{1/\the\numexpr\ifodd #1 -2*#1-1\else2*#1+1\fi\relax }% +% the above gives (-1)^n/(2n+1). The sign being in the denominator, +% **** no [0] should be added ****, +% else nothing is guaranteed to work (even if it could by sheer luck) +% Notice in passing this aspect of \numexpr: +% **** \numexpr -(1)\relax is ilegal !!! **** +\def\f {1/25[0]}% 1/5^2 +\[\mathrm{Arctg}(\frac15)\approx \frac15\sum_{n=0}^{15} \frac{(-1)^n}{(2n+1)25^n} += \xintFrac{\xintIrr {\xintDiv {\xintPowerSeries {0}{15}{\coeffarctg}{\f}}{5}}}\] \end{everbatim*} -have no issue. Anyway, one should never use |\xinttheexpr| for sub-expressions -but only |\xintexpr|, so this restriction on the \csa{xintNewExpr} syntax -isn't really one. -\subsection{The \csbh{xintNewFunction} macro} -See \autoref{xintNewFunction} for its documentation.\NewWith{1.2h} +\subsection{\csbh{xintPowerSeriesX}}\label{xintPowerSeriesX} -\subsection{\csbh{xintiexpr}, \csbh{xinttheiexpr}} -\label{xintiexpr}\label{xinttheiexpr}\label{thexintiexpr} +%{\small\hspace*{\parindent}New with release |1.04|.\par} -Equivalent\etype{x} to doing |\xintexpr round(...)\relax| (more precisely, -|round| is applied to each one of the evaluated values, if the expression was -comma separated). Thus, only the \emph{final result value} is rounded to an -integer. Half integers are rounded towards $+\infty$ for positive numbers and -towards $-\infty$ for negative ones. +\noindent This is the same as \csbxint{PowerSeries}\ntype{\numx\numx\Ff\Ff} +apart +from the fact that the last parameter |f| is expanded once and for all before +being then used repeatedly. If the |f| parameter is to be an explicit big +fraction with many (dozens) digits, rather than using it directly it is slightly +better to have some macro |\g| defined to expand to the explicit fraction and +then use \csbxint{PowerSeries} with |\g|; but if |f| has not yet been evaluated +and will be the output of a complicated expansion of some |\f|, and if, due to +an expanding only context, doing |\edef\g{\f}| is no option, then +\csa{xintPowerSeriesX} should be used with |\f| as last parameter. +% +\begin{everbatim*} +\def\ratioexp #1#2{\xintDiv {#1}{#2}}% x/n +% These are the (-1)^{n-1}/n of the log(1+h) series: +\def\coefflog #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]}% +% Let L(h) be the first 10 terms of the log(1+h) series and +% let E(t) be the first 10 terms of the exp(t) series. +% The following computes L(E(a/10)-1) for a=1,..., 12. +\begin{multicols}{3}\raggedcolumns +\cnta 1 +\loop +\noindent\xintTrunc {18}{% + \xintPowerSeriesX {1}{10}{\coefflog} + {\xintSub + {\xintRationalSeries {0}{9}{1[0]}{\ratioexp{\the\cnta[-1]}}} + {1}}}\dots +\endgraf +\ifnum\cnta < 12 \advance \cnta 1 \repeat +\end{multicols} +\end{everbatim*} -An optional parameter |d>0| within brackets, immediately after |\xintiexpr| -is allowed: it instructs the expression to do its final rounding to the -nearest value with that many digits after the decimal mark, \emph{i.e.}, -|\xintiexpr [d] \relax| is equivalent (in case of a single -expression) to |\xintexpr round(, d)\relax|. -|\xintiexpr [0] ...| is the same as |\xintiexpr ...|.\footnote{Incidentally - using |round(...,0)| in place of |round(...)| in |\xintexpr| would leave a - trailing dot in the produced value.} +\subsection{\csbh{xintFxPtPowerSeries}}\label{xintFxPtPowerSeries} -If truncation rather than rounding is needed use (in case of a single -expression, naturally) |\xintexpr trunc(...)\relax| for truncation to an -integer or |\xintexpr trunc(...,d)\relax| for truncation to a decimal number -with |d>0| digits after the decimal mark. +\csa{xintFxPtPowerSeries}|{A}{B}{\coeff}{f}{D}|\etype{\numx\numx} +computes +$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot |f|^{\,\text{|n|}}$ with each + term of the series truncated to |D| digits\etype{\Ff\Ff\numx} + after the decimal point. As + usual, |A| and |B| are completely expanded through their inclusion in a + |\numexpr| expression. Regarding |D| it will be similarly be expanded each + time it is used inside an \csa{xintTrunc}. The one-parameter macro |\coeff| + is similarly expanded at the time it is used inside the + computations. Idem for |f|. If |f| itself is some complicated macro it is + thus better to use the variant \csbxint{FxPtPowerSeriesX} which expands it + first and then uses the result of that expansion. -Perhaps in the future some meaning will be given to using negative value for -the optional parameter |d|.\footnote{Thanks to KT for this suggestion.} +The current (|1.04|) implementation is: the first power |f^A| is +computed exactly, then \emph{truncated}. Then each successive power is +obtained from the previous one by multiplication by the exact value of +|f|, and truncated. And |\coeff{n}|\raisebox{.5ex}{|.|}|f^n| is obtained +from that by multiplying by |\coeff{n}| (untruncated) and then +truncating. Finally the sum is computed exactly. Apart from that +\csa{xintFxPtPowerSeries} (where |FxPt| means `fixed-point') is like +\csa{xintPowerSeries}. -|\thexintiexpr| is synonym to |\xinttheiexpr|.\NewWith{1.2h} +There should be a variant for things of the type $\sum c_n \frac {f^n}{n!}$ to +avoid having to compute the factorial from scratch at each coefficient, the same +way \csa{xintFxPtPowerSeries} does not compute |f^n| from scratch at each |n|. +Perhaps in the next package release. -\subsection{\csbh{xintiiexpr}, \csbh{xinttheiiexpr}} -\label{xintiiexpr}\label{xinttheiiexpr}\label{thexintiiexpr} +\def\coeffexp #1{1/\xintiiFac {#1}[0]}% [0] for faster parsing +\def\f {-1/2[0]}% +\newcount\cnta -This variant\etype{x} does not know fractions. It deals almost only with long -integers. Comma separated lists of expressions are allowed. +\setlength{\multicolsep}{0pt} -\begin{framed} - It maps |/| to the \emph{rounded} quotient. The operator - |//| is, like in |\xintexpr...\relax|, mapped to \emph{truncated} division. - The euclidean quotient (which for positive operands is like the truncated - quotient) was, prior to release |1.1|, associated to |/|. The function - |quo(a,b)| can still be employed. -\end{framed} +\begin{multicols}{3}[% +\centeredline{$e^{-\frac12}\approx{}$}]% +\cnta 0 +\noindent\loop +$\xintFxPtPowerSeries {0}{\cnta}{\coeffexp}{\f}{20}$\\ +\ifnum\cnta<19 +\advance\cnta 1 +\repeat\par +\end{multicols} +\everb|@ +\def\coeffexp #1{1/\xintiiFac {#1}[0]}% 1/n! +\def\f {-1/2[0]}% [0] for faster input parsing +\cnta 0 % previously declared \count register +\noindent\loop +$\xintFxPtPowerSeries {0}{\cnta}{\coeffexp}{\f}{20}$\\ +\ifnum\cnta<19 \advance\cnta 1 \repeat\par +| -The \csbxint{iiexpr}-essions use the `ii' macros for addition, subtraction, -multiplication, power, square, sums, products, euclidean quotient and -remainder. -The |round|, |trunc|, |floor|, |ceil| functions are still available, and are -about the only places where fractions can be used, but |/| within, if not -somehow hidden will be executed as integer rounded division. To avoid this one -can wrap the input in \dtt{qfrac}: this means however that none of the normal -expression parsing will be executed on the argument. +% +\leftedline{|\xintFxPtPowerSeries {0}{19}{\coeffexp}{\f}{25}=| +\dtt{\xintFxPtPowerSeries {0}{19}{\coeffexp}{\f}{25}}} +\fdef\z{\xintIrr {\xintPowerSeries {0}{19}{\coeffexp}{\f}}} +% -To understand the illustrative examples, recall that |round| and |trunc| have -a second (non negative) optional argument. In a normal \csbxint{expr}-essions, -|round| and |trunc| are mapped to \csbxint{Round} and \csbxint{Trunc}, in -\csbxint{iiexpr}-essions, they are mapped to \csbxint{iRound} and -\csbxint{iTrunc}. +\texttt{\hyphenchar\font45 }% +It is no difficulty for \xintfracname to compute exactly, with the help +of \csa{xintPowerSeries}, the nineteenth partial sum, and to then give +(the start of) its exact decimal expansion: +% +\leftedline{|\xintPowerSeries {0}{19}{\coeffexp}{\f}| ${}= + \displaystyle\xintFrac{\z}$% + \vphantom{\vrule height 20pt depth 12pt}}% +% +\leftedline{${}=\xintTrunc {30}{\z}\dots$} Thus, one should always +estimate a priori how many ending digits are not reliable: if there are +|N| terms and |N| has |k| digits, then digits up to but excluding the +last |k| may usually be trusted. If we are optimistic and the series is +alternating we may even replace |N| with $\sqrt{|N|}$ to get the number |k| +of digits possibly of dubious significance. +\subsection{\csbh{xintFxPtPowerSeriesX}}\label{xintFxPtPowerSeriesX} -\begin{everbatim*} -\xinttheiiexpr 5/3, round(5/3,3), trunc(5/3,3), trunc(\xintDiv {5}{3},3), -trunc(\xintRaw {5/3},3)\relax{} are problematic, but -% -\xinttheiiexpr 5/3, round(qfrac(5/3),3), trunc(qfrac(5/3),3), floor(qfrac(5/3)), -ceil(qfrac(5/3))\relax{} work! -\end{everbatim*} -On the other hand decimal numbers and scientific numbers can be used directly -as arguments to the |num|, |round|, or any function producing an integer. +\noindent\csa{xintFxPtPowerSeriesX}|{A}{B}{\coeff}{\f}{D}|% +\ntype{\numx\numx} +computes, exactly as +\csa{xintFxPtPowerSeries}, the sum of +|\coeff{n}|\raisebox{.5ex}{|.|}|\f^n|\etype{\Ff\Ff\numx} from |n=A| to |n=B| with each term +of the series being \emph{truncated} to |D| digits after the decimal +point. The sole difference is that |\f| is first expanded and it +is the result of this which is used in the computations. -\begin{framed} - Scientific numbers will be - represented with as many zeroes as necessary, thus one does not want to - insert \dtt{num(1e100000)} for example in an \csa{xintiiexpr}ession ! -\end{framed} +Let us illustrate this on the numerical exploration of the identity % +\leftedline{|log(1+x) = -log(1/(1+x))|} +% +Let |L(h)=log(1+h)|, and |D(h)=L(h)+L(-h/(1+h))|. Theoretically thus, +|D(h)=0| but we shall evaluate |L(h)| and |-h/(1+h)| keeping only 10 +terms of their respective series. We will assume $|h|<0.5$. With only +ten terms kept in the power series we do not have quite 3 digits +precision as $2^{10}=1024$. So it wouldn't make sense to evaluate things +more precisely than, say circa 5 digits after the decimal points. \begin{everbatim*} -\xinttheiiexpr num(13.4567e3)+num(10000123e-3)\relax % should (num truncates) compute 13456+10000 +\cnta 0 +\def\coefflog #1{\the\numexpr\ifodd#1 1\else-1\fi\relax/#1[0]}% (-1)^{n-1}/n +\def\coeffalt #1{\the\numexpr\ifodd#1 -1\else1\fi\relax [0]}% (-1)^n +\begin{multicols}2 +\loop +\noindent \hbox to 2.5cm {\hss\texttt{D(\the\cnta/100): }}% +\xintAdd {\xintFxPtPowerSeriesX {1}{10}{\coefflog}{\the\cnta [-2]}{5}} + {\xintFxPtPowerSeriesX {1}{10}{\coefflog} + {\xintFxPtPowerSeriesX {1}{10}{\coeffalt}{\the\cnta [-2]}{5}} + {5}}\endgraf +\ifnum\cnta < 49 \advance\cnta 7 \repeat +\end{multicols} \end{everbatim*} -% - -The |reduce| function is not available and will raise un error. The |frac| -function also. The |sqrt| function is mapped to \csbxint{iiSqrt} which gives -a truncated square root. The |sqrtr| function is mapped to \csbxint{iiSqrtR} -which gives a rounded square root. -One can use the Float macros if one is careful to use |num|, or |round| -etc\dots on their output. +Let's say we evaluate functions on |[-1/2,+1/2]| with values more or less also +in |[-1/2,+1/2]| and we want to keep 4 digits of precision. So, roughly we need +at least 14 terms in series like the geometric or log series. Let's make this +15. Then it doesn't make sense to compute intermediate summands with more than 6 +digits precision. So we compute with 6 digits +precision but return only 4 digits (rounded) after the decimal point. +This result with 4 post-decimal points precision is then used as input +to the next evaluation. \begin{everbatim*} -\xinttheiiexpr \xintFloatSqrt [20]{2}, \xintFloatSqrt [20]{3}\relax % no operations - -\noindent The next example requires the |round|, and one could not put the |+| inside it: - -\xinttheiiexpr round(\xintFloatSqrt [20]{2},19)+round(\xintFloatSqrt [20]{3},19)\relax - -(the second argument of |round| and |trunc| tells how many digits from after the -decimal mark one should keep.) +\begin{multicols}2 +\loop +\noindent \hbox to 2.5cm {\hss\texttt{D(\the\cnta/100): }}% +\dtt{\xintRound{4} + {\xintAdd {\xintFxPtPowerSeriesX {1}{15}{\coefflog}{\the\cnta [-2]}{6}} + {\xintFxPtPowerSeriesX {1}{15}{\coefflog} + {\xintRound {4}{\xintFxPtPowerSeriesX {1}{15}{\coeffalt} + {\the\cnta [-2]}{6}}} + {6}}% + }}\endgraf +\ifnum\cnta < 49 \advance\cnta 7 \repeat +\end{multicols} \end{everbatim*} -The whole point of \csbxint{iiexpr} is to gain some speed in -\emph{integer-only} algorithms, and the above explanations related to how to -nevertheless use fractions therein are a bit peripheral. We observed -(2013/12/18) of the order of $30$\% speed gain when dealing with numbers with -circa one hundred digits (1.2: this info may be obsolete). - - -|\thexintiiexpr| is synonym to |\xinttheiiexpr|.\NewWith{1.2h} +Not bad... I have cheated a bit: the `four-digits precise' numeric +evaluations were left unrounded in the final addition. However the inner +rounding to four digits worked fine and made the next step faster than +it would have been with longer inputs. The morale is that one should not +use the raw results of \csa{xintFxPtPowerSeriesX} with the |D| digits +with which it was computed, as the last are to be considered garbage. +Rather, one should keep from the output only some smaller number of +digits. This will make further computations faster and not less precise. +I guess there should be some macro to do this final truncating, or +better, rounding, at a given number |D'}{YES}{NO}|\etype{xnn} does |\xinttheexpr -\relax| and then executes the |YES| or the |NO| branch depending on -whether the outcome was non-zero or zero. || can involve various |&| and -\verb+|+, parentheses, |all|, |any|, |xor|, the |bool| or |togl| operators, but -is not limited to them: the most general computation can be done, the test is on -whether the outcome of the computation vanishes or not. +But, for the +computation of a single constant, we are really interested in the exact +decimal expansion, so we truncate and compute more terms until the +earlier result gets validated. Finally if we do want the rounding we can +always do it on a value computed with |D+1| truncation. -Will not work on an expression composed of comma separated sub-expressions. +\clearpage +\section{Macros of the \xintcfracname package} +\label{sec:cfrac} -\subsection{\csbh{xintifboolfloatexpr}}\label{xintifboolfloatexpr} +\localtableofcontents -\csh{xintifboolfloatexpr}|{}{YES}{NO}|\etype{xnn} does |\xintthefloatexpr -\relax| and then executes the |YES| or the |NO| branch depending on -whether the outcome was non zero or zero. +First version of this package was included in release |1.04| (|2013/04/25|) of the +\xintname bundle. It was kept almost unchanged until |1.09m| of |2014/02/26| +which brings some new macros: \csbxint{FtoC}, \csbxint{CtoF}, \csbxint{CtoCv}, +dealing with sequences of braced partial quotients rather than comma separated +ones, \csbxint{FGtoC} which is to produce ``guaranteed'' coefficients of some +real number known approximately, and \csbxint{GGCFrac} for displaying arbitrary +material as a continued fraction; also, some changes to existing macros: +\csbxint{FtoCs} and \csbxint{CntoCs} insert spaces after the commas, +\csbxint{CstoF} and \csbxint{CstoCv} authorize spaces in the input also before +the commas. -\subsection{\csbh{xintifbooliiexpr}}\label{xintifbooliiexpr} +This section contains: +\begin{enumerate} +\item an \hyperref[ssec:cfracoverview]{overview} of the package functionalities, +\item a description of each one of the package macros, +\item further illustration of their use via the study of the + \hyperref[ssec:e-convergents]{convergents of $e$}. +\end{enumerate} -\csh{xintifbooliiexpr}|{}{YES}{NO}|\etype{xnn} does |\xinttheiiexpr -\relax| and then executes the |YES| or the |NO| branch depending on -whether the outcome was non zero or zero. +\subsection{Package overview}\label{ssec:cfracoverview} -\subsection{\csbh{xintNewFloatExpr}}\label{xintNewFloatExpr} +The package computes partial quotients and convergents of a fraction, or +conversely start from coefficients and obtain the corresponding fraction; three +macros \csbxint {CFrac}, \csbxint {GCFrac} and \csbxint {GGCFrac} are +for typesetting (the first two assume that the coefficients are numeric +quantities acceptable by the \xintfracname \csbxint{Frac} macro, the +last one will display arbitrary material), the others +can be nested (if applicable) or see their outputs further processed by other +macros from the \xintname bundle, particularly the macros of \xinttoolsname +dealing with sequences of braced items or comma separated lists. -This is exactly like \csbxint{NewExpr} except that the created formulas are -set-up to use |\xintthefloatexpr|. The precision used for the computation will -be the one given by |\xinttheDigits| at the time of use of the created formulas. -However, the numbers hard-wired in the original expression will have been -evaluated with the then current setting for |\xintDigits|. +A \emph{simple} continued fraction has coefficients +|[c0,c1,...,cN]| (usually called partial quotients, but I +dislike this entrenched terminology), where |c0| is a positive or +negative integer and the others are positive integers. +Typesetting is usually done via the |amsmath| macro |\cfrac|: \begin{everbatim*} -\xintNewFloatExpr \f [1] {sqrt(#1)} -\f {2} (with \xinttheDigits{} of precision). +\[ c_0 + \cfrac{1}{c_1+\cfrac1{c_2+\cfrac1{c_3+\cfrac1{\ddots}}}}\] +\end{everbatim*} -{\xintDigits := 32;\f {2} (with \xinttheDigits{} of precision).} +Here is a concrete example: +\begin{everbatim*} +\[ \xintFrac {208341/66317}=\xintCFrac {208341/66317}\]% +\end{everbatim*} +But it is the macro \csbxint{CFrac} which did all the work of \emph{computing} +the continued fraction \emph{and} using |\cfrac| from |amsmath| to typeset +it. -\xintNewFloatExpr \f [1] {sqrt(#1)*sqrt(2)} -\f {2} (with \xinttheDigits {} of precision). +A \emph{generalized} continued fraction has the same structure but the +numerators are not restricted to be $1$, and numbers used in the continued +fraction may be arbitrary, also fractions, irrationals, complex, +indeterminates.% +% +\footnote{\xintcfracname may be used with indeterminates, + for basic conversions from one inline format to another, but not for + actual computations. See \csbxint{GGCFrac}.} +% +The \emph{centered} continued fraction is an +example: +\begin{everbatim*} +\[ \xintFrac {915286/188421}=\xintGCFrac {5+-1/7+1/39+-1/53+-1/13} + =\xintCFrac {915286/188421}\] +\end{everbatim*} -{\xintDigits := 32;\f {2} (?? we thought we had a higher precision. Explanation next)} +The macro \csbxint{GCFrac}, contrarily to +\csbxint{CFrac}, does not compute anything, it just typesets starting from a +generalized continued fraction in inline format, which in this example +was input literally. We also used \csa{xintCFrac} +for comparison of the two types of continued fractions. -The sqrt(2) in the second formula was computed with only \xinttheDigits{} of -precision. Setting |\xinttheDigits| to a higher value at the time of definition will -confirm that the result above is from a mismatch of the precision for |sqrt(2)| at -the time of its evaluation and the precision for the new |sqrt(2)| with |#1=2| at -the time of use. +To let \TeX{} compute the centered continued fraction of |f| there is +\csbxint{FtoCC}: +\begin{everbatim*} +\[\xintFrac {915286/188421}\to\xintFtoCC {915286/188421}\] +\end{everbatim*} +The package macros are expandable and may be nested (naturally \csa{xintCFrac} +and \csa{xintGCFrac} must be at the top level, as they deal with typesetting). +\begin{everbatim*} +\[\xintGCFrac {\xintFtoCC{915286/188421}}\] +\end{everbatim*} -{\xintDigits := 32;\xintNewFloatExpr \f [1] {sqrt(#1)*sqrt(2)} -\f {2} (with \xinttheDigits {} of precision)} +The `inline' format expected on input by \csbxint{GCFrac} is +% +\leftedline{$a_0+b_0/a_1+b_1/a_2+b_2/a_3+\cdots+b_{n-2}/a_{n-1}+b_{n-1}/a_n$} +% +Fractions among the coefficients are allowed but they must be enclosed +within braces. Signed integers may be left without braces (but the |+| +signs are mandatory). No spaces are allowed around the plus and fraction +symbols. The coefficients may themselves be macros, as long as these +macros are \fexpan dable. +\begin{everbatim*} +\[ \xintFrac{\xintGCtoF {1+-1/57+\xintPow {-3}{7}/\xintiiQuo {132}{25}}} + = \xintGCFrac {1+-1/57+\xintPow {-3}{7}/\xintiiQuo {132}{25}}\] +\end{everbatim*} +To compute the actual fraction one has \csbxint{GCtoF}: +\begin{everbatim*} +\[\xintFrac{\xintGCtoF {1+-1/57+\xintPow {-3}{7}/\xintiiQuo {132}{25}}}\] +\end{everbatim*} +For non-numeric input there is \csbxint{GGCFrac}. +\begin{everbatim*} +\[\xintGGCFrac {a_0+b_0/a_1+b_1/a_2+b_2/\ddots+\ddots/a_{n-1}+b_{n-1}/a_n}\] +\end{everbatim*} +For regular continued fractions, there is a simpler comma separated format: +\begin{everbatim*} +\[-7,6,19,1,33\to\xintFrac{\xintCstoF{-7,6,19,1,33}}=\xintCFrac{\xintCstoF{-7,6,19,1,33}}\] +\end{everbatim*} +The macro \csbxint{FtoCs} produces from a fraction |f| the comma separated +list of its coefficients. +\begin{everbatim*} +\[\xintFrac{1084483/398959}=[\xintFtoCs{1084483/398959}]\] +\end{everbatim*} +If one prefers other separators, one can use the two arguments macros +\csbxint{FtoCx} whose first argument is the separator (which may consist of more +than one token) which is to be used. +\begin{everbatim*} +\[\xintFrac{2721/1001}=\xintFtoCx {+1/(}{2721/1001})\cdots)\] \end{everbatim*} +This allows under Plain \TeX{} with |amstex| to obtain the same effect +as with \LaTeX{}+|\amsmath|+\csbxint{CFrac}: +% +\leftedline{|$$\xintFwOver{2721/1001}=\xintFtoCx {+\cfrac1\\ }{2721/1001}\endcfrac$$|} -\subsection{\csbh{xintNewIExpr}}\label{xintNewIExpr} +As a shortcut to \csa{xintFtoCx} with separator |1+/|, there is +\csbxint{FtoGC}: +\begin{everbatim*} +2721/1001=\xintFtoGC {2721/1001} +\end{everbatim*} +Let us compare in that case with the output of \csbxint{FtoCC}: +\begin{everbatim*} +2721/1001=\xintFtoCC {2721/1001} +\end{everbatim*} +To obtain the coefficients as a sequence of braced numbers, there is +\csbxint{FtoC} (this is a shortcut for |\xintFtoCx {}|). This list +(sequence) may then be manipulated using the various macros of \xinttoolsname +such as the non-expandable macro \csbxint{AssignArray} or the expandable +\csbxint{Apply} and \csbxint{ListWithSep}. -Like \csbxint{NewExpr} but using |\xinttheiexpr|. +Conversely to go from such a sequence of braced coefficients to the +corresponding fraction there is \csbxint{CtoF}. +The `|\printnumber|' (\autoref{ssec:printnumber}) macro which we use in this +document to print long numbers can also be useful on long continued fractions. +% +\begin{everbatim*} +\printnumber{\xintFtoCC {35037018906350720204351049/244241737886197404558180}} +\end{everbatim*} +% +If we apply \csbxint{GCtoF} to this generalized continued fraction, we +discover that the original fraction was reducible: +% +\leftedline{|\xintGCtoF + {143+1/2+...+-1/9}|\dtt{=\xintGCtoF{143+1/2+1/5+-1/4+-1/4+-1/4+-1/3+1/2+1/2+1/6+-1/22+1/2+1/10+-1/5+-1/11+-1/3+1/4+-1/2+1/2+1/4+-1/2+1/23+1/3+1/8+-1/6+-1/9}}} -\subsection{\csbh{xintNewIIExpr}}\label{xintNewIIExpr} +\def\mymacro #1{$\xintFrac{#1}=[\xintFtoCs{#1}]$\vtop to 6pt{}} -Like \csbxint{NewExpr} but using |\xinttheiiexpr|. +\begingroup +\catcode`^\active +\def^#1^{\hbox{#1}}% -\subsection{\csbh{xintNewBoolExpr}}\label{xintNewBoolExpr} +When a generalized continued fraction is built with integers, and +numerators are only |1|'s or |-1|'s, the produced fraction is +irreducible. And if we compute it again with the last sub-fraction +omitted we get another irreducible fraction related to the bigger one by +a Bezout identity. Doing this here we get: +% +\leftedline{|\xintGCtoF {143+1/2+...+-1/6}|\dtt{=\xintGCtoF{143+1/2+1/5+-1/4+-1/4+-1/4+-1/3+1/2+1/2+1/6+-1/22+1/2+1/10+-1/5+-1/11+-1/3+1/4+-1/2+1/2+1/4+-1/2+1/23+1/3+1/8+-1/6}}} +and indeed: +\[\begin{vmatrix} + ^2897319801297630107^ & ^328124887710626729^\\ + ^20197107104701740^ & ^2287346221788023^ + \end{vmatrix} = \mbox{\dtt{\xintiiSub {\xintiiMul {2897319801297630107}{2287346221788023}}{\xintiiMul{20197107104701740}{328124887710626729}}}}\] -Like \csbxint{NewExpr} but using |\xinttheboolexpr|. +\endgroup -\xintDigits:= 16; +The various fractions obtained from the truncation of a continued fraction to +its initial terms are called the convergents. The macros of \xintcfracname +such as \csbxint{FtoCv}, \csbxint{FtoCCv}, and others which compute such +convergents, return them as a list of braced items, with no separator (as does +\csbxint {FtoC} for the partial quotients). Here is an example: -\subsection{Technicalities} +\begin{everbatim*} +\[\xintFrac{915286/188421}\to + \xintListWithSep{,}{\xintApply\xintFrac{\xintFtoCv{915286/188421}}}\] +\end{everbatim*} +\begin{everbatim*} +\[\xintFrac{915286/188421}\to + \xintListWithSep{,}{\xintApply\xintFrac{\xintFtoCCv{915286/188421}}}\] +\end{everbatim*} +% +We thus see that the `centered convergents' obtained with \csbxint{FtoCCv} are +among the fuller list of convergents as returned by \csbxint{FtoCv}. -As already mentioned \csa{xintNewExpr}|\myformula[n]| does not check the prior -existence of a macro |\myformula|. And the number of parameters |n| given as -mandatory argument within square brackets should be (at least) equal -to the number of parameters in the expression. +Here is a more complicated use of \csa{xintApply} +and \csa{xintListWithSep}. We first define a macro which will be applied to each +convergent:% +% +\leftedline{|\newcommand{\mymacro}[1]{$\xintFrac{#1}=[\xintFtoCs{#1}]$\vtop to 6pt{}}|} +% +Next, we use the following code: +% +\leftedline{|$\xintFrac{49171/18089}\to{}$|} +% +\leftedline{|\xintListWithSep {, + }{\xintApply{\mymacro}{\xintFtoCv{49171/18089}}}|} +It produces:\par +\noindent$ \xintFrac{49171/18089}\to {}$\xintListWithSep {, + }{\xintApply{\mymacro}{\xintFtoCv{49171/18089}}}. -Obviously I should mention that \csa{xintNewExpr} itself can not be used in an -expansion-only context, as it creates a macro. +The macro \csbxint{CntoF} allows to specify the coefficients as a function given +by a one-parameter macro. The produced values do not have to be integers. +\begin{everbatim*} +\def\cn #1{\xintiiPow {2}{#1}}% 2^n + \[\xintFrac{\xintCntoF {6}{\cn}}=\xintCFrac [l]{\xintCntoF {6}{\cn}}\] +\end{everbatim*} -The |\escapechar| setting may be arbitrary when using |\xintexpr|. +Notice the use of the optional argument |[l]| to \csa{xintCFrac}. Other +possibilities are |[r]| and (default) |[c]|. +\begin{everbatim*} +\def\cn #1{\xintPow {2}{-#1}}% + \[\xintFrac{\xintCntoF {6}{\cn}}=\xintGCFrac [r]{\xintCntoGC {6}{\cn}}= + [\xintFtoCs {\xintCntoF {6}{\cn}}]\] +\end{everbatim*} +We used \csbxint{CntoGC} as we wanted to display also the continued fraction and +not only the fraction returned by \csa{xintCntoF}. -The format of the output of -|\xintexpr|\meta{stuff}|\relax| is a |!| (with catcode 11) followed by various things: +There are also \csbxint{GCntoF} and \csbxint{GCntoGC} which allow the same for +generalized fractions. An initial portion of a generalized continued +fraction for $\pi$ is obtained like this \begin{everbatim*} -\edef\f {\xintexpr 1.23^10\relax }\meaning\f +\def\an #1{\the\numexpr 2*#1+1\relax }% +\def\bn #1{\the\numexpr (#1+1)*(#1+1)\relax }% +\[\xintFrac{\xintDiv {4}{\xintGCntoF {5}{\an}{\bn}}} = + \cfrac{4}{\xintGCFrac{\xintGCntoGC {5}{\an}{\bn}}} = + \xintTrunc {10}{\xintDiv {4}{\xintGCntoF {5}{\an}{\bn}}}\dots\] \end{everbatim*} -\begin{framed} - Note that |\xintexpr| expands in an |\edef|, contrarily - to |\numexpr| which is non-expandable, if not prefixed by |\the|, |\number|, - or |\romannumeral| or in some other context where \TeX{} is building a number. See - \autoref{ssec:fibonacci} for some illustration. -\end{framed} +We see that the quality of approximation is not fantastic compared to the simple +continued fraction of $\pi$ with about as many terms: +\begin{everbatim*} +\[\xintFrac{\xintCstoF{3,7,15,1,292,1,1}}= + \xintGCFrac{3+1/7+1/15+1/1+1/292+1/1+1/1}= + \xintTrunc{10}{\xintCstoF{3,7,15,1,292,1,1}}\dots\] +\end{everbatim*} -I decided to put all intermediate results (from each evaluation of an infix -operators, or of a parenthesized subpart of the expression, or from application -of the minus as prefix, or of the exclamation sign as postfix, or any -encountered braced material) inside |\csname...\endcsname|, as this can be done -expandably and encapsulates an arbitrarily long fraction in a single token (left -with undefined meaning), thus providing tremendous relief to the programmer in -his/her expansion control. +When studying the continued fraction of some real number, there is always +some doubt about how many terms are valid, when computed starting from some +approximation. If $f\leqslant x\leqslant g$ and $f, g$ both have the +same first $K$ partial quotients, then $x$ also has the same first $K$ quotients +and convergents. The macro \csbxint{FGtoC} outputs as a sequence of braced items +the common partial quotients of its two arguments. We can thus use it to produce +a sure list of valid convergents of $\pi$ for example, starting from some proven +lower and upper bound: +\begin{everbatim*} +$$\pi\to [\xintListWithSep{,} + {\xintFGtoC {3.14159265358979323}{3.14159265358979324}}, \dots]$$ +\noindent$\pi\to\xintListWithSep{,\allowbreak\;} + {\xintApply{\xintFrac} + {\xintCtoCv{\xintFGtoC {3.14159265358979323}{3.14159265358979324}}}}, \dots$ +\end{everbatim*} -\begin{framed} - As the |\xintexpr| computations corresponding to functions and infix - or postfix operators are done inside |\csname...\endcsname|, the - \fexpan dability could possibly be dropped and one could imagine - implementing the basic operations with expandable but not \fexpan - dable macros (as \csbxint{XTrunc}.) I have not investigated that - possibility. -\end{framed} -Syntax errors in the input such as using a one-argument function with two -arguments will generate low-level \TeX{} processing unrecoverable errors, with -cryptic accompanying message. +\subsection{\csbh{xintCFrac}}\label{xintCFrac} -Some other problems will give rise to `error messages' macros giving some -indication on the location and nature of the problem. Mainly, an attempt has -been made to handle gracefully missing or extraneous parentheses. +\csa{xintCFrac}|{f}|\ntype{\Ff} is a math-mode only, \LaTeX{} with |amsmath| +only, macro which first computes then displays with the help of |\cfrac| the +simple continued fraction corresponding to the given fraction. It admits an +optional argument which may be |[l]|, |[r]| or (the default) |[c]| to specify +the location of the one's in the numerators of the sub-fractions. Each +coefficient is typeset using the \csbxint{Frac} macro from the \xintfracname +package. This macro is \fexpan dable in the sense that it prepares expandably +the whole expression with the multiple |\cfrac|'s, but it is not completely +expandable naturally as |\cfrac| isn't. -However, this mechanism is completely inoperant for parentheses involved in -the syntax of the |seq|, |add|, |mul|, |subs|, |rseq| and |rrseq| functions, -and missing parentheses may cause the parser to fetch tokens beyond the ending -|\relax| necessarily ending up in cryptic low-level \TeX-errors. +\subsection{\csbh{xintGCFrac}}\label{xintGCFrac} -Note that the |,=| part must be visible, it can not arise from -expansion (the equal sign does not have to be an equal sign, it can be any -token and will be gobbled).\IMPORTANT{} However for |iter|, |iterr|, |rseq|, -|rrseq|, the initial values delimited by a |;| are parsed in the normal way, -and in particular may be braced or arise from expansion. This is useful as the -|;| may be hidden from \csa{xintdeffunc} as |{;}| for example. Again, this -remark does \emph{not} apply to the comma |,| which precedes the |=| -part. The comma will be fetched by delimited macros and must be there. Nesting -is handled by checking (again using suitable delimited macros) that -parentheses are suitably balanced. +\csa{xintGCFrac}|{a+b/c+d/e+f/g+h/...+x/y}|\ntype{f} uses similarly |\cfrac| +to prepare the typesetting with the |amsmath| |\cfrac| (\LaTeX{}) of a +generalized continued fraction given in inline format (or as macro which +will \fexpan d to it). It admits the +same optional argument as \csa{xintCFrac}. Plain \TeX{} with |amstex| +users, see \csbxint{GCtoGCx}. +\begin{everbatim*} +\[\xintGCFrac {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}\] +\end{everbatim*} +This is mostly a typesetting macro, although it does provoke the +expansion of the coefficients. See \csbxint{GCtoF} if you are impatient +to see this specific fraction computed. +It admits an optional argument within square brackets which may be +either |[l]|, |[c]| or |[r]|. Default is |[c]| (numerators are centered). -Note that |\relax| is \emph{mandatory} (contrarily to the situation for |\numexpr|). +Numerators and denominators are made arguments to the \csbxint{Frac} +macro. This allows them to be themselves fractions or anything \fexpan +dable giving numbers or fractions, but also means however that they can +not be arbitrary material, they can not contain color changing macros +for example. One of the reasons is that \csa{xintGCFrac} tries to +determine the signs of the numerators and chooses accordingly to use +$+$ or $-$. -\subsection{Acknowledgements (2013/05/25)} +\subsection{\csbh{xintGGCFrac}}\label{xintGGCFrac} -I was greatly helped in my preparatory thinking, prior to producing such an -expandable parser, by the commented source of the -\href{http://www.ctan.org/pkg/l3kernel}{l3fp} package, specifically the -|l3fp-parse.dtx| file (in the version of April-May 2013; I think there was in -particular a text called ``roadmap'' which was helpful). Also the source of the -|calc| package was instructive, despite the fact that here for |\xintexpr| the -principles are necessarily different due to the aim of achieving expandability. +\csa{xintGGCFrac}|{a+b/c+d/e+f/g+h/...+x/y}|\ntype{f} is a clone of +\csbxint{GCFrac}, hence again \LaTeX{} specific with package +|amsmath|. +It does not assume the coefficients to be numbers as understood by +\xintfracname. The macro can be used for displaying arbitrary content as +a continued fraction with |\cfrac|, using only plus signs though. Note +though that it will first \fexpan d its argument, which may be thus be +one of the \xintcfracname macros producing a (general) continued +fraction in inline format, see \csbxint{FtoCx} for an example. If this +expansion is not wished, it is enough to start the argument with a +space. +\begin{everbatim*} +\[\xintGGCFrac {1+q/1+q^2/1+q^3/1+q^4/1+q^5/\ddots}\] +\end{everbatim*} +\subsection{\csbh{xintGCtoGCx}}\label{xintGCtoGCx} +%{\small New with release |1.05|.\par} -\clearpage -\section{Macros of the \xintbinhexname package} -\label{sec:binhex} +\csa{xintGCtoGCx}|{sepa}{sepb}{a+b/c+d/e+f/...+x/y}|\etype{nnf} returns the list +of the coefficients of the generalized continued fraction of |f|, each one +within a pair of braces, and separated with the help of |sepa| and |sepb|. Thus +% +\leftedline{|\xintGCtoGCx :;{1+2/3+4/5+6/7}| gives \xintGCtoGCx + :;{1+2/3+4/5+6/7}} +% +The following can be used byt Plain \TeX{}+|amstex| users to obtain an +output similar as the ones produced by \csbxint{GCFrac} and +\csbxint{GGCFrac}:\par +\everb|@ +$$\xintGCtoGCx {+\cfrac}{\\}{a+b/...}\endcfrac$$ +$$\xintGCtoGCx {+\cfrac\xintFwOver}{\\\xintFwOver}{a+b/...}\endcfrac$$ +| -\localtableofcontents +\subsection{\csbh{xintFtoC}}\label{xintFtoC} -This package provides expandable conversions of (big) integers to -and from binary and hexadecimal. +\csa{xintFtoC}|{f}|\etype{\Ff} computes the +coefficients of the simple continued fraction of |f| and returns them as a list +(sequence) of braced items. -It was first included in the |1.08| (|2013/06/07|) release of \xintname. Its -routines remained un-modified until their complete rewrite at release |1.2m| -(|2017/07/31|). The new macros are faster, using techniques from the |1.2| -(|2015/10/10|) release of \xintcorename. But the inputs are now limited to a -few thousand digits, whereas the |1.08| could handle (slowly...) tens of -thousands of digits. +\begin{everbatim*} +\fdef\test{\xintFtoC{-5262046/89233}}\texttt{\meaning\test} +\end{everbatim*} -\autoref{tab:binhexsizes} recapitulates the maximal allowed sizes (they got -increased at |1.2n|)\CHANGED{1.2n}: -for macro |\xintFooToBar| in the first column, the value in the second column -is the maximal |N| such that |\edef\X{\xintFooToBar{}}| does not -raise an error with standard \TeX\ memory parameters (input stack -size=\dtt{5000}, expansion depth=\dtt{10000}, parameter stack -size=\dtt{10000}). The tests were done with TL2017 and |etex|. Nested calls -will allow slightly lesser values only. The third column gives the -corresponding maximal size of output. The fourth column gives the \TeX\ -parameter cited in the error message when trying with |N+1| digits. +\subsection{\csbh{xintFtoCs}}\label{xintFtoCs} -\begin{table}[htbp] -\capstart - \centering -\def\E#1#2!{\edef\F{\the\numexpr(#1-\xintLength{#2})/2}% - \relax\romannumeral\xintreplicate{\F}{ }#2% - \romannumeral\xintreplicate{#1-\F-\xintLength{#2}}{ }\relax}% -% non satisfactory because depends on #1 oddness, but well. Temporary destined -% to stay... -\begin{tabular}{r>{\E{19}}c<{!}>{\E{19}}c<{!}r} - \hline - &Max\ length\ of\ input&->\ length\ of\ output&Limiting factor\\ - \csbxint{DecToHex}&6014&4995&input stack size=5000\\ - \csbxint{DecToBin}&6014&19979&input stack size=5000\\ - \csbxint{HexToDec}&8298&9992&input stack size=5000\\ - \csbxint{BinToDec}&19988&6017&input stack size=5000\\ - \csbxint{BinToHex}&19988&4997&input stack size=5000\\ - \csbxint{HexToBin}&4996&19984&input stack size=5000\\ - \csbxint{CHexToBin}&4997&19988&input stack size=5000\\ - \hline -\end{tabular} -\caption{Maximal sizes of inputs (at \texttt{1.2n}) for \xintbinhexname macros}\label{tab:binhexsizes} -\end{table} +\csa{xintFtoCs}|{f}|\etype{\Ff} returns the comma separated list of the +coefficients of the simple continued fraction of |f|. Notice that starting with +|1.09m| a space follows each comma (mainly for usage in text mode, as in math +mode spaces are produced in the typeset output by \TeX{} itself). +\begin{everbatim*} +\[ \xintSignedFrac{-5262046/89233} \to [\xintFtoCs{-5262046/89233}]\] +\end{everbatim*} -Roughly, base |10| numbers are limited to \dtt{6000} digits, hexadecimal -numbers to (almost) \dtt{5000} digits, and binary numbers to (almost) -\dtt{20000} digits. With the surprising exception of \csbxint{HexToDec} which -allows almost \dtt{8300} hexadecimal digits on input.\CHANGED{1.2n} +\subsection{\csbh{xintFtoCx}}\label{xintFtoCx} -The argument is first \fexpan ded. -It may optionally have a unique leading minus sign (a plus sign is not -allowed), and leading zeroes. +\csa{xintFtoCx}|{sep}{f}|\etype{n\Ff} returns the list of the +coefficients of the simple continued fraction of |f| separated with the +help of |sep|, which may be anything (and is kept unexpanded). For +example, with Plain \TeX{} and |amstex|, +% +\leftedline{|$$\xintFtoCx {+\cfrac1\\ }{-5262046/89233}\endcfrac$$|} +% +will display the continued fraction using +|\cfrac|. Each coefficient is inside a brace pair \hbox{|{ }|}, allowing +a macro to end the separator and fetch it as argument, +for example, again with Plain \TeX{} and |amstex|: +\everb|@ + \def\highlight #1{\ifnum #1>200 \textcolor{red}{#1}\else #1\fi} + $$\xintFtoCx {+\cfrac1\\ \highlight}{104348/33215}\endcfrac$$ +| -An input (possibly signed) with no leading zeroes is guaranteed to give an -output without leading zero, with the sole, deliberate, exception of -\csbxint{CHexToBin}: from |N| hexadecimal digits it produces |4N| binary -digits,\CHANGED{1.2m} hence possibly with up to three leading zeroes (if the -input had none.) +Due to the different and extremely cumbersome syntax of |\cfrac| under +\LaTeX{} it proves a bit tortuous to obtain there the same effect. +Actually, it is partly for this purpose that |1.09m| added \csbxint +{GGCFrac}. We thus use \csa{xintFtoCx} with a suitable separator, and\; +then the whole thing as argument to \csbxint{GGCFrac}: +\begin{everbatim*} +\def\highlight #1{\ifnum #1>200 \fcolorbox{blue}{white}{\boldmath\color{red}$#1$}% + \else #1\fi} +\[\xintGGCFrac {\xintFtoCx {+1/\highlight}{208341/66317}}\] +\end{everbatim*} -Inputs with leading zeroes usually produce outputs with an unspecified, -case-dependent, number of leading zeroes (\csbxint{BinToHex} always uses the -minimal number of hexadecimal digits needed to represent the binary digits, -inclusive of leading zeroes if present.) +\subsection{\csbh{xintFtoGC}}\label{xintFtoGC} -The macros\CHANGED{1.2m} converting from binary or decimal are robust against -non terminated inputs like |\the\numexpr 2+3| or |\the\mathcode`\-|. The macro -\csbxint{HexToDec} also but not \csbxint{HexToBin} and \csbxint{CHexToBin} -(anyway there are no primitive in (e)-\TeX\ to my knowledge which will -generate hexadecimal digits and may force expansion of next token). +\csa{xintFtoGC}|{f}|\etype{\Ff} does the same as \csa{xintFtoCx}|{+1/}{f}|. Its +output may thus be used in the package macros expecting such an `inline +format'. +% This continued fraction is a \emph{simple} one, not a +% \emph{generalized} one, but as it is produced in the format used for +% user input of generalized continued fractions, the macro was called +% \csa{xintFtoGC} rather than \csa{xintFtoC} for example. +% +\begin{everbatim*} +566827/208524=\xintFtoGC {566827/208524} +\end{everbatim*} -Hexadecimal digits |A..F| must be in uppercase. Category code for them on -input may be \emph{letter} or \emph{other}. On output they are of category -code \emph{letter}, and in uppercase. +\subsection{\csbh{xintFGtoC}}\label{xintFGtoC} -Low-level unrecoverable errors will happen if for example a supposedly binary -input contains other digits than |0| and |1|. Inputs can not start with a -|0b|, |0x|, |#x|, |"| or similar prefix: only digits/letters according to the -binary, decimal, or hexadecimal notation. +\csa{xintFGtoC}|{f}{g}|\etype{\Ff\Ff} computes the common initial coefficients +to +two given fractions |f| and |g|. Notice that any real number |fx>g| +will then necessarily share with |f| and |g| these common initial coefficients +for its regular continued fraction. The coefficients are output as a sequence of +braced numbers. This list can then be manipulated via macros from +\xinttoolsname, or other macros of \xintcfracname. +\begin{everbatim*} +\fdef\test{\xintFGtoC{-5262046/89233}{-5314647/90125}}\texttt{\meaning\test} +\end{everbatim*} +\begin{everbatim*} +\fdef\test{\xintFGtoC{3.141592653}{3.141592654}}\texttt{\meaning\test} +\end{everbatim*} +\begin{everbatim*} +\fdef\test{\xintFGtoC{3.1415926535897932384}{3.1415926535897932385}}\meaning\test +\end{everbatim*} +\begin{everbatim*} +\xintRound {30}{\xintCstoF{\xintListWithSep{,}{\test}}} +\end{everbatim*} +\begin{everbatim*} +\xintRound {30}{\xintCtoF{\test}} +\end{everbatim*} +\begin{everbatim*} +\fdef\test{\xintFGtoC{1.41421356237309}{1.4142135623731}}\meaning\test +\end{everbatim*} -With this package loaded additionally to \xintexprname, hexadecimal input is -possible in expressions: simply by using the prefix |"|. Such hexadecimal -numbers may have a fractional part. Lowercase hexadecimal letters are -currently \emph{not} recognized as such in expressions. -Currently the |p| postfix notation from standard programming languages given a -power of two multiplicand is not implemented. +\subsection{\csbh{xintFtoCC}}\label{xintFtoCC} -% \clearpage +\csa{xintFtoCC}|{f}|\etype{\Ff} returns the `centered' continued fraction of +|f|, in `inline format'. % +\begin{everbatim*} +566827/208524=\xintFtoCC {566827/208524} +\end{everbatim*} +\begin{everbatim*} +\[\xintFrac{566827/208524} = \xintGCFrac{\xintFtoCC{566827/208524}}\] +\end{everbatim*} -\subsection{\csbh{xintDecToHex}}\label{xintDecToHex} +\subsection{\csbh{xintCstoF}}\label{xintCstoF} -Converts from decimal to hexadecimal.\etype{f} +\csa{xintCstoF}|{a,b,c,d,...,z}|\etype{f} computes the fraction corresponding to +the coefficients, which may be fractions or even macros expanding to such +fractions. The final fraction may then be highly reducible. Starting with +release |1.09m| spaces before commas are allowed and trimmed automatically +(spaces after commas were already silently handled in earlier releases). +\begin{everbatim*} +\[\xintGCFrac {-1+1/3+1/-5+1/7+1/-9+1/11+1/-13}= + \xintSignedFrac{\xintCstoF {-1,3,-5,7,-9,11,-13}}=\xintSignedFrac{\xintGCtoF + {-1+1/3+1/-5+1/7+1/-9+1/11+1/-13}}\] +\end{everbatim*} +\begin{everbatim*} +\[\xintGCFrac{{1/2}+1/{1/3}+1/{1/4}+1/{1/5}}=\xintFrac{\xintCstoF {1/2,1/3,1/4,1/5}}\] +\end{everbatim*} +% +A generalized continued fraction may produce a reducible fraction +(\csa{xintCstoF} tries its best not to accumulate in a silly way superfluous +factors but will not do simplifications which would be obvious to a human, like +simplification by 3 in the result above). -\texttt{\string\xintDecToHex \string{\printnumber{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}\string}}\endgraf\noindent\dtt{->\printnumber{\xintDecToHex{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}}} +\subsection{\csbh{xintCtoF}}\label{xintCtoF} -\subsection{\csbh{xintDecToBin}}\label{xintDecToBin} +\csa{xintCtoF}|{{a}{b}{c}...{z}}|\etype{f} computes the fraction corresponding +to the coefficients, which may be fractions or even macros. +\begin{everbatim*} +\xintCtoF {\xintApply {\xintiiPow 3}{\xintSeq {1}{5}}} +\end{everbatim*} +\begin{everbatim*} +\[ \xintFrac{14946960/4805083}=\xintCFrac {14946960/4805083}\] +\end{everbatim*} +In the example above the power of $3$ was already pre-computed via the expansion +done by |\xintApply|, but if we try with |\xintApply { \xintiiPow 3}| where the +space will stop this expansion, we can check that |\xintCtoF| will itself +provoke the needed coefficient expansion.% ok -Converts from decimal to binary.\etype{f} +\subsection{\csbh{xintGCtoF}}\label{xintGCtoF} -\texttt{\string\xintDecToBin \string{\printnumber{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}\string}}\endgraf\noindent\dtt{->\printnumber{\xintDecToBin{2718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003}}} +\csa{xintGCtoF}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} computes the fraction +defined by the inline generalized continued fraction. Coefficients may be +fractions but must then be put within braces. They can be macros. The plus signs +are mandatory. +\begin{everbatim*} +\[\xintGCFrac {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}} = +\xintFrac{\xintGCtoF {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}} = +\xintFrac{\xintIrr{\xintGCtoF + {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}}}\] +\end{everbatim*} -\subsection{\csbh{xintHexToDec}}\label{xintHexToDec} +\begin{everbatim*} +\[ \xintGCFrac{{1/2}+{2/3}/{4/5}+{1/2}/{1/5}+{3/2}/{5/3}} = + \xintFrac{\xintGCtoF {{1/2}+{2/3}/{4/5}+{1/2}/{1/5}+{3/2}/{5/3}}} \] +\end{everbatim*} -Converts from hexadecimal to decimal.\etype{f} +The macro tries its best not to accumulate superfluous factor in the +denominators, but doesn't reduce the fraction to irreducible form before +returning it and does not do simplifications which would be obvious to a human. -\texttt{\string\xintHexToDec - \string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent -\dtt{->\printnumber{\xintHexToDec{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}} +\subsection{\csbh{xintCstoCv}}\label{xintCstoCv} -\subsection{\csbh{xintBinToDec}}\label{xintBinToDec} +\csa{xintCstoCv}|{a,b,c,d,...,z}|\etype{f} returns the sequence of the +corresponding convergents, each one within braces. -Converts from binary to decimal.\etype{f} +It is allowed to use fractions as coefficients (the computed +convergents have then no reason to be the real convergents of the final +fraction). When the coefficients are integers, the convergents are irreducible +fractions, but otherwise it is not necessarily the case. +\begin{everbatim*} +\xintListWithSep:{\xintCstoCv{1,2,3,4,5,6}} +\end{everbatim*} +\begin{everbatim*} +\xintListWithSep:{\xintCstoCv{1,1/2,1/3,1/4,1/5,1/6}} +\end{everbatim*} +\begin{everbatim*} +\[\xintListWithSep{\to}{\xintApply\xintFrac{\xintCstoCv {\xintPow + {-.3}{-5},7.3/4.57,\xintCstoF{3/4,9,-1/3}}}}\] +\end{everbatim*} -\texttt{\string\xintBinToDec - \string{\printnumber{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}\string}}\endgraf\noindent -\dtt{->\printnumber{\xintBinToDec{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}}} +\subsection{\csbh{xintCtoCv}}\label{xintCtoCv} -\subsection{\csbh{xintBinToHex}}\label{xintBinToHex} +\csa{xintCtoCv}|{{a}{b}{c}...{z}}|\etype{f} returns the sequence of the +corresponding convergents, each one within braces. +\begin{everbatim*} +\fdef\test{\xintCtoCv {11111111111}}\texttt{\meaning\test} +\end{everbatim*} -Converts from binary to hexadecimal.\etype{f} +\subsection{\csbh{xintGCtoCv}}\label{xintGCtoCv} -\texttt{\string\xintBinToHex - \string{\printnumber{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}\string}}\endgraf\noindent -\dtt{->\printnumber{\xintBinToHex{100011010100100111001011111000110011010010100100110101001011100000101000111110111110100001010100000010111100100010100111000111110000010110001011111000100000110110001000111000100100010111010111011110010101101010111011000001011101100111000110100100111001011110100011011011100111001000110110001100000001100101001001101101011111100110111110110101100100100011000100000010100110001100011}}} +\csa{xintGCtoCv}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} returns the list of +the corresponding convergents. The coefficients may be fractions, but must then +be inside braces. Or they may be macros, too. -\subsection{\csbh{xintHexToBin}}\label{xintHexToBin} +The convergents will in the general case be reducible. To put them into +irreducible form, one needs one more step, for example it can be done +with |\xintApply\xintIrr|. +\begin{everbatim*} +\[\xintListWithSep{,}{\xintApply\xintFrac + {\xintGCtoCv{3+{-2}/{7/2}+{3/4}/12+{-56}/3}}}\] +\[\xintListWithSep{,}{\xintApply\xintFrac{\xintApply\xintIrr + {\xintGCtoCv{3+{-2}/{7/2}+{3/4}/12+{-56}/3}}}}\] +\end{everbatim*} -Converts from hexadecimal to binary. Up to three leading zeroes of the output -are trimmed.\etype{f} -\texttt{\string\xintHexToBin - \string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent -\dtt{->\printnumber{\xintHexToBin{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}} +\subsection{\csbh{xintFtoCv}}\label{xintFtoCv} -\subsection{\csbh{xintCHexToBin}}\label{xintCHexToBin} +\csa{xintFtoCv}|{f}|\etype{\Ff} returns the list of the (braced) convergents of +|f|, with no separator. To be treated with \csbxint{AssignArray} or +\csbxint{ListWithSep}. +\begin{everbatim*} +\[\xintListWithSep{\to}{\xintApply\xintFrac{\xintFtoCv{5211/3748}}}\] +\end{everbatim*} -Converts from hexadecimal to binary.\etype{f} Same as \csbxint{HexToBin}, but -an input with |N| hexadecimal digits will give an output with exactly |4N| -binary digits, leading zeroes are not trimmed.\CHANGED{1.2m} +\subsection{\csbh{xintFtoCCv}}\label{xintFtoCCv} -\texttt{\string\xintCHexToBin - \string{\printnumber{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}\string}}\endgraf\noindent -\dtt{->\printnumber{\xintCHexToBin{11A9397C66949A97051F7D0A817914E3E0B17C41B11C48BAEF2B5760BB38D272F46DCE46C6032936BF37DAC918814C63}}} +\csa{xintFtoCCv}|{f}|\etype{\Ff} returns the list of the (braced) centered +convergents of |f|, with no separator. To be treated with \csbxint{AssignArray} +or \csbxint{ListWithSep}. +\begin{everbatim*} +\[\xintListWithSep{\to}{\xintApply\xintFrac{\xintFtoCCv{5211/3748}}}\] +\end{everbatim*} -\clearpage -\section{Macros of the \xintgcdname package} -\label{sec:gcd} +\subsection{\csbh{xintCntoF}}\label{xintCntoF} -\localtableofcontents -This package was included in the original release |1.0| (|2013/03/28|) of the -\xintname bundle. +\csa{xintCntoF}|{N}{\macro}|\etype{\numx f} computes the fraction |f| having +coefficients |c(j)=\macro{j}| for |j=0,1,...,N|. The |N| parameter is given to a +|\numexpr|. The values of the coefficients, as returned by |\macro| do not have +to be positive, nor integers, and it is thus not necessarily the case that the +original |c(j)| are the true coefficients of the final |f|. +\begin{everbatim*} +\def\macro #1{\the\numexpr 1+#1*#1\relax} \xintCntoF {5}{\macro} +\end{everbatim*} -Since release |1.09a| the macros filter their inputs through the \csbxint{Num} -macro, so one can use count registers, or fractions as long as they reduce to -integers. - -Since release |1.1|, the two ``|typeset|'' macros require the explicit -loading by the user of package \xinttoolsname. - - -%% \clearpage - -\subsection{\csbh{xintGCD}, \csbh{xintiiGCD}}\label{xintGCD}\label{xintiiGCD} - -|\xintGCD|\n\m\etype{\Numf\Numf} computes the greatest common divisor. It is -positive, except when both |N| and |M| vanish, in which case the macro returns -zero. -% -\leftedline{\csa{xintGCD}|{10000}{1113}|\dtt{=\xintGCD{10000}{1113}}} -% -\leftedline{|\xintiiGCD{123456789012345}{9876543210321}=|\dtt - {\xintiiGCD{123456789012345}{9876543210321}}} - -\csa{xintiiGCD} skips the \csbxint{Num} overhead.\etype{ff} - -\subsection{\csbh{xintGCDof}}\label{xintGCDof} +This example shows that the fraction is output with a trailing number in square +brackets (representing a power of ten), this is for consistency with what do +most macros of \xintfracname, and does not have to be always this annoying |[0]| +as the coefficients may for example be numbers in scientific notation. To avoid +these trailing square brackets, for example if the coefficients are known to be integers, there is always the possibility to filter the output via +\csbxint{PRaw}, or \csbxint{Irr} (the latter is overkill in the case of integer +coefficients, as the fraction is guaranteed to be irreducible then). -\csa{xintGCDof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast\Numf}} computes the greatest common divisor of all -integers |a|, |b|, \dots{} The list argument -may be a macro, it is \fexpan ded first and must contain at least one item. +\subsection{\csbh{xintGCntoF}}\label{xintGCntoF} -\subsection{\csbh{xintLCM}, \csbh{xintiiLCM}}\label{xintLCM}\label{xintiiLCM} +\csa{xintGCntoF}|{N}{\macroA}{\macroB}|\etype{\numx ff} returns the fraction |f| +corresponding to the inline generalized continued fraction +|a0+b0/a1+b1/a2+....+b(N-1)/aN|, with |a(j)=\macroA{j}| and |b(j)=\macroB{j}|. +The |N| parameter is given to a |\numexpr|. +\begin{everbatim*} +\def\coeffA #1{\the\numexpr #1+4-3*((#1+2)/3)\relax }% +\def\coeffB #1{\the\numexpr \ifodd #1 -\fi 1\relax }% (-1)^n +\[\xintGCFrac{\xintGCntoGC {6}{\coeffA}{\coeffB}} = + \xintFrac{\xintGCntoF {6}{\coeffA}{\coeffB}}\] +\end{everbatim*} +There is also \csbxint{GCntoGC} to get the `inline format' continued +fraction. -|\xintGCD|\n\m\etype{\Numf\Numf} computes the least common multiple. It is -|0| if one of the two integers vanishes. +\subsection{\csbh{xintCntoCs}}\label{xintCntoCs} -\csa{xintiiLCM} skips the \csbxint{Num} overhead.\etype{ff} +\csa{xintCntoCs}|{N}{\macro}|\etype{\numx f} produces the comma separated list +of the corresponding coefficients, from |n=0| to |n=N|. The |N| is given to a +|\numexpr|. % +\begin{everbatim*} +\xintCntoCs {5}{\macro} +\end{everbatim*} +\begin{everbatim*} +\[ \xintFrac{\xintCntoF{5}{\macro}}=\xintCFrac{\xintCntoF {5}{\macro}}\] +\end{everbatim*} -\subsection{\csbh{xintLCMof}}\label{xintLCMof} +\subsection{\csbh{xintCntoGC}}\label{xintCntoGC} -\csa{xintLCMof}|{{a}{b}{c}...}|\etype{f{$\to$}{\lowast\Numf}} computes the least -common multiple of all integers |a|, |b|, \dots{} The list argument may be a -macro, it is \fexpan ded first and must contain at least one item. +% +\csa{xintCntoGC}|{N}{\macro}|\etype{\numx f} evaluates the |c(j)=\macro{j}| from +|j=0| to |j=N| and returns a continued fraction written in inline format: +|{c(0)}+1/{c(1)}+1/...+1/{c(N)}|. The parameter |N| is given to a |\numexpr|. +The coefficients, after expansion, are, as shown, being enclosed in an added +pair of braces, they may thus be fractions. +\begin{everbatim*} +\def\macro #1{\the\numexpr\ifodd#1 -1-#1\else1+#1\fi\relax/\the\numexpr 1+#1*#1\relax} +\fdef\x{\xintCntoGC {5}{\macro}}\meaning\x +\[\xintGCFrac{\xintCntoGC {5}{\macro}}\] +\end{everbatim*} -\subsection{\csbh{xintBezout}}\label{xintBezout} +\subsection{\csbh{xintGCntoGC}}\label{xintGCntoGC} -|\xintBezout|\n\m\etype{\Numf\Numf} returns five numbers |A|, |B|, |U|, |V|, -|D| within braces. |A| is the first (expanded, as usual) input number, |B| the -second, |D| is the GCD, and \dtt{UA - VB = D}. +\csa{xintGCntoGC}|{N}{\macroA}{\macroB}|\etype{\numx ff} evaluates the +coefficients and then returns the corresponding +|{a0}+{b0}/{a1}+{b1}/{a2}+...+{b(N-1)}/{aN}| inline generalized fraction. |N| is +givent to a |\numexpr|. The coefficients are enclosed into pairs +of braces, and may thus be fractions, the fraction slash will not be +confused in further processing by the continued fraction slashes. +% \begin{everbatim*} -\xintAssign[oo]{{\xintBezout {10000}{1113}}}\to\X -\meaning\X\newline -\xintAssign {\xintBezout {10000}{1113}}\to\A\B\U\V\D -A: \meaning\A\newline -B: \meaning\B\newline -U: \meaning\U\newline -V: \meaning\V\newline -D: \meaning\D\par +\def\an #1{\the\numexpr #1*#1*#1+1\relax}% +\def\bn #1{\the\numexpr \ifodd#1 -\fi 1*(#1+1)\relax}% +$\xintGCntoGC {5}{\an}{\bn}=\xintGCFrac {\xintGCntoGC {5}{\an}{\bn}} = +\displaystyle\xintFrac {\xintGCntoF {5}{\an}{\bn}}$\par \end{everbatim*} -For more than three years (from |1.09j 2014/01/09| to |1.2l| in 2017...) this -documentation looked strange (also in the next two sub-sections,) because -\csbxint{Assign} was modified at |1.09j| but the example above was missing the -now needed |[oo]| (or |[f]|, or |[e]|) hence |\X| was simply displayed as -|\xintBezout {10000}{1113}|. + +\subsection{\csbh{xintCstoGC}}\label{xintCstoGC} + +\csa{xintCstoGC}|{a,b,..,z}|\etype{f} transforms a comma separated list (or +something expanding to such a list) into an `inline format' continued fraction +|{a}+1/{b}+1/...+1/{z}|. The coefficients are just copied and put within braces, +without expansion. The output can then be used in \csbxint{GCFrac} for example. \begin{everbatim*} -\xintAssign {\xintBezout {123456789012345}{9876543210321}}\to\A\B\U\V\D -A: \meaning\A\newline -B: \meaning\B\newline -U: \meaning\U\newline -V: \meaning\V\newline -D: \meaning\D\par +\[\xintGCFrac {\xintCstoGC {-1,1/2,-1/3,1/4,-1/5}}=\xintSignedFrac{\xintCstoF {-1,1/2,-1/3,1/4,-1/5}}\] \end{everbatim*} +\subsection{\csbh{xintiCstoF}, \csbh{xintiGCtoF}, \csbh{xintiCstoCv}, \csbh{xintiGCtoCv}}\label{xintiCstoF} +\label{xintiGCtoF} +\label{xintiCstoCv} +\label{xintiGCtoCv} -\subsection{\csbh{xintEuclideAlgorithm}}\label{xintEuclideAlgorithm} +Essentially\etype{f} the same as the corresponding macros without the +`i', but for integer-only input. Infinitesimally faster, mainly for +internal use by the package. -|\xintEuclideAlgorithm|\n\m\etype{\Numf\Numf} applies the Euclide algorithm -and keeps a copy of all quotients and remainders. +\subsection{\csbh{xintGCtoGC}}\label{xintGCtoGC} + +\csa{xintGCtoGC}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} expands (with the +usual meaning) each one of the coefficients and returns an inline continued +fraction of the same type, each expanded coefficient being enclosed within +braces. +% \begin{everbatim*} -\xintAssign [oo]{{\xintEuclideAlgorithm {10000}{1113}}}\to\X -\meaning\X +\fdef\x {\xintGCtoGC {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/% + \xintiiFac {6}+\xintCstoF {2,-7,-5}/16}} \meaning\x \end{everbatim*} -The first token is the number of steps, the second is |N|, the -third is the GCD, the fourth is |M| then the first quotient and -remainder, the second quotient and remainder, \dots until the -final quotient and last (zero) remainder. +To be honest I have forgotten for which purpose I wrote this macro in the first +place. -\subsection{\csbh{xintBezoutAlgorithm}}\label{xintBezoutAlgorithm} +\subsection{Euler's number \texorpdfstring{$e$}{e}}\label{ssec:e-convergents} + +Let us explore +the convergents of Euler's number $e$. +\smallskip The volume of computation is kept minimal by the following steps: +\begin{itemize} +\item a comma separated list of the first 36 coefficients is produced by + \csbxint{CntoCs}, +\item this is then given to \csbxint{iCstoCv} which produces the list of the + convergents (there is also \csbxint{CstoCv}, but our + coefficients being integers we used the infinitesimally + faster \csbxint{iCstoCv}), +\item then the whole list was converted into a sequence of one-line paragraphs, + each convergent becomes the argument to a macro printing it + together with its decimal expansion with 30 digits after the decimal point. +\item A count register |\cnta| was used to give a line count serving as a visual + aid: we could also have done that in an expandable way, but well, let's relax + from time to time\dots +\end{itemize} -|\xintBezoutAlgorithm|\n\m\etype{\Numf\Numf} applies the Euclide algorithm -and keeps a copy of all quotients and remainders. Furthermore it computes the -entries of the successive products of the 2 by 2 matrices -$\left(\vcenter{\halign {\,#&\,#\cr q & 1 \cr 1 & 0 \cr}}\right)$ formed from -the quotients arising in the algorithm. \begin{everbatim*} -\xintAssign [oo]{{\xintBezoutAlgorithm {10000}{1113}}}\to\X -\printnumber{\meaning\X} +\def\cn #1{\the\numexpr\ifcase \numexpr #1+3-3*((#1+2)/3)\relax + 1\or1\or2*(#1/3)\fi\relax } +% produces the pattern 1,1,2,1,1,4,1,1,6,1,1,8,... which are the +% coefficients of the simple continued fraction of e-1. +\cnta 0 +\def\mymacro #1{\advance\cnta by 1 + \noindent + \hbox to 3em {\hfil\small\dtt{\the\cnta.} }% + $\xintTrunc {30}{\xintAdd {1[0]}{#1}}\dots= + \xintFrac{\xintAdd {1[0]}{#1}}$}% +\xintListWithSep{\vtop to 6pt{}\vbox to 12pt{}\par} + {\xintApply\mymacro{\xintiCstoCv{\xintCntoCs {35}{\cn}}}} \end{everbatim*} -The first token is the number of steps, the second is |N|, then -|0|, |1|, the GCD, |M|, |1|, |0|, the first quotient, the first -remainder, the top left entry of the first matrix, the bottom left -entry, and then these four things at each step until the end. - -\subsection{\csbh{xintTypesetEuclideAlgorithm}}\label{xintTypesetEuclideAlgorithm} -Requires explicit loading by the user of package \xinttoolsname. +\smallskip -This macro is just an example of how to organize the data returned by -\csa{xintEuclideAlgorithm}.\ntype{\Numf\Numf} Copy the source code to a new -macro and modify it to what is needed. -% -\leftedline{|\xintTypesetEuclideAlgorithm {123456789012345}{9876543210321}|} -\xintTypesetEuclideAlgorithm {123456789012345}{9876543210321} +% The actual computation of the list of all 36 convergents accounts for +% only 8\% of the total time (total time equal to about 5 hundredths of a second +% in my testing, on my laptop): another 80\% is occupied with the computation of +% the truncated decimal expansions (and the addition of 1 to everything as the +% formula gives the continued fraction of $e-1$). -\subsection{\csbh{xintTypesetBezoutAlgorithm}}% -\label{xintTypesetBezoutAlgorithm} +One can with no problem compute +much bigger convergents. Let's get the 200th convergent. It turns out to +have the same first 268 digits after the decimal point as $e-1$. Higher +convergents get more and more digits in proportion to their index: the 500th +convergent already gets 799 digits correct! To allow speedy compilation of the +source of this document when the need arises, I limit here to the 200th +convergent. +% (getting the 500th took about 1.2s on my laptop last time I tried, +% and the 200th convergent is obtained ten times faster). +\begin{everbatim*} +\fdef\z {\xintCntoF {199}{\cn}}% +\begingroup\parindent 0pt \leftskip 2.5cm +\indent\llap {Numerator = }\printnumber{\xintNumerator\z}\par +\indent\llap {Denominator = }\printnumber{\xintDenominator\z}\par +\indent\llap {Expansion = }\printnumber{\xintTrunc{268}\z}\dots\par\endgroup +\end{everbatim*} -Requires explicit loading by the user of package \xinttoolsname. -This macro is just an example of how to organize the data returned by -\csa{xintBezoutAlgorithm}.\ntype{\Numf\Numf} Copy the source code to a new -macro and modify it to what is needed. -% -\leftedline{|\xintTypesetBezoutAlgorithm {10000}{1113}|} -\xintTypesetBezoutAlgorithm {10000}{1113} +One can also use a centered continued fraction: we get more digits but there are +also more computations as the numerators may be either +$1$ or $-1$. \clearpage -\section{Macros of the \xintseriesname package} -\label{sec:series} +\section{Macros of the \xinttoolsname package} + +\label{sec:tools} \localtableofcontents -This package was first released with version |1.03| (|2013/04/14|) of the -\xintname bundle. +\def\n{|{N}|} +\def\m{|{M}|} +\def\x{|{x}|} -The \Ff{} expansion type of various macro arguments is only a \Numf{} if only -\xintname but not \xintfracname is loaded. The macro \csbxint{iSeries} is -special and expects summing big integers obeying the strict format, even if -\xintfracname is loaded. +These utilities used to be provided within the \xintname package; since |1.09g| +(|2013/11/22|) they have been moved to an independently usable package +\xinttoolsname, which has none of the \xintname facilities regarding big +numbers. Whenever relevant release |1.09h| has made the macros |\long| so they +accept |\par| tokens on input. -The arguments serving as indices are of the \numx{} expansion type. +The completely expandable utilities (up to \csbxint{iloop}) are documented +first, then the non expandable utilities. -In some cases one or two of the macro arguments are only expanded at a later -stage not immediately. +A brief overview is in \autoref{sec:sometoolsutils} and \autoref{sec:examples} +has more examples of use of macros of this package. -%% \clearpage +\subsection{\csbh{xintRevWithBraces}}\label{xintRevWithBraces} -\subsection{\csbh{xintSeries}}\label{xintSeries} +%{\small New in release |1.06|.\par} -\csa{xintSeries}|{A}{B}{\coeff}|\etype{\numx\numx\Ff} computes -$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|. The initial and final indices -must obey the |\numexpr| constraint of expanding to numbers at most |2^31-1|. -The |\coeff| macro must be a one-parameter \fexpan dable macro, taking on -input an explicit number |n| and producing some number or fraction |\coeff{n}|; -it is expanded at the time it is -needed.% +\edef\X{\xintRevWithBraces{12345}} +\edef\y{\xintRevWithBraces\X} +\expandafter\def\expandafter\w\expandafter + {\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}} + +% +\csa{xintRevWithBraces}\marg{list}\etype{f} first does the \fexpan sion of its +argument then it reverses the order of the tokens, or braced material, it +encounters, maintaining existing braces and adding a brace pair around each +naked token encountered. Space tokens (in-between top level braces or naked +tokens) are gobbled. This macro is mainly thought out for use on a \meta{list} +of such braced material; with such a list as argument the \fexpan sion will only +hit against the first opening brace, hence do nothing, and the braced stuff may +thus be macros one does not want to expand. +% +\leftedline{|\edef\x{\xintRevWithBraces{12345}}|} +% +\leftedline{|\meaning\x:|\dtt{\meaning\X}} +% +\leftedline{|\edef\y{\xintRevWithBraces\x}|} % -\footnote{\label{fn:xintiiMON}\csbxint{iiMON} is like \csbxint{MON} but - does not parse its argument through \csbxint{Num}, for efficiency; - other macros of this type are \csbxint{iiAdd}, \csbxint{iiMul}, - \csbxint{iiSum}, \csbxint{iiPrd}, \csbxint{iiMMON}, \csbxint{iiLDg}, - \csbxint{iiFDg}, \csbxint{iiOdd}, \dots} +\leftedline{|\meaning\y:|\dtt{\meaning\y}} +% +The examples above could be defined with |\edef|'s because the braced material +did not contain macros. Alternatively: +% +\leftedline{|\expandafter\def\expandafter\w\expandafter|} +% +\leftedline{|{\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}}|} +% +\leftedline{|\meaning\w:|\dtt{\meaning\w}} +% +The macro \csa{xintReverseWithBracesNoExpand}\etype{n} does the same job +without the initial expansion of its argument. -\begin{everbatim*} -\def\coeff #1{\xintiiMON{#1}/#1.5} % (-1)^n/(n+1/2) -\fdef\w {\xintSeries {0}{50}{\coeff}} % we want to re-use it -\fdef\z {\xintJrr {\w}[0]} % the [0] for a microsecond gain. -% \xintJrr preferred to \xintIrr: a big common factor is suspected. -% But numbers much bigger would be needed to show the greater efficiency. -\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} = \xintFrac\z \] -\end{everbatim*} -The definition of |\coeff| as |\xintiiMON{#1}/#1.5| is quite suboptimal. It -allows |#1| to be a big integer, but anyhow only small integers are accepted -as initial and final indices (they are of the \numx{} type). Second, when the -\xintfracname parser sees the |#1.5| it will remove the dot hence create a -denominator with one digit more. For example |1/3.5| turns internally into -|10/35| whereas it would be more efficient to have |2/7|. For info here is the -non-reduced |\w|: -\[\xintFrac\w\] -It would have been bigger still in releases earlier than |1.1|: now, the -\xintfracname \csbxint{Add} routine does not multiply blindly denominators -anymore, it checks if one is a multiple of the other. However it does not -practice systematic reduction to lowest terms. +\subsection{\csbh{xintZapFirstSpaces}, \csbh{xintZapLastSpaces}, \csbh{xintZapSpaces}, \csbh{xintZapSpacesB}} +\label{xintZapFirstSpaces} +\label{xintZapLastSpaces} +\label{xintZapSpaces} +\label{xintZapSpacesB} +%{\small New with release |1.09f|.\par} -A more efficient way to code |\coeff| is illustrated next. -\begin{everbatim*} -\def\coeff #1{\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}% -% The [0] in \coeff is a tiny optimization: in its presence the \xintfracname parser -% sees something which is already in internal format. -\fdef\w {\xintSeries {0}{50}{\coeff}} -\[\sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12}=\xintFrac\w\] -\end{everbatim*} -The reduced form |\z| as displayed above only differs from this one by a -factor of \dtt{\xintNum {\xintDenominator\w/\xintDenominator\z}}. +\csa{xintZapFirstSpaces}\marg{stuff}\etype{n} does not do \emph{any} expansion +of its argument, nor brace removal of any sort, nor does it alter \meta{stuff} +in anyway apart from stripping away all \emph{leading} spaces. -\setlength{\columnsep}{0pt} -\everb|@ -\def\coeffleibnitz #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]} -\cnta 1 -\loop % in this loop we recompute from scratch each partial sum! -% we can afford that, as \xintSeries is fast enough. -\noindent\hbox to 2em{\hfil\texttt{\the\cnta.} }% - \xintTrunc {12}{\xintSeries {1}{\cnta}{\coeffleibnitz}}\dots -\endgraf -\ifnum\cnta < 30 \advance\cnta 1 \repeat -| +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.} -\begin{multicols}{3} - \def\coeffleibnitz #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]} \cnta 1 - \loop - \noindent\hbox to 2em{\hfil\dtt{\the\cnta.} }% - \xintTrunc {12}{\xintSeries {1}{\cnta}{\coeffleibnitz}}\dots - \endgraf - \ifnum\cnta < 30 \advance\cnta 1 \repeat -\end{multicols} +\TeX's input scanner already converts consecutive blanks into single space +tokens, but |\xintZapFirstSpaces| handles successfully also inputs with +consecutive multiple space tokens. +However, it is assumed that \meta{stuff} does not contain (except inside braced +sub-material) space tokens of character code distinct from $32$. -\subsection{\csbh{xintiSeries}}\label{xintiSeries} +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}}|. -\def\coeff #1{\xintiTrunc {40} - {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% +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. -\csa{xintiSeries}|{A}{B}{\coeff}|\etype{\numx\numx f} computes - $\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}| where |\coeff{n}| - must \fexpan d to a (possibly long) integer in the strict format. -\everb|@ -\def\coeff #1{\xintiTrunc {40}{\xintMON{#1}/#1.5}}% -% better: -\def\coeff #1{\xintiTrunc {40} - {\the\numexpr 2*\xintiiMON{#1}\relax/\the\numexpr 2*#1+1\relax [0]}}% -% better still: -\def\coeff #1{\xintiTrunc {40} - {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% -% (-1)^n/(n+1/2) times 10^40, truncated to an integer. -\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx - \xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\dots\] -| +\begingroup +\def\x { \a { \X } { \b \Y } } +% +\leftedline{|\xintZapFirstSpaces { \a { \X } { \b \Y } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}}+++} +\endgroup -\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx \xintTrunc -{40}{\xintiSeries {0}{50}{\coeff}[-40]}\] +\medskip -We should have cut out at -least the last two digits: truncating errors originating with the first -coefficients of the sum will never go away, and each truncation -introduces an uncertainty in the last digit, so as we have 40 terms, we -should trash the last two digits, or at least round at 38 digits. It is -interesting to compare with the computation where rounding rather than -truncation is used, and with the decimal -expansion of the exactly computed partial sum of the series: -\everb|@ -\def\coeff #1{\xintiRound {40} % rounding at 40 - {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% -% (-1)^n/(n+1/2) times 10^40, rounded to an integer. -\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx - \xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\] -\def\exactcoeff #1% - {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}% -\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} - = \xintTrunc {50}{\xintSeries {0}{50}{\exactcoeff}}\dots\] -| +\noindent\csbxint{ZapLastSpaces}\marg{stuff}\etype{n} does not do \emph{any} expansion of +its argument, nor brace removal of any sort, nor does it alter \meta{stuff} in +anyway apart from stripping away all \emph{ending} spaces. The same remarks as +for \csbxint{ZapFirstSpaces} apply. -\def\coeff #1{\xintiRound {40} - {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}}% -% (-1)^n/(n+1/2) times 10^40, rounded to an integer. -\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} \approx - \xintTrunc {40}{\xintiSeries {0}{50}{\coeff}[-40]}\] -\def\exactcoeff #1% - {\the\numexpr\ifodd #1 -2\else2\fi\relax/\the\numexpr 2*#1+1\relax [0]}% -\[ \sum_{n=0}^{n=50} \frac{(-1)^n}{n+\frac12} - = \xintTrunc {50}{\xintSeries {0}{50}{\exactcoeff}}\dots\] -This shows indeed that our sum of truncated terms -estimated wrongly the 39th and 40th digits of the exact result% -% -\footnote{as the series is alternating, we can roughly expect an error - of $\sqrt{40}$ and the last two digits are off by 4 units, which is - not contradictory to our expectations.} +% ATTENTION à l'\ignorespaces fait par \color! +\begingroup +\def\x { \a { \X } { \b \Y } } % -and that the sum of rounded terms fared a bit better. +\leftedline{|\xintZapLastSpaces { \a { \X } { \b \Y } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzaplastspaces\expandafter{\x}}}+++} +\endgroup -\subsection{\csbh{xintRationalSeries}}\label{xintRationalSeries} +\medskip +\noindent\csbxint{ZapSpaces}\marg{stuff}\etype{n} does not do \emph{any} +expansion of its +argument, nor brace removal of any sort, nor does it alter \meta{stuff} in +anyway apart from stripping away all \emph{leading} and all \emph{ending} +spaces. The same remarks as for \csbxint{ZapFirstSpaces} apply. -\noindent \csa{xintRationalSeries}|{A}{B}{f}{\ratio}|\etype{\numx\numx\Ff\Ff} -evaluates $\sum_{\text{|n=A|}}^{\text{|n=B|}}$|F(n)|, where |F(n)| is specified -indirectly via the data of |f=F(A)| and the one-parameter macro |\ratio| which -must be such that |\macro{n}| expands to |F(n)/F(n-1)|. The name indicates that -\csa{xintRationalSeries} was designed to be useful in the cases where -|F(n)/F(n-1)| is a rational function of |n| but it may be anything expanding to -a fraction. The macro |\ratio| must be an expandable-only compatible macro and -expand to its value after iterated full expansion of its first token. |A| and -|B| are fed to a |\numexpr| hence may be count registers or arithmetic -expressions built with such; they must obey the \TeX{} bound. The initial term -|f| may be a macro |\f|, it will be expanded to its value representing |F(A)|. +\begingroup +\def\x { \a { \X } { \b \Y } } +% +\leftedline{|\xintZapSpaces { \a { \X } { \b \Y } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapspaces\expandafter{\x}}}+++} +\endgroup -\begin{everbatim*} -\def\ratio #1{2/#1[0]}% 2/n, to compute exp(2) -\cnta 0 % previously declared count -\begin{quote} -\loop \fdef\z {\xintRationalSeries {0}{\cnta}{1}{\ratio }}% -\noindent$\sum_{n=0}^{\the\cnta} \frac{2^n}{n!}= - \xintTrunc{12}\z\dots= - \xintFrac\z=\xintFrac{\xintIrr\z}$\vtop to 5pt{}\par -\ifnum\cnta<20 \advance\cnta 1 \repeat -\end{quote} -\end{everbatim*} +\medskip -\begin{everbatim*} -\def\ratio #1{-1/#1[0]}% -1/n, comes from the series of exp(-1) -\cnta 0 % previously declared count -\begin{quote} -\loop -\fdef\z {\xintRationalSeries {0}{\cnta}{1}{\ratio }}% -\noindent$\sum_{n=0}^{\the\cnta} \frac{(-1)^n}{n!}= - \xintTrunc{20}\z\dots=\xintFrac{\z}=\xintFrac{\xintIrr\z}$% - \vtop to 5pt{}\par -\ifnum\cnta<20 \advance\cnta 1 \repeat -\end{quote} -\end{everbatim*} +\noindent\csbxint{ZapSpacesB}\marg{stuff}\etype{n} does not do \emph{any} +expansion of +its argument, nor does it alter \meta{stuff} in anyway apart from stripping away +all leading and all ending spaces and possibly removing one level of braces if +\meta{stuff} had the shape |{braced}|. The same remarks as for +\csbxint{ZapFirstSpaces} apply. +\begingroup +\def\x { \a { \X } { \b \Y } } +% +\leftedline{|\xintZapSpacesB { \a { \X } { \b \Y } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++} +\def\x { { \a { \X } { \b \Y } } } +% +\leftedline{|\xintZapSpacesB { { \a { \X } { \b \Y } } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++} +\endgroup + The spaces here at the start and end of the output come from the braced + material, and are not removed (one would need a second application for that; + recall though that the \xintname zapping macros do not expand their argument). - \def\ratioexp #1#2{\xintDiv{#1}{#2}}% #1/#2 +\subsection{\csbh{xintCSVtoList}} +\label{xintCSVtoList} +\label{xintCSVtoListNoExpand} -\medskip We can incorporate an indeterminate if we define |\ratio| to be -a macro with two parameters: |\def\ratioexp - #1#2{\xintDiv{#1}{#2}}|\texttt{\%}| x/n: x=#1, n=#2|. -Then, if |\x| expands to some fraction |x|, the -macro % -% -\leftedline{|\xintRationalSeries {0}{b}{1}{\ratioexp{\x}}|} -will compute $\sum_{n=0}^{n=b} x^n/n!$:\par -\begin{everbatim*} -\cnta 0 -\def\ratioexp #1#2{\xintDiv{#1}{#2}}% #1/#2 -\loop -\noindent -$\sum_{n=0}^{\the\cnta} (.57)^n/n! = \xintTrunc {50} - {\xintRationalSeries {0}{\cnta}{1}{\ratioexp{.57}}}\dots$ - \vtop to 5pt {}\endgraf -\ifnum\cnta<50 \advance\cnta 10 \repeat -\end{everbatim*} -Observe that in this last example the |x| was directly inserted; if it -had been a more complicated explicit fraction it would have been -worthwile to use |\ratioexp\x| with |\x| defined to expand to its value. -In the further situation where this fraction |x| is not explicit but -itself defined via a complicated, and time-costly, formula, it should be -noted that \csa{xintRationalSeries} will do again the evaluation of |\x| -for each term of the partial sum. The easiest is thus when |x| can be -defined as an |\edef|. If however, you are in an expandable-only context -and cannot store in a macro like |\x| the value to be used, a variant of -\csa{xintRationalSeries} is needed which will first evaluate this |\x| and then -use this result without recomputing it. This is \csbxint{RationalSeriesX}, -documented next. +\csa{xintCSVtoList}|{a,b,c...,z}|\etype{f} returns |{a}{b}{c}...{z}|. A +\emph{list} is by +convention in this manual simply a succession of tokens, where each braced thing +will count as one item (``items'' are defined according to the rules of \TeX{} +for fetching undelimited parameters of a macro, which are exactly the same rules +as for \LaTeX{} and macro arguments [they are the same things]). The word +`list' in `comma separated list of items' has its usual linguistic meaning, +and then an ``item'' is what is delimited by commas. -Here is a slightly more complicated evaluation: -\begin{everbatim*} -\cnta 1 -\begin{multicols}{2} -\loop \fdef\z {\xintRationalSeries - {\cnta} - {2*\cnta-1} - {\xintiPow {\the\cnta}{\cnta}/\xintiiFac{\cnta}} - {\ratioexp{\the\cnta}}}% -\fdef\w {\xintRationalSeries {0}{2*\cnta-1}{1}{\ratioexp{\the\cnta}}}% -\noindent -$\sum_{n=\the\cnta}^{\the\numexpr 2*\cnta-1\relax} \frac{\the\cnta^n}{n!}/% - \sum_{n=0}^{\the\numexpr 2*\cnta-1\relax} \frac{\the\cnta^n}{n!} = - \xintTrunc{8}{\xintDiv\z\w}\dots$ \vtop to 5pt{}\endgraf -\ifnum\cnta<20 \advance\cnta 1 \repeat -\end{multicols} -\end{everbatim*} +So \csa{xintCSVtoList} takes on input a `comma separated list of items' and +converts it into a `\TeX{} list of braced items'. The argument to +|\xintCSVtoList| may be a macro: it will first be +\hyperref[ssec:expansions]{\fexpan ded}. Hence the item before the first comma, +if it is itself a macro, will be expanded which may or may not be a good thing. +A space inserted at the start of the first item serves to stop that expansion +(and disappears). The macro \csbxint{CSVtoListNoExpand}\etype{n} does the same +job without +the initial expansion of the list argument. +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{xintRationalSeriesX}}\label{xintRationalSeriesX} +Contiguous spaces and tab characters, are collapsed by \TeX{} +into single spaces. All such spaces around commas% +% +\footnote{and multiple space tokens are not a problem; but those at the + top level (not hidden inside braces) \emph{must} be of character code + |32|.} +% +\fbox{are removed}, as well as +the spaces at the start and the spaces at the end of the list.% +% +\footnote{let us recall that this is all done completely expandably... + There is absolutely no alteration of any sort of the item apart from + the stripping of initial and final space tokens (of character code + |32|) and brace removal if and only if the item apart from intial and + final spaces (or more generally multiple |char 32| space tokens) is + braced.} +% +The items may contain explicit |\par|'s or +empty lines (converted by the \TeX{} input parsing into |\par| tokens). +\begingroup -\noindent\csa{xintRationalSeriesX}|{A}{B}{\first}{\ratio}{\g}|% -\etype{\numx\numx\Ff\Ff f} is a parametrized version of \csa{xintRationalSeries} -where |\first| is now a one-parameter macro such that |\first{\g}| gives the -initial term and |\ratio| is a two-parameter macro such that |\ratio{n}{\g}| -represents the ratio of one term to the previous one. The parameter |\g| is -evaluated only once at the beginning of the computation, and can thus itself be -the yet unevaluated result of a previous computation. +\edef\X{\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , { {x , + y} } }} -Let |\ratio| be such a two-parameter macro; note the subtle differences -between% % -\leftedline{|\xintRationalSeries {A}{B}{\first}{\ratio{\g}}|} +\leftedline{|\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , + { {x , y} } }|} % -\leftedline{and |\xintRationalSeriesX {A}{B}{\first}{\ratio}{\g}|.} First the -location of braces differ... then, in the former case |\first| is a -\emph{no-parameter} macro expanding to a fractional number, and in the latter, -it is a -\emph{one-parameter} macro which will use |\g|. Furthermore the |X| variant -will expand |\g| at the very beginning whereas the former non-|X| former variant -will evaluate it each time it needs it (which is bad if this -evaluation is time-costly, but good if |\g| is a big explicit fraction -encapsulated in a macro). +\leftedline{|->|% +{\makeatletter\dtt{\expandafter\strip@prefix\meaning\X}}} -The example will use the macro \csbxint{PowerSeries} which computes -efficiently exact partial sums of power series, and is discussed in the -next section. -\begin{everbatim*} -\def\firstterm #1{1[0]}% first term of the exponential series -% although it is the constant 1, here it must be defined as a -% one-parameter macro. Next comes the ratio function for exp: -\def\ratioexp #1#2{\xintDiv {#1}{#2}}% x/n -% These are the (-1)^{n-1}/n of the log(1+h) series: -\def\coefflog #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]}% -% Let L(h) be the first 10 terms of the log(1+h) series and -% let E(t) be the first 10 terms of the exp(t) series. -% The following computes E(L(a/10)) for a=1,...,12. -\begin{multicols}{3}\raggedcolumns -\cnta 0 -\loop -\noindent\xintTrunc {18}{% - \xintRationalSeriesX {0}{9}{\firstterm}{\ratioexp} - {\xintPowerSeries{1}{10}{\coefflog}{\the\cnta[-1]}}}\dots -\endgraf -\ifnum\cnta < 12 \advance \cnta 1 \repeat -\end{multicols} -\end{everbatim*} +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. +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. -These completely exact operations rapidly create numbers with many digits. Let -us print in full the raw fractions created by the operation illustrated above: +From the rules above: for an empty argument (only spaces, no braces, no comma) +the output is +\dtt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist { }}} +(a list with one empty item), +for ``|{}|'' the output is +\dtt{\expandafter\detokenize\expandafter + {\romannumeral0\xintcsvtolist { {} }}} +(again a list with one empty item, the braces were removed), +for ``|{ }|'' the output is +\dtt{\expandafter\detokenize\expandafter + {\romannumeral0\xintcsvtolist {{ }}}} +(again a list with one empty item, the braces were removed and then +the inner space was removed), +for ``| { }|'' the output is +\dtt{\expandafter\detokenize\expandafter +{\romannumeral0\xintcsvtolist { { }}}} (again a list with one empty item, the initial space served only to stop the expansion, so this was like ``|{ }|'' as input, the braces were removed and the inner space was stripped), +for ``\texttt{\ \{\ \ \}\ }'' the output is +\dtt{\expandafter\detokenize\expandafter +{\romannumeral0\xintcsvtolist { { } }}} (this time the ending space of the first +item meant that after brace removal the inner spaces were kept; recall though +that \TeX{} collapses on input consecutive blanks into one space token), +for ``|,|'' the output consists of two consecutive +empty items +\dtt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist + {,}}}. Recall that on output everything is braced, a |{}| is an ``empty'' +item. +% +Most of the above is mainly irrelevant for every day use, apart perhaps from the +fact to be noted that an empty input does not give an empty output but a +one-empty-item list (it is as if an ending comma was always added at the end of +the input). -\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} -{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1[-1]}}} +\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}} -|E(L(1[-1]))=|\dtt{\printnumber{\z}} (length of numerator: -\xintLen {\xintNumerator \z}) +% +\leftedline{|\def\y{ \a,\b,\c,\d,\e} \xintCSVtoList\y->|% + {\makeatletter\dtt{\expandafter\strip@prefix\meaning\Y}}} +% +\leftedline{|\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} +% +\leftedline +{|\xintCSVtoList\t->|\makeatletter\dtt{\expandafter\strip@prefix\meaning\T}} +% +The results above were automatically displayed using \TeX's primitive +\csa{meaning}, which adds a space after each control sequence name. These spaces +are not in the actual braced items of the produced lists. The first items |\a| +and |\if| were either preceded by a space or braced to prevent expansion. The +macro \csa{xintCSVtoListNoExpand} would have done the same job without the +initial expansion of the list argument, hence no need for such protection but if +|\y| is defined as |\def\y{\a,\b,\c,\d,\e}| we then must do: +% +\leftedline{|\expandafter\xintCSVtoListNoExpand\expandafter {\y}|} Else, we +may have direct use: % +% +\leftedline{|\xintCSVtoListNoExpand + {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} +% +\leftedline{|->|\dtt{\expandafter\detokenize\expandafter + {\romannumeral0\xintcsvtolistnoexpand + {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}}}} +% +Again these spaces are an artefact from the use in the source of the document of +\csa{meaning} (or rather here, \csa{detokenize}) to display the result of using +\csa{xintCSVtoListNoExpand} (which is done for real in this document +source). -\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} -{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{12[-2]}}} +For the similar conversion from comma separated list to braced items list, but +without removal of spaces around the commas, there is +\csa{xintCSVtoListNonStripped}\etype{f} and +\csa{xintCSVtoListNonStrippedNoExpand}\etype{n}. -|E(L(12[-2]))=|\dtt{\printnumber{\z}} (length of numerator: -\xintLen {\xintNumerator \z}) +\endgroup -\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} -{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{123[-3]}}} +\subsection{\csbh{xintNthElt}}\label{xintNthElt} -|E(L(123[-3]))=|\dtt{\printnumber{\z}} (length of numerator: -\xintLen {\xintNumerator \z}) -We see that the denominators here remain the same, as our input only had various -powers of ten as denominators, and \xintfracname efficiently assemble (some -only, as we can see) powers of ten. Notice that 1 more digit in an input -denominator seems to mean 90 more in the raw output. We can check that with some -other test cases: +\def\macro #1{\the\numexpr 9-#1\relax} -\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} -{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/7}}} +\csa{xintNthElt\x}\marg{list}\etype{\numx f} gets (expandably) the |x|th +item of the \meta{list}. A braced item will lose one level of brace +pairs. The token list is first \fexpan ded. -|E(L(1/7))=|\dtt{\printnumber{\z}} (length of numerator: -\xintLen {\xintNumerator \z}; length of denominator: -\xintLen {\xintDenominator \z}) +Items are counted starting at one. -\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} -{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/71}}} +\leftedline{|\xintNthElt {3}{{agh}\u{zzz}\v{Z}}| is + \texttt{\xintNthElt {3}{{agh}\u{zzz}\v{Z}}}} +% +\leftedline{|\xintNthElt {3}{{agh}\u{{zzz}}\v{Z}}| is + \texttt{\expandafter\expandafter\expandafter + \detokenize\expandafter\expandafter\expandafter {\xintNthElt + {3}{{agh}\u{{zzz}}\v{Z}}}}} +% +\leftedline{|\xintNthElt {2}{{agh}\u{{zzz}}\v{Z}}| is + \texttt{\expandafter\expandafter\expandafter + \detokenize\expandafter\expandafter\expandafter {\xintNthElt + {2}{{agh}\u{{zzz}}\v{Z}}}}} +% +\leftedline{|\xintNthElt {37}{\xintiiFac {100}}|\dtt{=\xintNthElt + {37}{\xintiiFac {100}}} is the thirty-seventh digit of $100!$.} +% +\leftedline{|\xintNthElt {10}{\xintFtoCv + {566827/208524}}|\dtt{=\xintNthElt {10}{\xintFtoCv + {566827/208524}}}} +\leftedline{is the tenth convergent of $566827/208524$ (uses \xintcfracname + package).} +% +\leftedline{|\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% + \dtt{=\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} +% +\leftedline{|\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% + \dtt{=\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} +% +\leftedline{|\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% + \dtt{=\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} -|E(L(1/71))=|\dtt{\printnumber{\z}} (length of numerator: -\xintLen {\xintNumerator \z}; length of denominator: -\xintLen {\xintDenominator \z}) +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. -\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm} -{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/712}}} +If |x<0|, the macro returns the \verb+|x|+th element from the end of the list. +Thus for example |x=-1| will fetch the last item of the list. +% +\leftedline {|\xintNthElt {-5}{{{agh}}\u{zzz}\v{Z}}| is + \texttt{\expandafter\expandafter\expandafter \detokenize + \expandafter\expandafter\expandafter{\xintNthElt {-5}{{{agh}}\u{zzz}\v{Z}}}}} -|E(L(1/712))=|\dtt{\printnumber{\z}} (length of numerator: -\xintLen {\xintNumerator \z}; length of denominator: -\xintLen {\xintDenominator \z}) +The macro \csa{xintNthEltNoExpand}\etype{\numx n} does the same job but without +first expanding the list argument: |\xintNthEltNoExpand {-4}{\u\v\w T\x\y\z}| is +\xintNthEltNoExpand {-4}{\a\b\c\u\v\w T\x\y\z}. +If |x| is strictly larger (in absolute value) than the length of the list +then |\xintNthElt| produces empty contents. -Thus -decimal numbers such as |0.123| (equivalently -|123[-3]|) give less computing intensive tasks than fractions such as |1/712|: -in the case of decimal numbers the (raw) denominators originate in the -coefficients of the series themselves, powers of ten of the input within -brackets being treated separately. And even then the -numerators will grow with the size of the input in a sort of linear way, the -coefficient being given by the order of series: here 10 from the log and 9 from -the exp, so 90. One more digit in the input means 90 more digits in the -numerator of the output: obviously we can not go on composing such partial sums -of series and hope that \xintname will joyfully do all at the speed of light! +\subsection{\csbh{xintKeep}}\label{xintKeep} -Hence, truncating the output (or better, rounding) is the only way to go if one -needs a general calculus of special functions. This is why the package -\xintseriesname provides, besides \csbxint{Series}, \csbxint{RationalSeries}, or -\csbxint{PowerSeries} which compute \emph{exact} sums, -\csbxint{FxPtPowerSeries} for fixed-point computations and a (tentative naive) -\csbxint{FloatPowerSeries}. +\csa{xintKeep\x}\marg{list}\etype{\numx f} expands the token list argument |L| +and produces a new list, depending on the value of |x|: +\begin{itemize}[nosep] +\item if |x>0|, the new list contains the first |x| items from |L| (counting + starts at one.) \emph{Each + such item will be output within a brace pair.} Use \csbxint{KeepUnbraced} is + this is not desired. This means that if the list item was braced to start + with, there is no modification, but if it was a token without braces, + then it acquires them. +\item if |x>=length(L)|, the new list is the old one with all its items now + braced. +\item if |x=0| the empty list is returned. +\item if |x<0| the last \verb+|x|+ elements compose the output in the same + order as in the initial list; as the macro proceeds by removing head items + the kept items end up in output as they were in input: no added braces. +\item if |x<=-length(L)| the output is identical with the input. +\end{itemize} -\subsection{\csbh{xintPowerSeries}}\label{xintPowerSeries} +\csa{xintKeepNoExpand} does the same without first \fexpan ding its list +argument. +% +\begin{everbatim*} +\fdef\test {\xintKeep {17}{\xintKeep {-69}{\xintSeq {1}{100}}}}\meaning\test\par +\noindent\fdef\test {\xintKeep {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintKeep {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintKeep {7}{123456789}}\meaning\test\par +\noindent\fdef\test {\xintKeep {-7}{123456789}}\meaning\test\par +\end{everbatim*} -\csa{xintPowerSeries}|{A}{B}{\coeff}{f}|\etype{\numx\numx\Ff\Ff} -evaluates the sum -$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot |f|^{\text{|n|}}$. The -initial and final indices are given to a |\numexpr| expression. The |\coeff| -macro (which, as argument to \csa{xintPowerSeries} is expanded only at the time -|\coeff{n}| is needed) should be defined as a one-parameter expandable macro, -its input will be an explicit number. -The |f| can be either a fraction directly input or a macro |\f| expanding to -such a fraction. It is actually more efficient to encapsulate an explicit -fraction |f| in such a macro, if it has big numerators and denominators (`big' -means hundreds of digits) as it will then take less space in the processing -until being (repeatedly) used. +\subsection{\csbh{xintKeepUnbraced}}\label{xintKeepUnbraced} -This macro computes the \emph{exact} result (one can use it also for -polynomial evaluation), using a Horner scheme which helps avoiding a -denominator build-up (this problem however, even if using a naive additive -approach, is much less acute since release |1.1| and its new policy regarding -\csbxint{Add}). +Same as \csbxint{Keep} but no brace pairs are added around the kept items from +the head of the list in the case |x>0|: each such item will lose one level of +braces. Thus, to remove braces from all items of the list, one can use +\csbxint{KeepUnbraced} with its first argument larger than the length of the +list; the same is obtained from \csbxint{ListWithSep}|{}|\marg{list}. But the +new list will then have generally many more items than the original ones, +corresponding to the unbraced original items. -\begin{everbatim*} -\def\geom #1{1[0]} % the geometric series -\def\f {5/17[0]} -\[ \sum_{n=0}^{n=20} \Bigl(\frac 5{17}\Bigr)^n - =\xintFrac{\xintIrr{\xintPowerSeries {0}{20}{\geom}{\f}}} - =\xintFrac{\xinttheexpr (17^21-5^21)/12/17^20\relax}\] -\end{everbatim*} +For |x<0| the macro is no different from \csbxint{Keep}. Hence the name is a +bit misleading because brace removal will happen only if |x>0|. +\csa{xintKeepUnbracedNoExpand} does the same without first \fexpan ding +its list argument. +% \begin{everbatim*} -\def\coefflog #1{1/#1[0]}% 1/n -\def\f {1/2[0]}% -\[ \log 2 \approx \sum_{n=1}^{20} \frac1{n\cdot 2^n} - = \xintFrac {\xintIrr {\xintPowerSeries {1}{20}{\coefflog}{\f}}}\] -\[ \log 2 \approx \sum_{n=1}^{50} \frac1{n\cdot 2^n} - = \xintFrac {\xintIrr {\xintPowerSeries {1}{50}{\coefflog}{\f}}}\] +\fdef\test {\xintKeepUnbraced {10}{\xintSeq {1}{100}}}\meaning\test\par +\noindent\fdef\test {\xintKeepUnbraced {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintKeepUnbraced {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintKeepUnbraced {7}{123456789}}\meaning\test\par +\noindent\fdef\test {\xintKeepUnbraced {-7}{123456789}}\meaning\test\par \end{everbatim*} +\subsection{\csbh{xintTrim}}\label{xintTrim} + +\csa{xintTrim\x}\marg{list}\etype{\numx f} expands the list argument and +gobbles its first |x| elements. +\begin{itemize}[nosep] +\item if |x>0|, the first |x| items from |L| are gobbled. The remaining items + are not modified. +\item if |x>=length(L)|, the returned list is empty. +\item if |x=0| the original list is returned (with no added braces.) +\item if |x<0| the last \verb+|x|+ items of the list are removed. \emph{The + head items end up braced in the output.} Use \csbxint{TrimUnbraced} if + this is not desired. +\item if |x<=-length(L)| the output is empty. +\end{itemize} +\csa{xintTrimNoExpand} does the same without first \fexpan ding its list +argument. \begin{everbatim*} -\setlength{\columnsep}{0pt} -\begin{multicols}{3} -\cnta 1 % previously declared count -\loop % in this loop we recompute from scratch each partial sum! -% we can afford that, as \xintPowerSeries is fast enough. -\noindent\hbox to 2em{\hfil\texttt{\the\cnta.} }% - \xintTrunc {12} - {\xintPowerSeries {1}{\cnta}{\coefflog}{\f}}\dots -\endgraf -\ifnum \cnta < 30 \advance\cnta 1 \repeat -\end{multicols} +\fdef\test {\xintTrim {17}{\xintTrim {-69}{\xintSeq {1}{100}}}}\meaning\test\par +\noindent\fdef\test {\xintTrim {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintTrim {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintTrim {7}{123456789}}\meaning\test\par +\noindent\fdef\test {\xintTrim {-7}{123456789}}\meaning\test\par \end{everbatim*} +\subsection{\csbh{xintTrimUnbraced}}\label{xintTrimUnbraced} + +Same as \csbxint{Trim} but in case of a negative |x| (cutting items from +the tail), the kept items from the head are not enclosed in brace pairs. They +will lose one level of braces. The name is a bit misleading +because when |x>0| there is no brace-stripping done on the kept items, because +the macro works simply by gobbling the head ones. + +\csa{xintTrimUnbracedNoExpand} does the same without first \fexpan ding its list +argument. \begin{everbatim*} -\def\coeffarctg #1{1/\the\numexpr\ifodd #1 -2*#1-1\else2*#1+1\fi\relax }% -% the above gives (-1)^n/(2n+1). The sign being in the denominator, -% **** no [0] should be added ****, -% else nothing is guaranteed to work (even if it could by sheer luck) -% Notice in passing this aspect of \numexpr: -% **** \numexpr -(1)\relax is ilegal !!! **** -\def\f {1/25[0]}% 1/5^2 -\[\mathrm{Arctg}(\frac15)\approx \frac15\sum_{n=0}^{15} \frac{(-1)^n}{(2n+1)25^n} -= \xintFrac{\xintIrr {\xintDiv {\xintPowerSeries {0}{15}{\coeffarctg}{\f}}{5}}}\] +\fdef\test {\xintTrimUnbraced {-90}{\xintSeq {1}{100}}}\meaning\test\par +\noindent\fdef\test {\xintTrimUnbraced {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintTrimUnbraced {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintTrimUnbraced {7}{123456789}}\meaning\test\par +\noindent\fdef\test {\xintTrimUnbraced {-7}{123456789}}\meaning\test\par \end{everbatim*} +\subsection{\csbh{xintListWithSep}}\label{xintListWithSep} -\subsection{\csbh{xintPowerSeriesX}}\label{xintPowerSeriesX} -%{\small\hspace*{\parindent}New with release |1.04|.\par} +\def\macro #1{\the\numexpr 9-#1\relax} -\noindent This is the same as \csbxint{PowerSeries}\ntype{\numx\numx\Ff\Ff} -apart -from the fact that the last parameter |f| is expanded once and for all before -being then used repeatedly. If the |f| parameter is to be an explicit big -fraction with many (dozens) digits, rather than using it directly it is slightly -better to have some macro |\g| defined to expand to the explicit fraction and -then use \csbxint{PowerSeries} with |\g|; but if |f| has not yet been evaluated -and will be the output of a complicated expansion of some |\f|, and if, due to -an expanding only context, doing |\edef\g{\f}| is no option, then -\csa{xintPowerSeriesX} should be used with |\f| as last parameter. -% +\csa{xintListWithSep}|{sep}|\marg{list}\etype{nf} inserts the separator |sep| +in-between all items of the given list. The items will be unbraced. The +separator may be a macro but will not be pre-expanded. The list argument is +\fexpan ded. \begin{everbatim*} -\def\ratioexp #1#2{\xintDiv {#1}{#2}}% x/n -% These are the (-1)^{n-1}/n of the log(1+h) series: -\def\coefflog #1{\the\numexpr\ifodd #1 1\else-1\fi\relax/#1[0]}% -% Let L(h) be the first 10 terms of the log(1+h) series and -% let E(t) be the first 10 terms of the exp(t) series. -% The following computes L(E(a/10)-1) for a=1,..., 12. -\begin{multicols}{3}\raggedcolumns -\cnta 1 -\loop -\noindent\xintTrunc {18}{% - \xintPowerSeriesX {1}{10}{\coefflog} - {\xintSub - {\xintRationalSeries {0}{9}{1[0]}{\ratioexp{\the\cnta[-1]}}} - {1}}}\dots -\endgraf -\ifnum\cnta < 12 \advance \cnta 1 \repeat -\end{multicols} +\edef\foo {\xintListWithSep{,}{{1}{2}{3}}}\meaning\foo\newline +\edef\foo {\xintListWithSep{:}{\xintiiFac{20}}}\meaning\foo\par \end{everbatim*} +An empty input gives an empty output, a singleton gives a singleton, and the +separator is used starting with at least two elements. Using an empty +separator has the net effect of unbracing the braced items constituting the +\meta{list} (then the new list will generally have many more ``items'' than +the original one). +% +The macro \csa{xintListWithSepNoExpand}\etype{nn} does the same +job without the initial expansion. -\subsection{\csbh{xintFxPtPowerSeries}}\label{xintFxPtPowerSeries} +\subsection{\csbh{xintApply}}\label{xintApply} -\csa{xintFxPtPowerSeries}|{A}{B}{\coeff}{f}{D}|\etype{\numx\numx} -computes -$\sum_{\text{|n=A|}}^{\text{|n=B|}}$|\coeff{n}|${}\cdot |f|^{\,\text{|n|}}$ with each - term of the series truncated to |D| digits\etype{\Ff\Ff\numx} - after the decimal point. As - usual, |A| and |B| are completely expanded through their inclusion in a - |\numexpr| expression. Regarding |D| it will be similarly be expanded each - time it is used inside an \csa{xintTrunc}. The one-parameter macro |\coeff| - is similarly expanded at the time it is used inside the - computations. Idem for |f|. If |f| itself is some complicated macro it is - thus better to use the variant \csbxint{FxPtPowerSeriesX} which expands it - first and then uses the result of that expansion. -The current (|1.04|) implementation is: the first power |f^A| is -computed exactly, then \emph{truncated}. Then each successive power is -obtained from the previous one by multiplication by the exact value of -|f|, and truncated. And |\coeff{n}|\raisebox{.5ex}{|.|}|f^n| is obtained -from that by multiplying by |\coeff{n}| (untruncated) and then -truncating. Finally the sum is computed exactly. Apart from that -\csa{xintFxPtPowerSeries} (where |FxPt| means `fixed-point') is like -\csa{xintPowerSeries}. +\def\macro #1{\the\numexpr 9-#1\relax} -There should be a variant for things of the type $\sum c_n \frac {f^n}{n!}$ to -avoid having to compute the factorial from scratch at each coefficient, the same -way \csa{xintFxPtPowerSeries} does not compute |f^n| from scratch at each |n|. -Perhaps in the next package release. +\csa{xintApply}|{\macro}|\marg{list}\etype{ff} expandably applies the one +parameter macro |\macro| to each item in the \meta{list} given as second +argument and returns a new list with these outputs: each item is given one after +the other as parameter to |\macro| which is expanded at that time (as usual, +\emph{i.e.} fully for what comes first), the results are braced and output +together as a succession of braced items (if |\macro| is defined to start with a +space, the space will be gobbled and the |\macro| will not be expanded; it is +allowed to have its own arguments, the list items serve as last arguments to +|\macro|). Hence |\xintApply{\macro}{{1}{2}{3}}| returns +|{\macro{1}}{\macro{2}}{\macro{3}}| where all instances of |\macro| have been +already \fexpan ded. -\def\coeffexp #1{1/\xintiiFac {#1}[0]}% [0] for faster parsing -\def\f {-1/2[0]}% -\newcount\cnta +Being expandable, |\xintApply| is useful for example inside alignments where +implicit groups make standard loops constructs usually fail. In such situation +it is often not wished that the new list elements be braced, see +\csbxint{ApplyUnbraced}. The |\macro| does not have to be expandable: +|\xintApply| will try to expand it, the expansion may remain partial. -\setlength{\multicolsep}{0pt} +The \meta{list} may +itself be some macro expanding (in the previously described way) to the list of +tokens to which the macro |\macro| will be applied. For example, if the +\meta{list} expands to some positive number, then each digit will be replaced by +the result of applying |\macro| on it. % +% +\leftedline{|\def\macro #1{\the\numexpr + 9-#1\relax}|} % +% +\leftedline{|\xintApply\macro{\xintiiFac + {20}}|\dtt{=\xintApply\macro{\xintiiFac {20}}}} -\begin{multicols}{3}[% -\centeredline{$e^{-\frac12}\approx{}$}]% -\cnta 0 -\noindent\loop -$\xintFxPtPowerSeries {0}{\cnta}{\coeffexp}{\f}{20}$\\ -\ifnum\cnta<19 -\advance\cnta 1 -\repeat\par -\end{multicols} -\everb|@ -\def\coeffexp #1{1/\xintiiFac {#1}[0]}% 1/n! -\def\f {-1/2[0]}% [0] for faster input parsing -\cnta 0 % previously declared \count register -\noindent\loop -$\xintFxPtPowerSeries {0}{\cnta}{\coeffexp}{\f}{20}$\\ -\ifnum\cnta<19 \advance\cnta 1 \repeat\par -| +The macro \csa{xintApplyNoExpand}\etype{fn} does the same job without the first +initial expansion which gave the \meta{list} of braced tokens to which |\macro| +is applied. + +\subsection{\csbh{xintApplyUnbraced}}\label{xintApplyUnbraced} +\csa{xintApplyUnbraced}|{\macro}|\marg{list}\etype{ff} is like \csbxint{Apply}. +The difference is that after having expanded its list argument, and applied +|\macro| in turn to each item from the list, it reassembles the outputs without +enclosing them in braces. The net effect is the same as doing % -\leftedline{|\xintFxPtPowerSeries {0}{19}{\coeffexp}{\f}{25}=| -\dtt{\xintFxPtPowerSeries {0}{19}{\coeffexp}{\f}{25}}} -\fdef\z{\xintIrr {\xintPowerSeries {0}{19}{\coeffexp}{\f}}} +\leftedline{|\xintListWithSep {}{\xintApply {\macro}|\marg{list}|}|} This is +useful for preparing a macro which will itself define some other macros or make +assignments, as the scope will not be limited by brace pairs. % +\begin{everbatim*} +\def\macro #1{\expandafter\def\csname myself#1\endcsname {#1}} +\xintApplyUnbraced\macro{{elta}{eltb}{eltc}} +\begin{enumerate}[nosep,label=(\arabic{*})] +\item \meaning\myselfelta +\item \meaning\myselfeltb +\item \meaning\myselfeltc +\end{enumerate} +\end{everbatim*} -\texttt{\hyphenchar\font45 }% -It is no difficulty for \xintfracname to compute exactly, with the help -of \csa{xintPowerSeries}, the nineteenth partial sum, and to then give -(the start of) its exact decimal expansion: -% -\leftedline{|\xintPowerSeries {0}{19}{\coeffexp}{\f}| ${}= - \displaystyle\xintFrac{\z}$% - \vphantom{\vrule height 20pt depth 12pt}}% % -\leftedline{${}=\xintTrunc {30}{\z}\dots$} Thus, one should always -estimate a priori how many ending digits are not reliable: if there are -|N| terms and |N| has |k| digits, then digits up to but excluding the -last |k| may usually be trusted. If we are optimistic and the series is -alternating we may even replace |N| with $\sqrt{|N|}$ to get the number |k| -of digits possibly of dubious significance. +The macro \csa{xintApplyUnbracedNoExpand}\etype{fn} does the same job without +the first initial expansion which gave the \meta{list} of braced tokens to which +|\macro| is applied. -\subsection{\csbh{xintFxPtPowerSeriesX}}\label{xintFxPtPowerSeriesX} +\subsection{\csbh{xintSeq}}\label{xintSeq} +\csa{xintSeq}|[d]{x}{y}|\etype{{{\upshape[\numx]}}\numx\numx} generates +expandably |{x}{x+d}...| up to and possibly including |{y}| if |d>0| or down +to and including |{y}| if |d<0|. Naturally |{y}| is omitted if |y-x| is not a +multiple of |d|. If |d=0| the macro returns |{x}|. If |y-x| and |d| have +opposite signs, the macro returns nothing. If the optional argument |d| is +omitted it is taken to be the sign of |y-x|. Hence |\xintSeq {1}{0}| is not +empty but |{1}{0}|. But |\xintSeq [1]{1}{0}| is empty. -\noindent\csa{xintFxPtPowerSeriesX}|{A}{B}{\coeff}{\f}{D}|% -\ntype{\numx\numx} -computes, exactly as -\csa{xintFxPtPowerSeries}, the sum of -|\coeff{n}|\raisebox{.5ex}{|.|}|\f^n|\etype{\Ff\Ff\numx} from |n=A| to |n=B| with each term -of the series being \emph{truncated} to |D| digits after the decimal -point. The sole difference is that |\f| is first expanded and it -is the result of this which is used in the computations. +The arguments |x| and |y| are expanded inside a |\numexpr| so they may be +count registers or a \LaTeX{} |\value{countername}|, or arithmetic with such +things. -Let us illustrate this on the numerical exploration of the identity -% -\leftedline{|log(1+x) = -log(1/(1+x))|} % -Let |L(h)=log(1+h)|, and |D(h)=L(h)+L(-h/(1+h))|. Theoretically thus, -|D(h)=0| but we shall evaluate |L(h)| and |-h/(1+h)| keeping only 10 -terms of their respective series. We will assume $|h|<0.5$. With only -ten terms kept in the power series we do not have quite 3 digits -precision as $2^{10}=1024$. So it wouldn't make sense to evaluate things -more precisely than, say circa 5 digits after the decimal points. \begin{everbatim*} -\cnta 0 -\def\coefflog #1{\the\numexpr\ifodd#1 1\else-1\fi\relax/#1[0]}% (-1)^{n-1}/n -\def\coeffalt #1{\the\numexpr\ifodd#1 -1\else1\fi\relax [0]}% (-1)^n -\begin{multicols}2 -\loop -\noindent \hbox to 2.5cm {\hss\texttt{D(\the\cnta/100): }}% -\xintAdd {\xintFxPtPowerSeriesX {1}{10}{\coefflog}{\the\cnta [-2]}{5}} - {\xintFxPtPowerSeriesX {1}{10}{\coefflog} - {\xintFxPtPowerSeriesX {1}{10}{\coeffalt}{\the\cnta [-2]}{5}} - {5}}\endgraf -\ifnum\cnta < 49 \advance\cnta 7 \repeat -\end{multicols} +\xintListWithSep{,\hskip2pt plus 1pt minus 1pt }{\xintSeq {12}{-25}} \end{everbatim*} - - -Let's say we evaluate functions on |[-1/2,+1/2]| with values more or less also -in |[-1/2,+1/2]| and we want to keep 4 digits of precision. So, roughly we need -at least 14 terms in series like the geometric or log series. Let's make this -15. Then it doesn't make sense to compute intermediate summands with more than 6 -digits precision. So we compute with 6 digits -precision but return only 4 digits (rounded) after the decimal point. -This result with 4 post-decimal points precision is then used as input -to the next evaluation. +% \begin{everbatim*} -\begin{multicols}2 -\loop -\noindent \hbox to 2.5cm {\hss\texttt{D(\the\cnta/100): }}% -\dtt{\xintRound{4} - {\xintAdd {\xintFxPtPowerSeriesX {1}{15}{\coefflog}{\the\cnta [-2]}{6}} - {\xintFxPtPowerSeriesX {1}{15}{\coefflog} - {\xintRound {4}{\xintFxPtPowerSeriesX {1}{15}{\coeffalt} - {\the\cnta [-2]}{6}}} - {6}}% - }}\endgraf -\ifnum\cnta < 49 \advance\cnta 7 \repeat -\end{multicols} +\xintiiSum{\xintSeq [3]{1}{1000}} \end{everbatim*} -Not bad... I have cheated a bit: the `four-digits precise' numeric -evaluations were left unrounded in the final addition. However the inner -rounding to four digits worked fine and made the next step faster than -it would have been with longer inputs. The morale is that one should not -use the raw results of \csa{xintFxPtPowerSeriesX} with the |D| digits -with which it was computed, as the last are to be considered garbage. -Rather, one should keep from the output only some smaller number of -digits. This will make further computations faster and not less precise. -I guess there should be some macro to do this final truncating, or -better, rounding, at a given number |D'...\repeat|\retype{} is an expandable loop +compatible with nesting. However to break out of the loop one almost always need +some un-expandable step. The cousin \csbxint{iloop} is \csbxint{loop} with an +embedded expandable mechanism allowing to exit from the loop. The iterated +macros may contain |\par| tokens or empty lines. -\everb+@ -\def\coeffexp #1{1/\xintiiFac {#1}[0]}% 1/n! (exact, not float) -\def\coefflog #1{\the\numexpr\ifodd#1 1\else-1\fi\relax/#1[0]}% -\xintFloatPowerSeriesX [8]{0}{30}{\coeffexp} - {\xintFloatPowerSeries [8]{1}{30}{\coefflog}{-1/2[0]}} -+ +If a sub-loop is to be used all the material from the start of the main loop and +up to the end of the entire subloop should be braced; these braces will be +removed and do not create a group. The simplest to allow the nesting of one or +more sub-loops is to brace everything between \csa{xintloop} and \csa{repeat}, +being careful not to leave a space between the closing brace and |\repeat|. -% -\leftedline{\dtt{\xintFloatPowerSeriesX [8]{0}{30}{\coeffexp} - {\xintFloatPowerSeries [8]{1}{30}{\coefflog}{-1/2[0]}}}} +As this loop and \csbxint{iloop} will primarily be of interest to experienced +\TeX{} macro programmers, my description will assume that the user is +knowledgeable enough. Some examples in this document will be perhaps more +illustrative than my attemps at explanation of use. -\subsection{Computing \texorpdfstring{$\log 2$}{log(2)} and \texorpdfstring{$\pi$}{pi}}\label{ssec:Machin} +One can abort the loop with \csbxint{breakloop}; this should not be used inside +the final test, and one should expand the |\fi| from the corresponding test +before. One has also \csbxint{breakloopanddo} whose first argument will be +inserted in the token stream after the loop; one may need a macro such as +|\xint_afterfi| to move the whole thing after the |\fi|, as a simple +|\expandafter| will not be enough. -In this final section, the use of \csbxint{FxPtPowerSeries} (and -\csbxint{PowerSeries}) will be -illustrated on the (expandable... why make things simple when it is so easy to -make them difficult!) computations of the first digits of the decimal expansion -of the familiar constants $\log 2$ and $\pi$. +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*}. -Let us start with $\log 2$. We will get it from this formula (which is -left as an exercise): % +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|.% % -\leftedline{\dtt{log(2)=-2\,log(1-13/256)-% - 5\,log(1-1/9)}} +\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.} % -The number of terms to be kept in the log series, for a desired -precision of |10^{-D}| was roughly estimated without much theoretical -analysis. Computing exactly the partial sums with \csa{xintPowerSeries} -and then printing the truncated values, from |D=0| up to |D=100| showed -that it worked in terms of quality of the approximation. Because of -possible strings of zeroes or nines in the exact decimal expansion (in -the present case of $\log 2$, strings of zeroes around the fourtieth and -the sixtieth decimals), this -does not mean though that all digits printed were always exact. In -the end one always end up having to compute at some higher level of -desired precision to validate the earlier result. - -Then we tried with \csa{xintFxPtPowerSeries}: this is worthwile only for -|D|'s at least 50, as the exact evaluations are faster (with these -short-length |f|'s) for a lower -number of digits. And as expected the degradation in the quality of -approximation was in this range of the order of two or three digits. -This meant roughly that the 3+1=4 ending digits were wrong. Again, we ended -up having to compute with five more digits and compare with the earlier -value to validate it. We use truncation rather than rounding because our -goal is not to obtain the correct rounded decimal expansion but the -correct exact truncated one. -% 693147180559945309417232121458176568075500134360255254120680009493 \begin{everbatim*} -\def\coefflog #1{1/#1[0]}% 1/n -\def\xa {13/256[0]}% we will compute log(1-13/256) -\def\xb {1/9[0]}% we will compute log(1-1/9) -\def\LogTwo #1% -% get log(2)=-2log(1-13/256)- 5log(1-1/9) -{% we want to use \printnumber, hence need something expanding in two steps - % only, so we use here the \romannumeral0 method - \romannumeral0\expandafter\LogTwoDoIt \expandafter - % Nb Terms for 1/9: - {\the\numexpr #1*150/143\expandafter}\expandafter - % Nb Terms for 13/256: - {\the\numexpr #1*100/129\expandafter}\expandafter - % We print #1 digits, but we know the ending ones are garbage - {\the\numexpr #1\relax}% allows #1 to be a count register -}% -\def\LogTwoDoIt #1#2#3% -% #1=nb of terms for 1/9, #2=nb of terms for 13/256, -{% #3=nb of digits for computations, also used for printing - \xinttrunc {#3} % lowercase form to stop the \romannumeral0 expansion! - {\xintAdd - {\xintMul {2}{\xintFxPtPowerSeries {1}{#2}{\coefflog}{\xa}{#3}}} - {\xintMul {5}{\xintFxPtPowerSeries {1}{#1}{\coefflog}{\xb}{#3}}}% - }% +\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}}% }% -\noindent $\log 2 \approx \LogTwo {60}\dots$\endgraf -\noindent\phantom{$\log 2$}${}\approx{}$\printnumber{\LogTwo {65}}\dots\endgraf -\noindent\phantom{$\log 2$}${}\approx{}$\printnumber{\LogTwo {70}}\dots\endgraf +\def\Matrix@helper@size #1#2#3]{\csname\string#1{#3}\endcsname }% +\def\Matrix@helper@entry #1#2#3% + {\csname\string#1{\the\numexpr#2.\the\numexpr#3}\endcsname }% +\def\A #1{\ifx[#1\expandafter\A@size + \else\expandafter\A@entry\fi {#1}}% +\def\A@size #1#2]{\ifx I#23\else4\fi}% 3rows, 4columns +\def\A@entry #1#2{\the\numexpr #1+#2-1\relax}% not pre-computed... +\def\B #1{\ifx[#1\expandafter\B@size + \else\expandafter\B@entry\fi {#1}}% +\def\B@size #1#2]{\ifx I#24\else3\fi}% 4rows, 3columns +\def\B@entry #1#2{\the\numexpr #1-#2\relax}% not pre-computed... +\makeatother +\MatrixMultiplication\A\B\C \MatrixMultiplication\C\C\D +\MatrixMultiplication\C\D\E \MatrixMultiplication\C\E\F +\begin{multicols}2 + \[\begin{pmatrix} + \A11&\A12&\A13&\A14\\ + \A21&\A22&\A23&\A24\\ + \A31&\A32&\A33&\A34 + \end{pmatrix} + \times + \begin{pmatrix} + \B11&\B12&\B13\\ + \B21&\B22&\B23\\ + \B31&\B32&\B33\\ + \B41&\B42&\B43 + \end{pmatrix} + = + \begin{pmatrix} + \C11&\C12&\C13\\ + \C21&\C22&\C23\\ + \C31&\C32&\C33 + \end{pmatrix}\] + \[\begin{pmatrix} + \C11&\C12&\C13\\ + \C21&\C22&\C23\\ + \C31&\C32&\C33 + \end{pmatrix}^2 = \begin{pmatrix} + \D11&\D12&\D13\\ + \D21&\D22&\D23\\ + \D31&\D32&\D33 + \end{pmatrix}\] + \[\begin{pmatrix} + \C11&\C12&\C13\\ + \C21&\C22&\C23\\ + \C31&\C32&\C33 + \end{pmatrix}^3 = \begin{pmatrix} + \E11&\E12&\E13\\ + \E21&\E22&\E23\\ + \E31&\E32&\E33 + \end{pmatrix}\] + \[\begin{pmatrix} + \C11&\C12&\C13\\ + \C21&\C22&\C23\\ + \C31&\C32&\C33 + \end{pmatrix}^4 = \begin{pmatrix} + \F11&\F12&\F13\\ + \F21&\F22&\F23\\ + \F31&\F32&\F33 + \end{pmatrix}\] +\end{multicols} \end{everbatim*} -Here is the code doing an exact evaluation of the partial sums. We have -added a |+1| to the number of digits for estimating the number of terms -to keep from the log series: we experimented that this gets exactly the -first |D| digits, for all values from |D=0| to |D=100|, except in one -case (|D=40|) where the last digit is wrong. For values of |D| -higher than |100| it is more efficient to use the code using -\csa{xintFxPtPowerSeries}. -\everb|@ -\def\LogTwo #1% get log(2)=-2log(1-13/256)- 5log(1-1/9) -{% - \romannumeral0\expandafter\LogTwoDoIt \expandafter - {\the\numexpr (#1+1)*150/143\expandafter}\expandafter - {\the\numexpr (#1+1)*100/129\expandafter}\expandafter - {\the\numexpr #1\relax}% -}% -\def\LogTwoDoIt #1#2#3% -{% #3=nb of digits for truncating an EXACT partial sum - \xinttrunc {#3} - {\xintAdd - {\xintMul {2}{\xintPowerSeries {1}{#2}{\coefflog}{\xa}}} - {\xintMul {5}{\xintPowerSeries {1}{#1}{\coefflog}{\xb}}}% - }% -}% -| -Let us turn now to Pi, computed with the Machin formula (but see also the -approach via the \hyperlink{BrentSalamin}{Brent-Salamin algorithm} with -\csa{xintfloatexpr}) Again the numbers of terms to keep in the two |arctg| -series were roughly estimated, and some experimentations showed that removing -the last three digits was enough (at least for |D=0-100| range). And the -algorithm does print the correct digits when used with |D=1000| (to be -convinced of that one needs to run it for |D=1000| and again, say for -|D=1010|.) A theoretical analysis could help confirm that this algorithm -always gets better than |10^{-D}| precision, but again, strings of zeroes or -nines encountered in the decimal expansion may falsify the ending digits, -nines may be zeroes (and the last non-nine one should be increased) and zeroes -may be nine (and the last non-zero one should be decreased). +\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} -\hypertarget{MachinCode}{} -\begin{everbatim*} -\def\coeffarctg #1{\the\numexpr\ifodd#1 -1\else1\fi\relax/% - \the\numexpr 2*#1+1\relax [0]}% -%\def\coeffarctg #1{\romannumeral0\xintmon{#1}/\the\numexpr 2*#1+1\relax }% -\def\xa {1/25[0]}% 1/5^2, the [0] for faster parsing -\def\xb {1/57121[0]}% 1/239^2, the [0] for faster parsing -\def\Machin #1{% #1 may be a count register, \Machin {\mycount} is allowed - \romannumeral0\expandafter\MachinA \expandafter - % number of terms for arctg(1/5): - {\the\numexpr (#1+3)*5/7\expandafter}\expandafter - % number of terms for arctg(1/239): - {\the\numexpr (#1+3)*10/45\expandafter}\expandafter - % do the computations with 3 additional digits: - {\the\numexpr #1+3\expandafter}\expandafter - % allow #1 to be a count register: - {\the\numexpr #1\relax }}% -\def\MachinA #1#2#3#4% -{\xinttrunc {#4} - {\xintSub - {\xintMul {16/5}{\xintFxPtPowerSeries {0}{#1}{\coeffarctg}{\xa}{#3}}} - {\xintMul{4/239}{\xintFxPtPowerSeries {0}{#2}{\coeffarctg}{\xb}{#3}}}% - }}% -\begin{framed} - \[ \pi = \Machin {60}\dots \] -\end{framed} -\end{everbatim*} +\csa{xintiloop}|[start+delta]|\meta{stuff}|\if ... \repeat|\retype{} is a +completely expandable nestable loop. complete expandability depends naturally on +the actual iterated contents, and complete expansion will not be achievable +under a sole \fexpan sion, as is indicated by the hollow star in the margin; +thus the loop can be used inside an |\edef| but not inside arguments to the +package macros. It can be used inside an |\xintexpr..\relax|. The +|[start+delta]| is mandatory, not optional. -Here is a variant|\MachinBis|, -which evaluates the partial sums \emph{exactly} using -\csa{xintPowerSeries}, before their final truncation. No need for a -``|+3|'' then. -\begin{everbatim*} -\def\MachinBis #1{% #1 may be a count register, -% the final result will be truncated to #1 digits post decimal point - \romannumeral0\expandafter\MachinBisA \expandafter - % number of terms for arctg(1/5): - {\the\numexpr #1*5/7\expandafter}\expandafter - % number of terms for arctg(1/239): - {\the\numexpr #1*10/45\expandafter}\expandafter - % allow #1 to be a count register: - {\the\numexpr #1\relax }}% -\def\MachinBisA #1#2#3% -{\xinttrunc {#3} % - {\xintSub - {\xintMul {16/5}{\xintPowerSeries {0}{#1}{\coeffarctg}{\xa}}} - {\xintMul{4/239}{\xintPowerSeries {0}{#2}{\coeffarctg}{\xb}}}% -}}% -\end{everbatim*} +This loop benefits via \csbxint{iloopindex} to (a limited access to) the integer +index of the iteration. The starting value |start| (which may be a |\count|) and +increment |delta| (\emph{id.}) are mandatory arguments. A space after the +closing square bracket is not significant, it will be ignored. Spaces inside the +square brackets will also be ignored as the two arguments are first given to a +|\numexpr...\relax|. Empty lines and explicit |\par| tokens are accepted. -Let us use this variant for a loop showing the build-up of digits: -\begin{everbatim*} -\begin{multicols}{2} - \cnta 0 % previously declared \count register - \loop \noindent - \centeredline{\dtt{\MachinBis{\cnta}}}% - \ifnum\cnta < 30 - \advance\cnta 1 \repeat -\end{multicols} -\end{everbatim*} +As with \csbxint{loop}, this tool will mostly be of interest to advanced users. +For nesting, one puts inside braces all the +material from the start (immediately after |[start+delta]|) and up to and +inclusive of the inner loop, these braces will be removed and do not create a +loop. In case of nesting, \csbxint{outeriloopindex} gives access to the index of +the outer loop. If needed one could write on its model a macro giving access to +the index of the outer outer loop (or even to the |nth| outer loop). -\hypertarget{Machin1000}{} +The \csa{xintiloopindex} and \csa{xintouteriloopindex} can not be used inside +braces, and generally speaking this means they should be expanded first when +given as argument to a macro, and that this macro receives them as delimited +arguments, not braced ones. Or, but naturally this will break expandability, one +can assign the value of \csa{xintiloopindex} to some |\count|. Both +\csa{xintiloopindex} and \csa{xintouteriloopindex} extend to the litteral +representation of the index, thus in |\ifnum| tests, if it comes last one has to +correctly end the macro with a |\space|, or encapsulate it in a +|\numexpr..\relax|. + +When the repeat-test of the loop is, for example, |\ifnum\xintiloopindex<10 +\repeat|, this means that the last iteration will be with |\xintiloopindex=10| +(assuming |delta=1|). There is also |\ifnum\xintiloopindex=10 \else\repeat| to +get the last iteration to be the one with |\xintiloopindex=10|. + +One has \csbxint{breakiloop} and \csbxint{breakiloopanddo} to abort the loop. +The syntax of |\xintbreakiloopanddo| is a bit surprising, the sequence of tokens +to be executed after breaking the loop is not within braces but is delimited by +a dot as in: % -You want more digits and have some time? compile this copy of the -\hyperlink{MachinCode}{|\Machin|} with |etex| (or |pdftex|): +\leftedline{|\xintbreakiloopanddo .etc.. etc... \repeat|} % -\everb|@ -% Compile with e-TeX extensions enabled (etex, pdftex, ...) -\input xintfrac.sty -\input xintseries.sty -% pi = 16 Arctg(1/5) - 4 Arctg(1/239) (John Machin's formula) -\def\coeffarctg #1{\the\numexpr\ifodd#1 -1\else1\fi\relax/% - \the\numexpr 2*#1+1\relax [0]}% -\def\xa {1/25[0]}% -\def\xb {1/57121[0]}% -\def\Machin #1{% - \romannumeral0\expandafter\MachinA \expandafter - {\the\numexpr (#1+3)*5/7\expandafter}\expandafter - {\the\numexpr (#1+3)*10/45\expandafter}\expandafter - {\the\numexpr #1+3\expandafter}\expandafter - {\the\numexpr #1\relax }}% -\def\MachinA #1#2#3#4% -{\xinttrunc {#4} - {\xintSub - {\xintMul {16/5}{\xintFxPtPowerSeries {0}{#1}{\coeffarctg}{\xa}{#3}}} - {\xintMul {4/239}{\xintFxPtPowerSeries {0}{#2}{\coeffarctg}{\xb}{#3}}}% -}}% -\pdfresettimer -\fdef\Z {\Machin {1000}} -\odef\W {\the\pdfelapsedtime} -\message{\Z} -\message{computed in \xintRound {2}{\W/65536} seconds.} -\bye -| - -This will log the first 1000 digits of $\pi$ after the decimal point. On my -laptop (a 2012 model) this took about $5.05$ seconds last time I tried.% +The reason is that one may wish to use the then current value of +|\xintiloopindex| in || but it can't be within braces at the time it +is evaluated. However, it is not that easy as |\xintiloopindex| must be expanded +before, so one ends up with code like this: % -\footnote{With \texttt{1.09i} and earlier \xintname, this used to be \dtt{42} - seconds; starting with \texttt{1.09j}, and prior to \texttt{1.2}, it was - \dtt{16} seconds (this was probably due to a more efficient division with - denominators at most $9999$). The |1.2| \xintcorename achieves a further - gain at \dtt{5.6} seconds.} +\leftedline +{|\expandafter\xintbreakiloopanddo\expandafter\macro\xintiloopindex.%|} % -\footnote{With |\xintDigits:=1001;|, the non-optimized implementation with the - |iter| of \xintexprname fame using the - \hyperlink{BrentSalamin}{Brent-Salamin algorithm}, took, last time I tried - (1.2i), about \dtt{7} seconds on my laptop (the last two digits were wrong, - which is ok as they serve as guard digits), and for obtaining about - \dtt{500} digits, it was about \dtt{1.7}s. This is not bad, taking into - account that the syntax is almost free rolling speech, contrarily to the - code above for the Machin formula computation; we would like to use the - quadratically convergent Brent-Salamin algorithm for more digits, but with - such computations with numbers of one thousand digits we are beyond the - border of the reasonable range for \xintname. Innocent people not knowing - what it means to compute with \TeX, and with the extra constraint of - expandability will wonder why this is at least thousands of times slower - than with any other language (with a little Python program using the - |Decimal| library, I timed the Brent-Salamin algorithm to \dtt{4.4ms} for - about |1000| digits and \dtt{1.14ms} for |500| digits.) I will just say that - for example digits are represented and manipulated via their ascii-code ! - all computations must convert from ascii-code to cpu words; furthermore - nothing can be stored away. And there is no memory storage with |O(1)| time - access... if expandability is to be verified.} +\leftedline{|etc.. etc.. \repeat|} % - - -As mentioned in the -introduction, the file \href{http://www.ctan.org/pkg/pi}{pi.tex} by \textsc{D. - Roegel} shows that orders of magnitude faster computations are possible within -\TeX{}, but recall our constraints of complete expandability and be merciful, -please. - -\textbf{Why truncating rather than rounding?} One of our main competitors -on the market of scientific computing, a canadian product (not -encumbered with expandability constraints, and having barely ever heard -of \TeX{} ;-), prints numbers rounded in the last digit. Why didn't we -follow suit in the macros \csa{xintFxPtPowerSeries} and -\csa{xintFxPtPowerSeriesX}? To round at |D| digits, and excluding a -rewrite or cloning of the division algorithm which anyhow would add to -it some overhead in its final steps, \xintfracname needs to truncate at -|D+1|, then round. And rounding loses information! So, with more time -spent, we obtain a worst result than the one truncated at |D+1| (one -could imagine that additions and so on, done with only |D| digits, cost -less; true, but this is a negligeable effect per summand compared to the -additional cost for this term of having been truncated at |D+1| then -rounded). Rounding is the way to go when setting up algorithms to -evaluate functions destined to be composed one after the other: exact -algebraic operations with many summands and an |f| variable which is a -fraction are costly and create an even bigger fraction; replacing |f| -with a reasonable rounding, and rounding the result, is necessary to -allow arbitrary chaining. - -But, for the -computation of a single constant, we are really interested in the exact -decimal expansion, so we truncate and compute more terms until the -earlier result gets validated. Finally if we do want the rounding we can -always do it on a value computed with |D+1| truncation. - -\clearpage -\section{Macros of the \xintcfracname package} -\label{sec:cfrac} - -\localtableofcontents - -This package was first included in release |1.04| (|2013/04/25|) of the -\xintname bundle. It was kept almost unchanged until |1.09m| of |2014/02/26| -which brings some new macros: \csbxint{FtoC}, \csbxint{CtoF}, \csbxint{CtoCv}, -dealing with sequences of braced partial quotients rather than comma separated -ones, \csbxint{FGtoC} which is to produce ``guaranteed'' coefficients of some -real number known approximately, and \csbxint{GGCFrac} for displaying arbitrary -material as a continued fraction; also, some changes to existing macros: -\csbxint{FtoCs} and \csbxint{CntoCs} insert spaces after the commas, -\csbxint{CstoF} and \csbxint{CstoCv} authorize spaces in the input also before -the commas. - -This section contains: -\begin{enumerate} -\item an \hyperref[ssec:cfracoverview]{overview} of the package functionalities, -\item a description of each one of the package macros, -\item further illustration of their use via the study of the - \hyperref[ssec:e-convergents]{convergents of $e$}. -\end{enumerate} - -\subsection{Package overview}\label{ssec:cfracoverview} - -The package computes partial quotients and convergents of a fraction, or -conversely start from coefficients and obtain the corresponding fraction; three -macros \csbxint {CFrac}, \csbxint {GCFrac} and \csbxint {GGCFrac} are -for typesetting (the first two assume that the coefficients are numeric -quantities acceptable by the \xintfracname \csbxint{Frac} macro, the -last one will display arbitrary material), the others -can be nested (if applicable) or see their outputs further processed by other -macros from the \xintname bundle, particularly the macros of \xinttoolsname -dealing with sequences of braced items or comma separated lists. - -A \emph{simple} continued fraction has coefficients -|[c0,c1,...,cN]| (usually called partial quotients, but I -dislike this entrenched terminology), where |c0| is a positive or -negative integer and the others are positive integers. - -Typesetting is usually done via the |amsmath| macro |\cfrac|: -\begin{everbatim*} -\[ c_0 + \cfrac{1}{c_1+\cfrac1{c_2+\cfrac1{c_3+\cfrac1{\ddots}}}}\] -\end{everbatim*} - -Here is a concrete example: -\begin{everbatim*} -\[ \xintFrac {208341/66317}=\xintCFrac {208341/66317}\]% -\end{everbatim*} -But it is the macro \csbxint{CFrac} which did all the work of \emph{computing} -the continued fraction \emph{and} using |\cfrac| from |amsmath| to typeset -it. - -A \emph{generalized} continued fraction has the same structure but the -numerators are not restricted to be $1$, and numbers used in the continued -fraction may be arbitrary, also fractions, irrationals, complex, -indeterminates.% +As moreover the |\fi| from the test leading to the decision of breaking out of +the loop must be cleared out of the way, the above should be +a branch of an expandable conditional test, else one needs something such +as: % -\footnote{\xintcfracname may be used with indeterminates, - for basic conversions from one inline format to another, but not for - actual computations. See \csbxint{GGCFrac}.} +\leftedline +{|\xint_afterfi{\expandafter\xintbreakiloopanddo\expandafter\macro\xintiloopindex.}%|} % -The \emph{centered} continued fraction is an -example: -\begin{everbatim*} -\[ \xintFrac {915286/188421}=\xintGCFrac {5+-1/7+1/39+-1/53+-1/13} - =\xintCFrac {915286/188421}\] -\end{everbatim*} - -The macro \csbxint{GCFrac}, contrarily to -\csbxint{CFrac}, does not compute anything, it just typesets starting from a -generalized continued fraction in inline format, which in this example -was input literally. We also used \csa{xintCFrac} -for comparison of the two types of continued fractions. +\leftedline{|\fi etc..etc.. \repeat|} -To let \TeX{} compute the centered continued fraction of |f| there is -\csbxint{FtoCC}: -\begin{everbatim*} -\[\xintFrac {915286/188421}\to\xintFtoCC {915286/188421}\] -\end{everbatim*} -The package macros are expandable and may be nested (naturally \csa{xintCFrac} -and \csa{xintGCFrac} must be at the top level, as they deal with typesetting). -\begin{everbatim*} -\[\xintGCFrac {\xintFtoCC{915286/188421}}\] -\end{everbatim*} +There is \csbxint{iloopskiptonext} to abort the current iteration and skip to +the next, \hyperref[xintiloopskipandredo]{\ttfamily\hyphenchar\font45 \char92 + xintiloopskip\-and\-redo} to skip to the end of the current iteration and redo +it with the same value of the index (something else will have to change for this +not to become an eternal loop\dots ). -The `inline' format expected on input by \csbxint{GCFrac} is -% -\leftedline{$a_0+b_0/a_1+b_1/a_2+b_2/a_3+\cdots+b_{n-2}/a_{n-1}+b_{n-1}/a_n$} -% -Fractions among the coefficients are allowed but they must be enclosed -within braces. Signed integers may be left without braces (but the |+| -signs are mandatory). No spaces are allowed around the plus and fraction -symbols. The coefficients may themselves be macros, as long as these -macros are \fexpan dable. -\begin{everbatim*} -\[ \xintFrac{\xintGCtoF {1+-1/57+\xintPow {-3}{7}/\xintiQuo {132}{25}}} - = \xintGCFrac {1+-1/57+\xintPow {-3}{7}/\xintiQuo {132}{25}}\] -\end{everbatim*} -To compute the actual fraction one has \csbxint{GCtoF}: -\begin{everbatim*} -\[\xintFrac{\xintGCtoF {1+-1/57+\xintPow {-3}{7}/\xintiQuo {132}{25}}}\] -\end{everbatim*} -For non-numeric input there is \csbxint{GGCFrac}. -\begin{everbatim*} -\[\xintGGCFrac {a_0+b_0/a_1+b_1/a_2+b_2/\ddots+\ddots/a_{n-1}+b_{n-1}/a_n}\] -\end{everbatim*} -For regular continued fractions, there is a simpler comma separated format: -\begin{everbatim*} -\[-7,6,19,1,33\to\xintFrac{\xintCstoF{-7,6,19,1,33}}=\xintCFrac{\xintCstoF{-7,6,19,1,33}}\] -\end{everbatim*} -The macro \csbxint{FtoCs} produces from a fraction |f| the comma separated -list of its coefficients. -\begin{everbatim*} -\[\xintFrac{1084483/398959}=[\xintFtoCs{1084483/398959}]\] -\end{everbatim*} -If one prefers other separators, one can use the two arguments macros -\csbxint{FtoCx} whose first argument is the separator (which may consist of more -than one token) which is to be used. -\begin{everbatim*} -\[\xintFrac{2721/1001}=\xintFtoCx {+1/(}{2721/1001})\cdots)\] -\end{everbatim*} -This allows under Plain \TeX{} with |amstex| to obtain the same effect -as with \LaTeX{}+|\amsmath|+\csbxint{CFrac}: -% -\leftedline{|$$\xintFwOver{2721/1001}=\xintFtoCx {+\cfrac1\\ }{2721/1001}\endcfrac$$|} +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 a shortcut to \csa{xintFtoCx} with separator |1+/|, there is -\csbxint{FtoGC}: -\begin{everbatim*} -2721/1001=\xintFtoGC {2721/1001} -\end{everbatim*} -Let us compare in that case with the output of \csbxint{FtoCC}: +\phantomsection\label{edefprimes} +As an example, let us construct an |\edef\z{...}| which will define |\z| to be a +list of prime numbers: \begin{everbatim*} -2721/1001=\xintFtoCC {2721/1001} -\end{everbatim*} -To obtain the coefficients as a sequence of braced numbers, there is -\csbxint{FtoC} (this is a shortcut for |\xintFtoCx {}|). This list -(sequence) may then be manipulated using the various macros of \xinttoolsname -such as the non-expandable macro \csbxint{AssignArray} or the expandable -\csbxint{Apply} and \csbxint{ListWithSep}. - -Conversely to go from such a sequence of braced coefficients to the -corresponding fraction there is \csbxint{CtoF}. +\begingroup +\edef\z +{\xintiloop [10001+2] + {\xintiloop [3+2] + \ifnum\xintouteriloopindex<\numexpr\xintiloopindex*\xintiloopindex\relax + \xintouteriloopindex, + \expandafter\xintbreakiloop + \fi + \ifnum\xintouteriloopindex=\numexpr + (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax + \else + \repeat + }% no space here + \ifnum \xintiloopindex < 10999 \repeat }% +\meaning\z\endgroup +\end{everbatim*}and we should have taken +some steps to not have a trailing comma, but +the point was to show that one can do that in an |\edef|\,! See also +\autoref{ssec:primesII} which extracts from this code its way of testing +primality. -The `|\printnumber|' (\autoref{ssec:printnumber}) macro which we use in this -document to print long numbers can also be useful on long continued fractions. -% +Let us create an alignment where each row will contain all divisors of its +first entry. +Here is the output, thus obtained without any count register: \begin{everbatim*} -\printnumber{\xintFtoCC {35037018906350720204351049/244241737886197404558180}} +\begin{multicols}2 +\tabskip1ex \normalcolor +\halign{&\hfil#\hfil\cr + \xintiloop [1+1] + {\expandafter\bfseries\xintiloopindex & + \xintiloop [1+1] + \ifnum\xintouteriloopindex=\numexpr + (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax + \xintiloopindex&\fi + \ifnum\xintiloopindex<\xintouteriloopindex\space % CRUCIAL \space HERE + \repeat \cr }% + \ifnum\xintiloopindex<30 + \repeat +} +\end{multicols} \end{everbatim*} +We wanted this first entry in bold face, but |\bfseries| leads to +unexpandable tokens, so the |\expandafter| was necessary for |\xintiloopindex| +and |\xintouteriloopindex| not to be confronted with a hard to digest +|\endtemplate|. An alternative way of coding: % -If we apply \csbxint{GCtoF} to this generalized continued fraction, we -discover that the original fraction was reducible: -% -\leftedline{|\xintGCtoF - {143+1/2+...+-1/9}|\dtt{=\xintGCtoF{143+1/2+1/5+-1/4+-1/4+-1/4+-1/3+1/2+1/2+1/6+-1/22+1/2+1/10+-1/5+-1/11+-1/3+1/4+-1/2+1/2+1/4+-1/2+1/23+1/3+1/8+-1/6+-1/9}}} +\begin{everbatim} +\tabskip1ex +\def\firstofone #1{#1}% +\halign{&\hfil#\hfil\cr + \xintiloop [1+1] + {\bfseries\xintiloopindex\firstofone{&}% + \xintiloop [1+1] \ifnum\xintouteriloopindex=\numexpr + (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax + \xintiloopindex\firstofone{&}\fi + \ifnum\xintiloopindex<\xintouteriloopindex\space % \space is CRUCIAL + \repeat \firstofone{\cr}}% + \ifnum\xintiloopindex<30 \repeat } +\end{everbatim} -\def\mymacro #1{$\xintFrac{#1}=[\xintFtoCs{#1}]$\vtop to 6pt{}} +\begin{framed} + The next utilities are not compatible with expansion-only context. +\end{framed} -\begingroup -\catcode`^\active -\def^#1^{\hbox{#1}}% +\subsection{\csbh{xintApplyInline}}\label{xintApplyInline} -When a generalized continued fraction is built with integers, and -numerators are only |1|'s or |-1|'s, the produced fraction is -irreducible. And if we compute it again with the last sub-fraction -omitted we get another irreducible fraction related to the bigger one by -a Bezout identity. Doing this here we get: -% -\leftedline{|\xintGCtoF {143+1/2+...+-1/6}|\dtt{=\xintGCtoF{143+1/2+1/5+-1/4+-1/4+-1/4+-1/3+1/2+1/2+1/6+-1/22+1/2+1/10+-1/5+-1/11+-1/3+1/4+-1/2+1/2+1/4+-1/2+1/23+1/3+1/8+-1/6}}} -and indeed: -\[\begin{vmatrix} - ^2897319801297630107^ & ^328124887710626729^\\ - ^20197107104701740^ & ^2287346221788023^ - \end{vmatrix} = \mbox{\dtt{\xintiSub {\xintiMul {2897319801297630107}{2287346221788023}}{\xintiMul{20197107104701740}{328124887710626729}}}}\] -\endgroup +\csa{xintApplyInline}|{\macro}|\marg{list}\ntype{o{\lowast f}} works non +expandably. It applies the one-parameter |\macro| to the first element of the +expanded list (|\macro| may have itself some arguments, the list item will be +appended as last argument), and is then re-inserted in the input stream after +the tokens resulting from this first expansion of |\macro|. The next item is +then handled. -The various fractions obtained from the truncation of a continued fraction to -its initial terms are called the convergents. The macros of \xintcfracname -such as \csbxint{FtoCv}, \csbxint{FtoCCv}, and others which compute such -convergents, return them as a list of braced items, with no separator (as does -\csbxint {FtoC} for the partial quotients). Here is an example: +This is to be used in situations where one needs to do some repetitive +things. It is not expandable and can not be completely expanded inside a +macro definition, to prepare material for later execution, contrarily to what +\csbxint{Apply} or \csbxint{ApplyUnbraced} achieve. \begin{everbatim*} -\[\xintFrac{915286/188421}\to - \xintListWithSep{,}{\xintApply\xintFrac{\xintFtoCv{915286/188421}}}\] -\end{everbatim*} -\begin{everbatim*} -\[\xintFrac{915286/188421}\to - \xintListWithSep{,}{\xintApply\xintFrac{\xintFtoCCv{915286/188421}}}\] +\def\Macro #1{\advance\cnta #1 , \the\cnta} +\cnta 0 +0\xintApplyInline\Macro {3141592653}. \end{everbatim*} -% -We thus see that the `centered convergents' obtained with \csbxint{FtoCCv} are -among the fuller list of convergents as returned by \csbxint{FtoCv}. +The first argument |\macro| does not have to be an expandable macro. -Here is a more complicated use of \csa{xintApply} -and \csa{xintListWithSep}. We first define a macro which will be applied to each -convergent:% -% -\leftedline{|\newcommand{\mymacro}[1]{$\xintFrac{#1}=[\xintFtoCs{#1}]$\vtop to 6pt{}}|} -% -Next, we use the following code: -% -\leftedline{|$\xintFrac{49171/18089}\to{}$|} -% -\leftedline{|\xintListWithSep {, - }{\xintApply{\mymacro}{\xintFtoCv{49171/18089}}}|} -It produces:\par -\noindent$ \xintFrac{49171/18089}\to {}$\xintListWithSep {, - }{\xintApply{\mymacro}{\xintFtoCv{49171/18089}}}. +\csa{xintApplyInline} submits its second, token list parameter to an +\hyperref[ssec:expansions]{\fexpan +sion}. Then, each \emph{unbraced} item will also be \fexpan ded. This provides +an easy way to insert one list inside another. \emph{Braced} items are not +expanded. Spaces in-between items are gobbled (as well as those at the start +or the end of the list), but not the spaces \emph{inside} the braced items. -The macro \csbxint{CntoF} allows to specify the coefficients as a function given -by a one-parameter macro. The produced values do not have to be integers. +\csa{xintApplyInline}, despite being non-expandable, does survive to +contexts where the executed |\macro| closes groups, as happens inside +alignments with the tabulation character |&|. +This tabular provides an example:\par \begin{everbatim*} -\def\cn #1{\xintiiPow {2}{#1}}% 2^n - \[\xintFrac{\xintCntoF {6}{\cn}}=\xintCFrac [l]{\xintCntoF {6}{\cn}}\] +\centerline{\normalcolor\begin{tabular}{ccc} + $N$ & $N^2$ & $N^3$ \\ \hline + \def\Row #1{ #1 & \xintiiSqr {#1} & \xintiiPow {#1}{3} \\ \hline }% + \xintApplyInline \Row {\xintCSVtoList{17,28,39,50,61}} +\end{tabular}}\medskip \end{everbatim*} -Notice the use of the optional argument |[l]| to \csa{xintCFrac}. Other -possibilities are |[r]| and (default) |[c]|. -\begin{everbatim*} -\def\cn #1{\xintPow {2}{-#1}}% - \[\xintFrac{\xintCntoF {6}{\cn}}=\xintGCFrac [r]{\xintCntoGC {6}{\cn}}= - [\xintFtoCs {\xintCntoF {6}{\cn}}]\] -\end{everbatim*} -We used \csbxint{CntoGC} as we wanted to display also the continued fraction and -not only the fraction returned by \csa{xintCntoF}. +We see that despite the fact that the first encountered tabulation character in +the first row close a group and thus erases |\Row| from \TeX's memory, +|\xintApplyInline| knows how to deal with this. -There are also \csbxint{GCntoF} and \csbxint{GCntoGC} which allow the same for -generalized fractions. An initial portion of a generalized continued -fraction for $\pi$ is obtained like this -\begin{everbatim*} -\def\an #1{\the\numexpr 2*#1+1\relax }% -\def\bn #1{\the\numexpr (#1+1)*(#1+1)\relax }% -\[\xintFrac{\xintDiv {4}{\xintGCntoF {5}{\an}{\bn}}} = - \cfrac{4}{\xintGCFrac{\xintGCntoGC {5}{\an}{\bn}}} = - \xintTrunc {10}{\xintDiv {4}{\xintGCntoF {5}{\an}{\bn}}}\dots\] -\end{everbatim*} +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). -We see that the quality of approximation is not fantastic compared to the simple -continued fraction of $\pi$ with about as many terms: +One may nest various |\xintApplyInline|'s. For example (see the +\hyperref[float]{table} \vpageref{float}):\par \begin{everbatim*} -\[\xintFrac{\xintCstoF{3,7,15,1,292,1,1}}= - \xintGCFrac{3+1/7+1/15+1/1+1/292+1/1+1/1}= - \xintTrunc{10}{\xintCstoF{3,7,15,1,292,1,1}}\dots\] +\begin{figure*}[ht!] + \centering\phantomsection\label{float} + \def\Row #1{#1:\xintApplyInline {\Item {#1}}{0123456789}\\ }% + \def\Item #1#2{&\xintiiPow {#1}{#2}}% + \centeredline {\begin{tabular}{ccccccccccc} &0&1&2&3&4&5&6&7&8&9\\ \hline + \xintApplyInline \Row {0123456789} + \end{tabular}} +\end{figure*} \end{everbatim*} -When studying the continued fraction of some real number, there is always -some doubt about how many terms are valid, when computed starting from some -approximation. If $f\leqslant x\leqslant g$ and $f, g$ both have the -same first $K$ partial quotients, then $x$ also has the same first $K$ quotients -and convergents. The macro \csbxint{FGtoC} outputs as a sequence of braced items -the common partial quotients of its two arguments. We can thus use it to produce -a sure list of valid convergents of $\pi$ for example, starting from some proven -lower and upper bound: -\begin{everbatim*} -$$\pi\to [\xintListWithSep{,} - {\xintFGtoC {3.14159265358979323}{3.14159265358979324}}, \dots]$$ -\noindent$\pi\to\xintListWithSep{,\allowbreak\;} - {\xintApply{\xintFrac} - {\xintCtoCv{\xintFGtoC {3.14159265358979323}{3.14159265358979324}}}}, \dots$ -\end{everbatim*} +One could not move the definition of |\Item| inside the tabular, +as it would get lost after the first |&|. But this +works: +\everb|@ +\begin{tabular}{ccccccccccc} + &0&1&2&3&4&5&6&7&8&9\\ \hline + \def\Row #1{#1:\xintApplyInline {&\xintiiPow {#1}}{0123456789}\\ }% + \xintApplyInline \Row {0123456789} +\end{tabular} +| +A limitation is that, contrarily to what one may have expected, the +|\macro| for an |\xintApplyInline| can not be used to define +the |\macro| for a nested sub-|\xintApplyInline|. For example, +this does not work:\par +\everb|@ + \def\Row #1{#1:\def\Item ##1{&\xintiiPow {#1}{##1}}% + \xintApplyInline \Item {0123456789}\\ }% + \xintApplyInline \Row {0123456789} % does not work +| +\noindent But see \csbxint{For}. -\subsection{\csbh{xintCFrac}}\label{xintCFrac} +\subsection{\csbh{xintFor}, \csbh{xintFor*}}\label{xintFor}\label{xintFor*} -\csa{xintCFrac}|{f}|\ntype{\Ff} is a math-mode only, \LaTeX{} with |amsmath| -only, macro which first computes then displays with the help of |\cfrac| the -simple continued fraction corresponding to the given fraction. It admits an -optional argument which may be |[l]|, |[r]| or (the default) |[c]| to specify -the location of the one's in the numerators of the sub-fractions. Each -coefficient is typeset using the \csbxint{Frac} macro from the \xintfracname -package. This macro is \fexpan dable in the sense that it prepares expandably -the whole expression with the multiple |\cfrac|'s, but it is not completely -expandable naturally as |\cfrac| isn't. +\csbxint{For}\ntype{on} is a new kind of for loop.\footnote{first introduced + with \xintname |1.09c| of |2013/10/09|.} Rather than using macros +for encapsulating list items, its behavior is like a macro with parameters: +|#1|, |#2|, \dots, |#9| are used to represent the items for up to nine levels of +nested loops. Here is an example: +% +\everb|@ +\xintFor #9 in {1,2,3} \do {% + \xintFor #1 in {4,5,6} \do {% + \xintFor #3 in {7,8,9} \do {% + \xintFor #2 in {10,11,12} \do {% + $$#9\times#1\times#3\times#2=\xintiiPrd{{#1}{#2}{#3}{#9}}$$}}}} +| +\noindent This example illustrates that one does not have to use |#1| as the +first one: +the order is arbitrary. But each level of nesting should have its specific macro +parameter. Nine levels of nesting is presumably overkill, but I did not know +where it was reasonable to stop. |\par| tokens are accepted in both the comma +separated list and the replacement text. -\subsection{\csbh{xintGCFrac}}\label{xintGCFrac} +\begin{framed} + \TeX nical notes: -\csa{xintGCFrac}|{a+b/c+d/e+f/g+h/...+x/y}|\ntype{f} uses similarly |\cfrac| -to prepare the typesetting with the |amsmath| |\cfrac| (\LaTeX{}) of a -generalized continued fraction given in inline format (or as macro which -will \fexpan d to it). It admits the -same optional argument as \csa{xintCFrac}. Plain \TeX{} with |amstex| -users, see \csbxint{GCtoGCx}. -\begin{everbatim*} -\[\xintGCFrac {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}\] -\end{everbatim*} -This is mostly a typesetting macro, although it does provoke the -expansion of the coefficients. See \csbxint{GCtoF} if you are impatient -to see this specific fraction computed. +\begin{itemize} + \item The |#1| is replaced in the iterated-over text exactly as in general + \TeX\ macros or \LaTeX\ commands. This spares the user quite a few + |\expandafter|'s or other tricks needed with loops which have the + values encapsulated in macros, like \LaTeX's |\@for| and |\@tfor|. -It admits an optional argument within square brackets which may be -either |[l]|, |[c]| or |[r]|. Default is |[c]| (numerators are centered). + \item \csa{xintFor} (and \csa{xintFor*}) isn't purely expandable: one can + not use it inside an |\edef|. But it may be used, as will be shown in + examples, in some contexts such as \LaTeX's |tabular| which are usually + hostile to non-expandable loops. + + \item \csa{xintFor} (and \csa{xintFor*}) does some assignments prior to + executing each iteration of the replacement text, but it acts purely + expandably after the last iteration, hence if for example the replacement + text ends with a |\\|, the loop can be used insided a tabular and be + followed by a |\hline| without creating the dreaded ``|Misplaced + \noalign|'' error. -Numerators and denominators are made arguments to the \csbxint{Frac} -macro. This allows them to be themselves fractions or anything \fexpan -dable giving numbers or fractions, but also means however that they can -not be arbitrary material, they can not contain color changing macros -for example. One of the reasons is that \csa{xintGCFrac} tries to -determine the signs of the numerators and chooses accordingly to use -$+$ or $-$. + \item It does not create groups. -\subsection{\csbh{xintGGCFrac}}\label{xintGGCFrac} + \item It makes no global assignments. -\csa{xintGGCFrac}|{a+b/c+d/e+f/g+h/...+x/y}|\ntype{f} is a clone of -\csbxint{GCFrac}, hence again \LaTeX{} specific with package -|amsmath|. -It does not assume the coefficients to be numbers as understood by -\xintfracname. The macro can be used for displaying arbitrary content as -a continued fraction with |\cfrac|, using only plus signs though. Note -though that it will first \fexpan d its argument, which may be thus be -one of the \xintcfracname macros producing a (general) continued -fraction in inline format, see \csbxint{FtoCx} for an example. If this -expansion is not wished, it is enough to start the argument with a -space. + \item The iterated replacement text may close a group which was opened even + before the start of the loop (typical example being with |&| in + alignments). \begin{everbatim*} -\[\xintGGCFrac {1+q/1+q^2/1+q^3/1+q^4/1+q^5/\ddots}\] +\begin{tabular}{rccccc} + \hline + \xintFor #1 in {A, B, C} \do {% + #1:\xintFor #2 in {a, b, c, d, e} \do {&($ #2 \to #1 $)}\\ }% + \hline +\end{tabular} \end{everbatim*} + + \item There is no facility provided which would give access to a count of + the number of iterations as it is technically not easy to do so it in a + way working with nested loops while maintaining the ``expandable after + done'' property; something in the spirit of \csbxint{iloopindex} is + possible but this approach would bring its own limitations and + complications. Hence the user is invited to update her own count or + \LaTeX{} counter or macro at each iteration, if needed. -\subsection{\csbh{xintGCtoGCx}}\label{xintGCtoGCx} -%{\small New with release |1.05|.\par} - -\csa{xintGCtoGCx}|{sepa}{sepb}{a+b/c+d/e+f/...+x/y}|\etype{nnf} returns the list -of the coefficients of the generalized continued fraction of |f|, each one -within a pair of braces, and separated with the help of |sepa| and |sepb|. Thus -% -\leftedline{|\xintGCtoGCx :;{1+2/3+4/5+6/7}| gives \xintGCtoGCx - :;{1+2/3+4/5+6/7}} -% -The following can be used byt Plain \TeX{}+|amstex| users to obtain an -output similar as the ones produced by \csbxint{GCFrac} and -\csbxint{GGCFrac}:\par -\everb|@ -$$\xintGCtoGCx {+\cfrac}{\\}{a+b/...}\endcfrac$$ -$$\xintGCtoGCx {+\cfrac\xintFwOver}{\\\xintFwOver}{a+b/...}\endcfrac$$ -| + \item A |\macro| whose definition uses internally an \csbxint{For} loop + may be used inside another \csbxint{For} loop even if the two loops both + use the same macro parameter. The loop definition inside |\macro| + must use |##| as is the general rule for definitions done inside macros. -\subsection{\csbh{xintFtoC}}\label{xintFtoC} + \item \csbxint{For} is for comma separated values and \csbxint{For*} for + lists of braced items; their respective expansion policies differ. They + are described later. +\end{itemize} +\unskip +\end{framed} -\csa{xintFtoC}|{f}|\etype{\Ff} computes the -coefficients of the simple continued fraction of |f| and returns them as a list -(sequence) of braced items. +\noindent Regarding \csbxint{For}: +\begin{itemize}[nosep, listparindent=\leftmarginiii] +\item the spaces between the various declarative elements are all optional, +\item in the list of comma separated values, spaces around the commas or at + the start and end are ignored, +\item if an item must contain itself its own commas, then it should + be braced, and the braces will be removed before feeding the iterated-over + text, +\item the list may be a macro, it is expanded only once, +\item items are not pre-expanded. The first item should be braced or start + with a space if the list is explicit and the item should not be + pre-expanded, +\item empty items give empty |#1|'s in the replacement text, they are not + skipped, +\item an empty list executes once the replacement text with an empty parameter + value, +\item the list, if not a macro, \fbox{must be braced.} +\end{itemize} -\begin{everbatim*} -\fdef\test{\xintFtoC{-5262046/89233}}\texttt{\meaning\test} -\end{everbatim*} +\noindent Regarding \csbxint{For*}:\ntype{{\lowast f}n} +\begin{itemize}[nosep, listparindent=\leftmarginiii] +\item it handles lists of braced items (or naked tokens), +\item it \hyperref[ssec:expansions]{\fexpan ds} the list, +\item and more generally it \hyperref[ssec:expansions]{\fexpan ds} each naked + token encountered + before assigning the |#1| values (gobbling spaces in the process); + this + makes it easy to simulate concatenation of multiple lists|\x|, |\y|: + if |\x| expands to |{1}{2}{3}| and |\y| expands to |{4}{5}{6}| then |{\x\y}| + as argument to |\xintFor*| has the same effect as |{{1}{2}{3}{4}{5}{6}}|. -\subsection{\csbh{xintFtoCs}}\label{xintFtoCs} + For a further illustration see the use of |\xintFor*| at the end of + \autoref{ssec:fibonacci}. +\item spaces at the start, end, or in-between items are gobbled (but naturally + not the spaces inside \emph{braced} items), +\item except if the list argument is a macro (with no parameters), \fbox{it + must be braced.}, +\item an empty list leads to an empty result. +\end{itemize} -\csa{xintFtoCs}|{f}|\etype{\Ff} returns the comma separated list of the -coefficients of the simple continued fraction of |f|. Notice that starting with -|1.09m| a space follows each comma (mainly for usage in text mode, as in math -mode spaces are produced in the typeset output by \TeX{} itself). +The macro \csbxint{Seq} which generates arithmetic sequences is to be used +with \csbxint{For*} as its output consists of successive braced numbers (given +as digit tokens). \begin{everbatim*} -\[ \xintSignedFrac{-5262046/89233} \to [\xintFtoCs{-5262046/89233}]\] +\xintFor* #1 in {\xintSeq [+2]{-7}{+2}}\do {stuff + with #1\xintifForLast{\par}{\newline}} \end{everbatim*} -\subsection{\csbh{xintFtoCx}}\label{xintFtoCx} -\csa{xintFtoCx}|{sep}{f}|\etype{n\Ff} returns the list of the -coefficients of the simple continued fraction of |f| separated with the -help of |sep|, which may be anything (and is kept unexpanded). For -example, with Plain \TeX{} and |amstex|, -% -\leftedline{|$$\xintFtoCx {+\cfrac1\\ }{-5262046/89233}\endcfrac$$|} +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: % -will display the continued fraction using -|\cfrac|. Each coefficient is inside a brace pair \hbox{|{ }|}, allowing -a macro to end the separator and fetch it as argument, -for example, again with Plain \TeX{} and |amstex|: -\everb|@ - \def\highlight #1{\ifnum #1>200 \textcolor{red}{#1}\else #1\fi} - $$\xintFtoCx {+\cfrac1\\ \highlight}{104348/33215}\endcfrac$$ -| +\begin{everbatim} + \edef\innersequence {\xintSeq[+2]{-50}{50}}% + \xintFor* #1 in {\xintSeq {13}{27}} \do + {\xintFor* #2 in \innersequence \do {stuff with #1 and #2}% + .. some other macros .. } +\end{everbatim} -Due to the different and extremely cumbersome syntax of |\cfrac| under -\LaTeX{} it proves a bit tortuous to obtain there the same effect. -Actually, it is partly for this purpose that |1.09m| added \csbxint -{GGCFrac}. We thus use \csa{xintFtoCx} with a suitable separator, and\; -then the whole thing as argument to \csbxint{GGCFrac}: -\begin{everbatim*} -\def\highlight #1{\ifnum #1>200 \fcolorbox{blue}{white}{\boldmath\color{red}$#1$}% - \else #1\fi} -\[\xintGGCFrac {\xintFtoCx {+1/\highlight}{208341/66317}}\] -\end{everbatim*} +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. -\subsection{\csbh{xintFtoGC}}\label{xintFtoGC} -\csa{xintFtoGC}|{f}|\etype{\Ff} does the same as \csa{xintFtoCx}|{+1/}{f}|. Its -output may thus be used in the package macros expecting such an `inline -format'. -% This continued fraction is a \emph{simple} one, not a -% \emph{generalized} one, but as it is produced in the format used for -% user input of generalized continued fractions, the macro was called -% \csa{xintFtoGC} rather than \csa{xintFtoC} for example. +When the loop is defined inside a macro for later execution the |#| characters +must be doubled.% +% +\footnote{sometimes what seems to be a macro argument isn't really; in + \csa{raisebox\{1cm\}\{}\csa{xintFor \#1 in \{a,b,c\} }\csa{do + \{\#1\}\}} no doubling should be done.} +% +For example: % \begin{everbatim*} -566827/208524=\xintFtoGC {566827/208524} +\def\T{\def\z {}% + \xintFor* ##1 in {{u}{v}{w}} \do {% + \xintFor ##2 in {x,y,z} \do {% + \expandafter\def\expandafter\z\expandafter {\z\sep (##1,##2)} }% + }% +}% +\T\def\sep {\def\sep{, }}\z \end{everbatim*} -\subsection{\csbh{xintFGtoC}}\label{xintFGtoC} - -\csa{xintFGtoC}|{f}{g}|\etype{\Ff\Ff} computes the common initial coefficients -to -two given fractions |f| and |g|. Notice that any real number |fx>g| -will then necessarily share with |f| and |g| these common initial coefficients -for its regular continued fraction. The coefficients are output as a sequence of -braced numbers. This list can then be manipulated via macros from -\xinttoolsname, or other macros of \xintcfracname. +Similarly when the replacement text +of |\xintFor| defines a macro with parameters, the macro character |#| must be +doubled. -\begin{everbatim*} -\fdef\test{\xintFGtoC{-5262046/89233}{-5314647/90125}}\texttt{\meaning\test} -\end{everbatim*} -\begin{everbatim*} -\fdef\test{\xintFGtoC{3.141592653}{3.141592654}}\texttt{\meaning\test} -\end{everbatim*} -\begin{everbatim*} -\fdef\test{\xintFGtoC{3.1415926535897932384}{3.1415926535897932385}}\meaning\test -\end{everbatim*} -\begin{everbatim*} -\xintRound {30}{\xintCstoF{\xintListWithSep{,}{\test}}} -\end{everbatim*} -\begin{everbatim*} -\xintRound {30}{\xintCtoF{\test}} -\end{everbatim*} -\begin{everbatim*} -\fdef\test{\xintFGtoC{1.41421356237309}{1.4142135623731}}\meaning\test -\end{everbatim*} -\subsection{\csbh{xintFtoCC}}\label{xintFtoCC} +The iterated macros as well as the list items are allowed to contain explicit +|\par| tokens. -\csa{xintFtoCC}|{f}|\etype{\Ff} returns the `centered' continued fraction of -|f|, in `inline format'. % -\begin{everbatim*} -566827/208524=\xintFtoCC {566827/208524} -\end{everbatim*} -\begin{everbatim*} -\[\xintFrac{566827/208524} = \xintGCFrac{\xintFtoCC{566827/208524}}\] -\end{everbatim*} -\subsection{\csbh{xintCstoF}}\label{xintCstoF} +\subsection{\csbh{xintifForFirst}, \csbh{xintifForLast}} +\label{xintifForFirst}\label{xintifForLast} -\csa{xintCstoF}|{a,b,c,d,...,z}|\etype{f} computes the fraction corresponding to -the coefficients, which may be fractions or even macros expanding to such -fractions. The final fraction may then be highly reducible. Starting with -release |1.09m| spaces before commas are allowed and trimmed automatically -(spaces after commas were already silently handled in earlier releases). -\begin{everbatim*} -\[\xintGCFrac {-1+1/3+1/-5+1/7+1/-9+1/11+1/-13}= - \xintSignedFrac{\xintCstoF {-1,3,-5,7,-9,11,-13}}=\xintSignedFrac{\xintGCtoF - {-1+1/3+1/-5+1/7+1/-9+1/11+1/-13}}\] -\end{everbatim*} -\begin{everbatim*} -\[\xintGCFrac{{1/2}+1/{1/3}+1/{1/4}+1/{1/5}}=\xintFrac{\xintCstoF {1/2,1/3,1/4,1/5}}\] -\end{everbatim*} -% -A generalized continued fraction may produce a reducible fraction -(\csa{xintCstoF} tries its best not to accumulate in a silly way superfluous -factors but will not do simplifications which would be obvious to a human, like -simplification by 3 in the result above). +\csbxint{ifForFirst}\,\texttt{\{YES branch\}\{NO branch\}}\etype{nn} + and \csbxint{ifForLast}\,\texttt{\{YES + branch\}\hskip 0pt plus 0.2em \{NO branch\}}\etype{nn} execute the |YES| or +|NO| branch +if the +\csbxint{For} +or \csbxint{For*} loop is currently in its first, respectively last, iteration. -\subsection{\csbh{xintCtoF}}\label{xintCtoF} +Designed to work as expected under nesting (but see frame next.) Don't forget +an empty brace pair |{}| if a branch is to do nothing. May be used multiple +times in the replacement text of the loop. -\csa{xintCtoF}|{{a}{b}{c}...{z}}|\etype{f} computes the fraction corresponding -to the coefficients, which may be fractions or even macros. -\begin{everbatim*} -\xintCtoF {\xintApply {\xintiiPow 3}{\xintSeq {1}{5}}} -\end{everbatim*} -\begin{everbatim*} -\[ \xintFrac{14946960/4805083}=\xintCFrac {14946960/4805083}\] -\end{everbatim*} -In the example above the power of $3$ was already pre-computed via the expansion -done by |\xintApply|, but if we try with |\xintApply { \xintiiPow 3}| where the -space will stop this expansion, we can check that |\xintCtoF| will itself -provoke the needed coefficient expansion.% ok +\begin{framed} + \noindent Pay attention to these implementation features: + \begin{itemize}[nosep, listparindent=\leftmarginiii] + \item \emph{if an inner \csbxint{For} loop is positioned before the + \csb{xintifForFirst} or \csb{xintifForLast} of the outer loop it will + contaminate their settings. This applies also naturally if the inner loop + arises from the expansion of some macro located before the outer + conditionals.} -\subsection{\csbh{xintGCtoF}}\label{xintGCtoF} + One fix is to make sure that the outer conditionals are expanded before the + inner loop is executed, e.g. this will be the case if the inner loop is + located inside one of the branches of the conditional. -\csa{xintGCtoF}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} computes the fraction -defined by the inline generalized continued fraction. Coefficients may be -fractions but must then be put within braces. They can be macros. The plus signs -are mandatory. -\begin{everbatim*} -\[\xintGCFrac {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}} = -\xintFrac{\xintGCtoF {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}} = -\xintFrac{\xintIrr{\xintGCtoF - {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/\xintiiFac {6}}}}\] -\end{everbatim*} + Another approach is to enclose, if feasible, the inner loop in a group of + its own. + \item \emph{if the replacement text closes a group (e.g. from a |&| inside an + alignment), the conditionals will lose their ascribed meanings and end up + possibly undefined, depending whether there is some outer loop whose + execution started before the opening of the group.} -\begin{everbatim*} -\[ \xintGCFrac{{1/2}+{2/3}/{4/5}+{1/2}/{1/5}+{3/2}/{5/3}} = - \xintFrac{\xintGCtoF {{1/2}+{2/3}/{4/5}+{1/2}/{1/5}+{3/2}/{5/3}}} \] -\end{everbatim*} + The fix is to arrange things so that the conditionals are expanded + before \TeX\ encounters the closing-group token. + \end{itemize} +\end{framed} -The macro tries its best not to accumulate superfluous factor in the -denominators, but doesn't reduce the fraction to irreducible form before -returning it and does not do simplifications which would be obvious to a human. +\subsection{ \csbh{xintBreakFor}, \csbh{xintBreakForAndDo}} +\label{xintBreakFor}\label{xintBreakForAndDo} -\subsection{\csbh{xintCstoCv}}\label{xintCstoCv} +One may immediately terminate an \csbxint{For} or \csbxint{For*} loop with +\csbxint{BreakFor}. -\csa{xintCstoCv}|{a,b,c,d,...,z}|\etype{f} returns the sequence of the -corresponding convergents, each one within braces. +\begin{framed} + As it acts by clearing up all the rest of the replacement text when + encountered, it will not work from inside some |\if...\fi| without + suitable |\expandafter| or swapping technique. -It is allowed to use fractions as coefficients (the computed -convergents have then no reason to be the real convergents of the final -fraction). When the coefficients are integers, the convergents are irreducible -fractions, but otherwise it is not necessarily the case. -\begin{everbatim*} -\xintListWithSep:{\xintCstoCv{1,2,3,4,5,6}} -\end{everbatim*} -\begin{everbatim*} -\xintListWithSep:{\xintCstoCv{1,1/2,1/3,1/4,1/5,1/6}} -\end{everbatim*} -\begin{everbatim*} -\[\xintListWithSep{\to}{\xintApply\xintFrac{\xintCstoCv {\xintPow - {-.3}{-5},7.3/4.57,\xintCstoF{3/4,9,-1/3}}}}\] -\end{everbatim*} + Also it can't be used from inside braces as from there it can't see the end + of the replacement text. +\end{framed} -\subsection{\csbh{xintCtoCv}}\label{xintCtoCv} +There is also \csbxint{BreakForAndDo}. Both are illustrated by various examples +in the next section which is devoted to ``forever'' loops. -\csa{xintCtoCv}|{{a}{b}{c}...{z}}|\etype{f} returns the sequence of the -corresponding convergents, each one within braces. -\begin{everbatim*} -\fdef\test{\xintCtoCv {11111111111}}\texttt{\meaning\test} -\end{everbatim*} +\subsection{\csbh{xintintegers}, \csbh{xintdimensions}, \csbh{xintrationals}} +\label{xintegers}\label{xintintegers} +\label{xintdimensions}\label{xintrationals} -\subsection{\csbh{xintGCtoCv}}\label{xintGCtoCv} +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. -\csa{xintGCtoCv}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} returns the list of -the corresponding convergents. The coefficients may be fractions, but must then -be inside braces. Or they may be macros, too. +If the list argument is \csbxint{dimensions} or more generally +\csbxint{dimensions}|[||start|\allowbreak|+|\allowbreak|delta||]| (\emph{within + braces}!), then +\csbxint{For} does an infinite iteration where |#1| (or |#2|, \dots, |#9|) will +run through the arithmetic sequence of dimensions with initial value +|start| and increment |delta|. Default values: |start=0pt|, |delta=1pt|; if +the optional argument is present it must contain both of them, and they may +be explicit specifications, or macros, or dimen registers, or length macros +in \LaTeX{} (the stretch and shrink components will be discarded). The |#1| +will be |\dimexpr sp\relax|, from which one can get the +litteral (approximate) representation in points via |\the#1|. So |#1| can be +used anywhere \TeX{} expects a dimension (and there is no need in conditionals +to insert a |\relax|, and one should \emph{not} do it), and to print its value +one uses \fbox{\csa{the\#1}}. The chosen representation guarantees exact +incrementation with no rounding errors accumulating from converting into +points at each step. -The convergents will in the general case be reducible. To put them into -irreducible form, one needs one more step, for example it can be done -with |\xintApply\xintIrr|. -\begin{everbatim*} -\[\xintListWithSep{,}{\xintApply\xintFrac - {\xintGCtoCv{3+{-2}/{7/2}+{3/4}/12+{-56}/3}}}\] -\[\xintListWithSep{,}{\xintApply\xintFrac{\xintApply\xintIrr - {\xintGCtoCv{3+{-2}/{7/2}+{3/4}/12+{-56}/3}}}}\] -\end{everbatim*} -\subsection{\csbh{xintFtoCv}}\label{xintFtoCv} -\csa{xintFtoCv}|{f}|\etype{\Ff} returns the list of the (braced) convergents of -|f|, with no separator. To be treated with \csbxint{AssignArray} or -\csbxint{ListWithSep}. -\begin{everbatim*} -\[\xintListWithSep{\to}{\xintApply\xintFrac{\xintFtoCv{5211/3748}}}\] -\end{everbatim*} -\subsection{\csbh{xintFtoCCv}}\label{xintFtoCCv} -\csa{xintFtoCCv}|{f}|\etype{\Ff} returns the list of the (braced) centered -convergents of |f|, with no separator. To be treated with \csbxint{AssignArray} -or \csbxint{ListWithSep}. +If the list argument to \csbxint{For} (or \csbxint{For*}) is \csbxint{rationals} +or more generally +\csbxint{rationals}|[||start|\allowbreak|+|\allowbreak|delta||]| (\emph{within + braces}!), then \csbxint{For} does an infinite iteration where |#1| (or |#2|, +\dots, |#9|) will run through the arithmetic sequence of \xintfracname fractions +with initial value |start| and increment |delta| (default values: |start=1/1|, +|delta=1/1|). This loop works \emph{only with \xintfracname loaded}. if the +optional argument is present it must contain both of them, and they may be given +in any of the formats recognized by \xintfracname (fractions, decimal +numbers, numbers in scientific notations, numerators and denominators in +scientific notation, etc...) , or as macros or count registers (if they are +short integers). The |#1| (or |#2|, \dots, |#9|) will be an |a/b| fraction +(without a |[n]| part), where +the denominator |b| is the product of the denominators of +|start| and |delta| (for reasons of speed |#1| is not reduced to irreducible +form, and for another reason explained later |start| and |delta| are not put +either into irreducible form; the input may use explicitely \csa{xintIrr} to +achieve that). \begin{everbatim*} -\[\xintListWithSep{\to}{\xintApply\xintFrac{\xintFtoCCv{5211/3748}}}\] +\begingroup\small +\noindent\parbox{\dimexpr\linewidth-3em}{\color[named]{OrangeRed}% +\xintFor #1 in {\xintrationals [10/21+1/21]} \do +{#1=\xintifInt {#1} + {\textcolor{blue}{\xintTrunc{10}{#1}}} + {\xintTrunc{10}{#1}}% display in blue if an integer + \xintifGt {#1}{1.123}{\xintBreakFor}{, }% + }} +\endgroup\smallskip \end{everbatim*} -\subsection{\csbh{xintCntoF}}\label{xintCntoF} - +\smallskip The example above confirms that computations are done exactly, and +illustrates that the two initial (reduced) denominators are not multiplied when +they are found to be equal. It is thus recommended to input |start| and |delta| +with a common smallest possible denominator, or as fixed point numbers with the +same numbers of digits after the decimal mark; and this is also the reason why +|start| and |delta| are not by default made irreducible. As internally the +computations are done with numerators and denominators completely expanded, one +should be careful not to input numbers in scientific notation with exponents in +the hundreds, as they will get converted into as many zeroes. -\csa{xintCntoF}|{N}{\macro}|\etype{\numx f} computes the fraction |f| having -coefficients |c(j)=\macro{j}| for |j=0,1,...,N|. The |N| parameter is given to a -|\numexpr|. The values of the coefficients, as returned by |\macro| do not have -to be positive, nor integers, and it is thus not necessarily the case that the -original |c(j)| are the true coefficients of the final |f|. \begin{everbatim*} -\def\macro #1{\the\numexpr 1+#1*#1\relax} \xintCntoF {5}{\macro} +\noindent\parbox{\dimexpr.7\linewidth}{\raggedright +\xintFor #1 in {\xintrationals [0.000+0.125]} \do +{\edef\tmp{\xintTrunc{3}{#1}}% + \xintifInt {#1} + {\textcolor{blue}{\tmp}} + {\tmp}% + \xintifGt {#1}{2}{\xintBreakFor}{, }% + }}\smallskip \end{everbatim*} -This example shows that the fraction is output with a trailing number in square -brackets (representing a power of ten), this is for consistency with what do -most macros of \xintfracname, and does not have to be always this annoying |[0]| -as the coefficients may for example be numbers in scientific notation. To avoid -these trailing square brackets, for example if the coefficients are known to be integers, there is always the possibility to filter the output via -\csbxint{PRaw}, or \csbxint{Irr} (the latter is overkill in the case of integer -coefficients, as the fraction is guaranteed to be irreducible then). +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 -\subsection{\csbh{xintGCntoF}}\label{xintGCntoF} -\csa{xintGCntoF}|{N}{\macroA}{\macroB}|\etype{\numx ff} returns the fraction |f| -corresponding to the inline generalized continued fraction -|a0+b0/a1+b1/a2+....+b(N-1)/aN|, with |a(j)=\macroA{j}| and |b(j)=\macroB{j}|. -The |N| parameter is given to a |\numexpr|. +\subsection{\csbh{xintForpair}, \csbh{xintForthree}, \csbh{xintForfour}}\label{xintForpair}\label{xintForthree}\label{xintForfour} + +The syntax\ntype{on} is illustrated in this +example. The notation is the usual one for |n|-uples, with parentheses and +commas. Spaces around commas and parentheses are ignored. +% \begin{everbatim*} -\def\coeffA #1{\the\numexpr #1+4-3*((#1+2)/3)\relax }% -\def\coeffB #1{\the\numexpr \ifodd #1 -\fi 1\relax }% (-1)^n -\[\xintGCFrac{\xintGCntoGC {6}{\coeffA}{\coeffB}} = - \xintFrac{\xintGCntoF {6}{\coeffA}{\coeffB}}\] +{\centering\begin{tabular}{cccc} + \xintForpair #1#2 in { ( A , a ) , ( B , b ) , ( C , c ) } \do {% + \xintForpair #3#4 in { ( X , x ) , ( Y , y ) , ( Z , z ) } \do {% + $\Biggl($\begin{tabular}{cc} + -#1- & -#3-\\ + -#4- & -#2-\\ + \end{tabular}$\Biggr)$&}\\\noalign{\vskip1\jot}}% +\end{tabular}\\} \end{everbatim*} -There is also \csbxint{GCntoGC} to get the `inline format' continued -fraction. -\subsection{\csbh{xintCntoCs}}\label{xintCntoCs} +\csbxint{Forpair} must be followed by either |#1#2|, |#2#3|, |#3#4|, \dots, or +|#8#9| with |#1| usable as an alias for |#1#2|, |#2| as alias for |#2#3|, +etc \dots\ and similarly for \csbxint{Forthree} (using |#1#2#3| or simply +|#1|, |#2#3#4| or simply |#2|, \dots) and \csbxint{Forfour} (with |#1#2#3#4| +etc\dots). -\csa{xintCntoCs}|{N}{\macro}|\etype{\numx f} produces the comma separated list -of the corresponding coefficients, from |n=0| to |n=N|. The |N| is given to a -|\numexpr|. % -\begin{everbatim*} -\xintCntoCs {5}{\macro} -\end{everbatim*} -\begin{everbatim*} -\[ \xintFrac{\xintCntoF{5}{\macro}}=\xintCFrac{\xintCntoF {5}{\macro}}\] -\end{everbatim*} +Nesting works as long as the macro parameters are distinct among |#1|, |#2|, +..., |#9|. A macro which expands to an \csa{xintFor} or a +\csa{xintFor(pair,three,four)} can be used in another one with no constraint +about using distinct macro parameters. -\subsection{\csbh{xintCntoGC}}\label{xintCntoGC} +|\par| tokens are accepted in both the comma separated list and the +replacement text. -% -\csa{xintCntoGC}|{N}{\macro}|\etype{\numx f} evaluates the |c(j)=\macro{j}| from -|j=0| to |j=N| and returns a continued fraction written in inline format: -|{c(0)}+1/{c(1)}+1/...+1/{c(N)}|. The parameter |N| is given to a |\numexpr|. -The coefficients, after expansion, are, as shown, being enclosed in an added -pair of braces, they may thus be fractions. -\begin{everbatim*} -\def\macro #1{\the\numexpr\ifodd#1 -1-#1\else1+#1\fi\relax/\the\numexpr 1+#1*#1\relax} -\fdef\x{\xintCntoGC {5}{\macro}}\meaning\x -\[\xintGCFrac{\xintCntoGC {5}{\macro}}\] -\end{everbatim*} -\subsection{\csbh{xintGCntoGC}}\label{xintGCntoGC} +\subsection{\csbh{xintAssign}}\label{xintAssign} -\csa{xintGCntoGC}|{N}{\macroA}{\macroB}|\etype{\numx ff} evaluates the -coefficients and then returns the corresponding -|{a0}+{b0}/{a1}+{b1}/{a2}+...+{b(N-1)}/{aN}| inline generalized fraction. |N| is -givent to a |\numexpr|. The coefficients are enclosed into pairs -of braces, and may thus be fractions, the fraction slash will not be -confused in further processing by the continued fraction slashes. +\csa{xintAssign}\meta{braced things}\csa{to}% +\meta{as many cs as they are things} %\ntype{{(f$\to$\lowast [x)}{\lowast N}} % -\begin{everbatim*} -\def\an #1{\the\numexpr #1*#1*#1+1\relax}% -\def\bn #1{\the\numexpr \ifodd#1 -\fi 1*(#1+1)\relax}% -$\xintGCntoGC {5}{\an}{\bn}=\xintGCFrac {\xintGCntoGC {5}{\an}{\bn}} = -\displaystyle\xintFrac {\xintGCntoF {5}{\an}{\bn}}$\par -\end{everbatim*} +defines (without checking if something gets overwritten) the control sequences +on the right of \csa{to} to expand to the successive tokens or braced items +located to the left of \csa{to}. \csa{xintAssign} is not an expandable macro. -\subsection{\csbh{xintCstoGC}}\label{xintCstoGC} +\fexpan sion is first applied to the material in front of \csa{xintAssign} +which is fetched as one argument if it is braced. Then the expansion of this +argument is examined and successive items are assigned to the macros following +|\to|. There must be exactly as many macros as items. No check is done. The +macro assignments are done with removal of one level of brace pairs from each +item. -\csa{xintCstoGC}|{a,b,..,z}|\etype{f} transforms a comma separated list (or -something expanding to such a list) into an `inline format' continued fraction -|{a}+1/{b}+1/...+1/{z}|. The coefficients are just copied and put within braces, -without expansion. The output can then be used in \csbxint{GCFrac} for example. +After the initial \fexpan sion, each assigned (brace-stripped) item will be +expanded according to the setting of the optional parameter. + +For example |\xintAssign [e]...| means that all assignments are done using +|\edef|. With |[f]| the assignments will be made using +\hyperref[fdef]{\ttfamily\char92fdef}. The default is simply to make the +definitions with |\def|, corresponding to an empty optional paramter |[]|. +Possibilities for the optional parameter are: |[], [g], [e], [x], [o], [go], +[oo], [goo], [f], [gf]|. For example |[oo]| means a double expansion. \begin{everbatim*} -\[\xintGCFrac {\xintCstoGC {-1,1/2,-1/3,1/4,-1/5}}=\xintSignedFrac{\xintCstoF {-1,1/2,-1/3,1/4,-1/5}}\] +\xintAssign \xintiiDivision{1000000000000}{133333333}\to\Q\R +\meaning\Q\newline +\meaning\R\newline +\xintAssign {{\xintiiDivision{1000000000000}{133333333}}}\to\X +\meaning\X\newline +\xintAssign [oo]{{\xintiiDivision{1000000000000}{133333333}}}\to\X +\meaning\X\newline +\xintAssign \xintiiPow{7}{13}\to\SevenToThePowerThirteen +\meaning\SevenToThePowerThirteen\par \end{everbatim*} -\subsection{\csbh{xintiCstoF}, \csbh{xintiGCtoF}, \csbh{xintiCstoCv}, \csbh{xintiGCtoCv}}\label{xintiCstoF} -\label{xintiGCtoF} -\label{xintiCstoCv} -\label{xintiGCtoCv} -Essentially\etype{f} the same as the corresponding macros without the -`i', but for integer-only input. Infinitesimally faster, mainly for -internal use by the package. +Two special cases: +\begin{itemize}[nosep] +\item if after this initial expansion no brace is found immediately after + \csa{xintAssign}, it is assumed that there is only one control sequence + following |\to|, and this control sequence is then defined via |\def| (or + what is set-up by the optional parameter) to expand to the material between + \csa{xintAssign} and \csa{to}. +\item if the material between \csa{xintAssign} and |\to| is enclosed in two + brace pairs, the first brace pair is removed, then the \fexpan sion is + immediately stopped by the inner brace pair, hence \csa{xintAssign} now + finds a unique item and thus defines only a single macro to be this item, + which is now stripped of the second pair of braces. +\end{itemize} -\subsection{\csbh{xintGCtoGC}}\label{xintGCtoGC} -\csa{xintGCtoGC}|{a+b/c+d/e+f/g+......+v/w+x/y}|\etype{f} expands (with the -usual meaning) each one of the coefficients and returns an inline continued -fraction of the same type, each expanded coefficient being enclosed within -braces. -% +\emph{Note:} prior to release |1.09j|, |\xintAssign| did an |\edef| by default +for each item assignment but it now does |\def| corresponding to no or empty +optional parameter. + +It is allowed for the successive braced items to be separated by spaces. They +are removed during the assignments. But if a single macro is defined (which +happens if the argument after \fexpan sion does not start with a brace), +naturally the scooped up material has all intervening spaces, as it is +considered a +single item. But an upfront initial space will have been absorbed by \fexpan +sion. \begin{everbatim*} -\fdef\x {\xintGCtoGC {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/% - \xintiiFac {6}+\xintCstoF {2,-7,-5}/16}} \meaning\x +\def\X{ {a} {b} {c} {d} }\def\Y { u {a} {b} {c} {d} } +\xintAssign\X\to\A\B\C\D +\xintAssign\Y\to\Z +\meaning\A, \meaning\B, \meaning\C, \meaning\D+++\newline +\meaning\Z+++\par \end{everbatim*} +As usual successive space characters in input make for a single \TeX\ space token. -To be honest I have forgotten for which purpose I wrote this macro in the first -place. -\subsection{Euler's number \texorpdfstring{$e$}{e}}\label{ssec:e-convergents} +\subsection{\csbh{xintAssignArray}}\label{xintAssignArray} -Let us explore -the convergents of Euler's number $e$. -\smallskip The volume of computation is kept minimal by the following steps: -\begin{itemize} -\item a comma separated list of the first 36 coefficients is produced by - \csbxint{CntoCs}, -\item this is then given to \csbxint{iCstoCv} which produces the list of the - convergents (there is also \csbxint{CstoCv}, but our - coefficients being integers we used the infinitesimally - faster \csbxint{iCstoCv}), -\item then the whole list was converted into a sequence of one-line paragraphs, - each convergent becomes the argument to a macro printing it - together with its decimal expansion with 30 digits after the decimal point. -\item A count register |\cnta| was used to give a line count serving as a visual - aid: we could also have done that in an expandable way, but well, let's relax - from time to time\dots -\end{itemize} +\xintAssignArray \xintBezout {1000}{113}\to\Bez -\begin{everbatim*} -\def\cn #1{\the\numexpr\ifcase \numexpr #1+3-3*((#1+2)/3)\relax - 1\or1\or2*(#1/3)\fi\relax } -% produces the pattern 1,1,2,1,1,4,1,1,6,1,1,8,... which are the -% coefficients of the simple continued fraction of e-1. -\cnta 0 -\def\mymacro #1{\advance\cnta by 1 - \noindent - \hbox to 3em {\hfil\small\dtt{\the\cnta.} }% - $\xintTrunc {30}{\xintAdd {1[0]}{#1}}\dots= - \xintFrac{\xintAdd {1[0]}{#1}}$}% -\xintListWithSep{\vtop to 6pt{}\vbox to 12pt{}\par} - {\xintApply\mymacro{\xintiCstoCv{\xintCntoCs {35}{\cn}}}} -\end{everbatim*} +\csa{xintAssignArray}\meta{braced + things}\csa{to}\csa{myArray} %\ntype{{(f$\to$\lowast x)}N} +% +first expands fully what comes immediately after |\xintAssignArray| and +expects to find a list of braced things |{A}{B}...| (or tokens). It then +defines \csa{myArray} as a macro with one parameter, such that \csa{myArray\x} +expands to give the |x|th braced thing of this original +list (the argument \texttt{\x} itself is fed to a |\numexpr| by |\myArray|, +and |\myArray| expands in two steps to its output). With |0| as parameter, +\csa{myArray}|{0}| returns the number |M| of elements of the array so that the +successive elements are \csa{myArray}|{1}|, \dots, \csa{myArray}|{M}|. +% +\leftedline{|\xintAssignArray \xintBezout {1000}{113}\to\Bez|} will set +|\Bez{0}| to \dtt{\Bez0}, |\Bez{1}| to \dtt{\Bez1}, |\Bez{2}| to +\dtt{\Bez2}, |\Bez{3}| to \dtt{\Bez3}, |\Bez{4}| to +\dtt{\Bez4}, and |\Bez{5}| to \dtt{\Bez5}: +\dtt{(\Bez3)${}\times{}$\Bez1${}-{}$(\Bez4)${}\times{}$\Bez2${}={}$\Bez5.} +This macro is incompatible with expansion-only contexts. +\csa{xintAssignArray} admits an optional parameter, for example +|\xintAssignArray [e]| means that the definitions of the macros will be made +with |\edef|. The empty optional parameter (default) means that definitions +are done with |\def|. Other possibilities: |[], [o], [oo], [f]|. Contrarily to +\csbxint{Assign} one can not use the |g| here to make the definitions global. +For this, one should rather do |\xintAssignArray| within a group starting with +|\globaldefs 1|. -\smallskip -% The actual computation of the list of all 36 convergents accounts for -% only 8\% of the total time (total time equal to about 5 hundredths of a second -% in my testing, on my laptop): another 80\% is occupied with the computation of -% the truncated decimal expansions (and the addition of 1 to everything as the -% formula gives the continued fraction of $e-1$). +\subsection{\csbh{xintDigitsOf}}\label{xintDigitsOf} -One can with no problem compute -much bigger convergents. Let's get the 200th convergent. It turns out to -have the same first 268 digits after the decimal point as $e-1$. Higher -convergents get more and more digits in proportion to their index: the 500th -convergent already gets 799 digits correct! To allow speedy compilation of the -source of this document when the need arises, I limit here to the 200th -convergent. -% (getting the 500th took about 1.2s on my laptop last time I tried, -% and the 200th convergent is obtained ten times faster). -\begin{everbatim*} -\fdef\z {\xintCntoF {199}{\cn}}% -\begingroup\parindent 0pt \leftskip 2.5cm -\indent\llap {Numerator = }\printnumber{\xintNumerator\z}\par -\indent\llap {Denominator = }\printnumber{\xintDenominator\z}\par -\indent\llap {Expansion = }\printnumber{\xintTrunc{268}\z}\dots\par\endgroup -\end{everbatim*} +This is a synonym for \csbxint{AssignArray},\ntype{fN} to be used to define +an array giving all the digits of a given (positive, else the minus sign will +be treated as first item) number. +\begingroup\xintDigitsOf\xintiiPow {7}{500}\to\digits +% +\leftedline{|\xintDigitsOf\xintiiPow {7}{500}\to\digits|} +\noindent $7^{500}$ has |\digits{0}=|\digits{0} digits, and the 123rd among them +(starting from the most significant) is +|\digits{123}=|\digits{123}. +\endgroup + +\subsection{\csbh{xintRelaxArray}}\label{xintRelaxArray} +\csa{xintRelaxArray}\csa{myArray} %\ntype{N} +% +(globally) sets to \csa{relax} all macros which were defined by the previous +\csa{xintAssignArray} with \csa{myArray} as array macro. -One can also use a centered continued fraction: we get more digits but there are -also more computations as the numerators may be either -$1$ or $-1$. \ifnum\NoSourceCode=1 \bigskip @@ -15368,20 +15383,27 @@ $1$ or $-1$. % This is \expandafter|\xintbndlversion| of \expandafter|\xintbndldate|. % % \begin{itemize} -% -% \item Release |1.2n| of |2017/08/06| modified \xintbinhexnameimp to depend -% only on \xintkernelnameimp: it does not load \xintcorenameimp anymore. -% Also, macros were rewritten and in particular conversion from decimal -% allows bigger arguments (up to around |6000| rather than |4000| digits as -% in |1.2m|). +% \item Release |1.2o| of |2017/08/29| deprecated those macros from +% \xintcorenameimp and \xintnameimp which filtered their arguments via +% |\xintNum|. Currently these macros execute as formerly but raise an error +% message. This deprecation is overruled for most if \xintfracnameimp is +% loaded as it provides their proper definitions. Some however (like +% |\xintiAdd|) remain deprecated even if loading \xintfracnameimp. All these +% deprecated macros are destined to be removed at some future release. +% +% A few macros got renamed (e.g. |\xintNot| became |\xintNOT|.) Former names +% emit a deprecation error and will get removed at some future release. +% +% \item Release |1.2n| of |2017/08/06| suppressed the \xintbinhexnameimp +% dependencies upon \xintcorenameimp; the package now depends upon, and +% loads, only \xintkernelnameimp. Also, the allowed maximal input lengths +% and the efficiency of its macros got improved. % % \item Release |1.2m| of |2017/07/31| has rewritten entirely the % \xintbinhexnameimp module. The new routines (in the style of the |1.2| -% from \xintcorenameimp) are faster (depending on the macro |1.5x--2.5x| -% faster at |100| digits, |5x--9x| times faster at |1000| digits) but they -% limit the maximal size of the inputs to a few thousand characters, from -% 4000 to about 19900 depending on the macro. The |1.08| routines could -% handle (slowly) tens of thousands of digits. +% from \xintcorenameimp) are faster but limit the maximal size of the inputs +% to a few thousand characters. The |1.08| routines could handle (slowly) +% tens of thousands of digits. % % \item Release |1.2l| of |2017/07/26| refactored the subtraction and also % |\xintiiCmp| got a rewrite. It should certainly use |\pdfstrcmp| for @@ -15613,7 +15635,7 @@ $1$ or $-1$. \fi \XINT_providespackage \ProvidesPackage {xintkernel}% - [2017/08/06 1.2n Paraphernalia for the xint packages (JFB)]% + [2017/08/29 1.2o Paraphernalia for the xint packages (JFB)]% % \end{macrocode} % \subsection{Constants} % \begin{macrocode} @@ -16199,7 +16221,7 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xinttools}% - [2017/08/06 1.2n Expandable and non-expandable utilities (JFB)]% + [2017/08/29 1.2o Expandable and non-expandable utilities (JFB)]% % \end{macrocode} % \lverb|\XINT_toks is used in macros such as \xintFor. It is not used % elsewhere in the xint bundle.| @@ -18103,7 +18125,7 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcore}% - [2017/08/06 1.2n Expandable arithmetic on big integers (JFB)]% + [2017/08/29 1.2o Expandable arithmetic on big integers (JFB)]% % \end{macrocode} % \subsection{(WIP!) Error conditions and exceptions} % \lverb|As per the Mike Cowlishaw/IBM's General Decimal Arithmetic Specification @@ -18225,6 +18247,7 @@ $1$ or $-1$. \XINT_resetFlag{Overflow}% not encountered so far in xint code 1.2l % .. others .. }% +\def\XINT_RaiseFlag #1{\expandafter\xint_gobble_i\csname XINT_#1Flag_ON\endcsname}% %% NOT IMPLEMENTED! WORK IN PROGRESS! (ALL SIGNALS TRAPPED, NO HANDLERS USED) \catcode`. 11 \let\XINT_Clamped.handler\xint_firstofone % WIP @@ -18253,11 +18276,35 @@ $1$ or $-1$. \newcount\xint_c_xii_e_viii \xint_c_xii_e_viii 1200000000 \newcount\xint_c_xi_e_viii_mone \xint_c_xi_e_viii_mone 1099999999 % \end{macrocode} +% \subsection*{Routines handling integers as lists of token digits} +% \addcontentsline{toc}{subsection}{Routines handling integers as lists of token digits} +% \lverb|& +% Routines handling big integers which are lists of digit tokens with no +% special additional structure. +% +% Some +% routines do not accept non properly terminated inputs like "\the\numexpr1", +% or "\the\mathcode`\-", others do. +% +% These routines or their sub-routines are mainly for internal usage. +% | +% +% \subsection{\csh{XINT_cuz_small}} +% \lverb|& +% \XINT_cuz_small removes leading zeroes from the first eight digits. Expands +% following \romannumeral0. At least one digit is produced.| +% \begin{macrocode} +\def\XINT_cuz_small#1{% +\def\XINT_cuz_small ##1##2##3##4##5##6##7##8% +{% + \expandafter#1\the\numexpr ##1##2##3##4##5##6##7##8\relax +}}\XINT_cuz_small{ }% +% \end{macrocode} % \subsection{\csh{xintNum}} % \lverb|& % For example \xintNum {----+-+++---+----000000000000003} % -% Very old routine got completely rewritten for 1.2l. +% Very old routine got completely rewritten at 1.2l. % % New code uses \numexpr governed expansion and fixes some issues of former % version particularly regarding inputs of the \numexpr...\relax type without @@ -18278,7 +18325,8 @@ $1$ or $-1$. \expandafter\XINT_num_cleanup\the\numexpr\expandafter\XINT_num_loop \romannumeral`&&@#1\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\Z }% -\let\xintNum\xintiNum \let\xintnum\xintinum +\def\xintNum {\romannumeral0\xintnum }% +\let\xintnum\xintinum \def\XINT_num #1% {% \expandafter\XINT_num_cleanup\the\numexpr\XINT_num_loop @@ -18311,37 +18359,11 @@ $1$ or $-1$. \def\XINT_num_end\xint:#1\xint:{#1+\xint_c_\xint:}% empty input ok \def\XINT_num_cleanup #1\xint:#2\Z { #1}% % \end{macrocode} -% \subsection*{Routines handling integers as lists of token digits} -% \addcontentsline{toc}{subsection}{Routines handling integers as lists of token digits} -% \lverb|& -% Routines handling big integers which are lists of digit tokens with no -% special additional structure. The argument is only subjected to a -% \romannumeral`^^@ expansion when macros have "ii" in their names. -% -% Some -% routines do not accept non properly terminated inputs like "\the\numexpr1", -% or "\the\mathcode`\-", others do. -% -% These routines or their sub-routines are mainly for internal usage. -% | -% -% \subsection{\csh{XINT_cuz_small}} -% \lverb|& -% \XINT_cuz_small removes leading zeroes from the first eight digits. Expands -% following \romannumeral0. At least one digit is produced.| -% \begin{macrocode} -\def\XINT_cuz_small#1{% -\def\XINT_cuz_small ##1##2##3##4##5##6##7##8% -{% - \expandafter#1\the\numexpr ##1##2##3##4##5##6##7##8\relax -}}\XINT_cuz_small{ }% -% \end{macrocode} -% \subsection{\csh{xintSgn}, \csh{xintiiSgn}, \csh{XINT_Sgn}, \csh{XINT_cntSgn}} +% \subsection{\csh{xintiiSgn}} % \lverb|& -% xintfrac.sty will rewrite \xintSgn to let it accept general input as recognized by -% xintfrac.sty macros +% 1.2l made \xintiiSgn robust against non terminated input. % -% 1.2l: \xintiiSgn made robust against non terminated input. +% 1.2o deprecates here \xintSgn (it requires xintfrac.sty). % | % \begin{macrocode} \def\xintiiSgn {\romannumeral0\xintiisgn }% @@ -18349,7 +18371,7 @@ $1$ or $-1$. {% \expandafter\XINT_sgn \romannumeral`&&@#1\xint: }% -\def\xintSgn {\romannumeral0\xintsgn }% +\def\xintSgn {\romannumeral0\XINT_signaldeprecated{xintcore}{xintSgn}\xintsgn }% \def\xintsgn #1% {% \expandafter\XINT_sgn \romannumeral0\xintnum{#1}\xint: @@ -18379,7 +18401,7 @@ $1$ or $-1$. \krof }% % \end{macrocode} -% \subsection{\csh{xintiOpp}, \csh{xintiiOpp}} +% \subsection{\csh{xintiiOpp}} % \lverb|Attention, \xintiiOpp non robust against non terminated inputs. % Reason is I don't want to have to grab a delimiter at the end, as everything % happens "upfront".| @@ -18389,7 +18411,7 @@ $1$ or $-1$. {% \expandafter\XINT_opp \romannumeral`&&@#1% }% -\def\xintiOpp {\romannumeral0\xintiopp }% +\def\xintiOpp {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiOpp}\xintiopp }% \def\xintiopp #1% {% \expandafter\XINT_opp \romannumeral0\xintnum{#1}% @@ -18404,15 +18426,17 @@ $1$ or $-1$. \krof }% % \end{macrocode} -% \subsection{\csh{xintiAbs}, \csh{xintiiAbs}} -% \lverb|Attention \xintiiAbs non robust against non terminated input.| +% \subsection{\csh{xintiiAbs}} +% \lverb|& +% Attention \xintiiAbs non robust against non terminated input. +%| % \begin{macrocode} \def\xintiiAbs {\romannumeral0\xintiiabs }% \def\xintiiabs #1% {% \expandafter\XINT_abs \romannumeral`&&@#1% }% -\def\xintiAbs {\romannumeral0\xintiabs }% +\def\xintiAbs {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiAbs}\xintiabs }% \def\xintiabs #1% {% \expandafter\XINT_abs \romannumeral0\xintnum{#1}% @@ -18425,23 +18449,20 @@ $1$ or $-1$. \krof }% % \end{macrocode} -% \subsection{\csh{xintFDg}, \csh{xintiiFDg}} +% \subsection{\csh{xintFDg}} % \lverb|& % FIRST DIGIT. % -% 1.2l: \xintiiFDg made robust against non terminated input.| +% 1.2l: \xintiiFDg made robust against non terminated input. +% +% 1.2o deprecates \xintiiFDg, gives to \xintFDg former meaning of \xintiiFDg.| % \begin{macrocode} -\def\xintiiFDg {\romannumeral0\xintiifdg }% -\def\xintiifdg #1% -{% - \expandafter\XINT_fdg \romannumeral`&&@#1\xint:\Z -}% \def\xintFDg {\romannumeral0\xintfdg }% -\def\xintfdg #1% -{% - \expandafter\XINT_fdg \romannumeral0\xintnum{#1}\xint:\Z -}% -\def\XINT_FDg #1{\romannumeral0\XINT_fdg #1\xint:\Z }% +\def\xintfdg #1{\expandafter\XINT_fdg \romannumeral`&&@#1\xint:\Z}% +\def\xintiiFDg {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiiFDg}\xintiifdg }% +\let\xintiifdg\xintfdg +\def\XINT_FDg #1% + {\romannumeral0\expandafter\XINT_fdg\romannumeral`&&@\xintnum{#1}\xint:\Z }% \def\XINT_fdg #1#2#3\Z {% \xint_UDzerominusfork @@ -18451,22 +18472,23 @@ $1$ or $-1$. \krof }% % \end{macrocode} -% \subsection{\csh{xintLDg}, \csh{xintiiLDg}} +% \subsection{\csh{xintLDg}} % \lverb|& % LAST DIGIT. % % Rewritten for 1.2i (2016/12/10). Surprisingly perhaps, it is faster than % \xintLastItem from xintkernel.sty despite the \numexpr operations. % -% Attention \xintiiLDg non robust against non terminated input. +% 1.2o deprecates \xintiiLDg, gives to \xintLDg former meaning of \xintiiLDg. +% +% Attention \xintLDg non robust against non terminated input. % | % \begin{macrocode} -\def\xintLDg {\romannumeral0\xintldg }% -\def\xintldg #1{\expandafter\XINT_ldg_fork\romannumeral0\xintnum{#1}% - \XINT_ldg_c{}{}{}{}{}{}{}{}\xint_bye\relax}% -\def\xintiiLDg {\romannumeral0\xintiildg }% -\def\xintiildg #1{\expandafter\XINT_ldg_fork\romannumeral`&&@#1% +\def\xintLDg {\romannumeral0\xintldg }% +\def\xintldg #1{\expandafter\XINT_ldg_fork\romannumeral`&&@#1% \XINT_ldg_c{}{}{}{}{}{}{}{}\xint_bye\relax}% +\def\xintiiLDg {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiiLDg}\xintiildg }% +\let\xintiildg\xintldg \def\XINT_ldg_fork #1% {% \xint_UDsignfork @@ -19034,10 +19056,10 @@ $1$ or $-1$. % it reduced the allowable numbers for addition from 19976 digits to 19968 % digits.| % -% \subsection{\csbh{xintiAdd}, \csbh{xintiiAdd}} +% \subsection{\csbh{xintiiAdd}} % \lverb|1.2l: \xintiiAdd made robust against non terminated input.| % \begin{macrocode} -\def\xintiAdd {\romannumeral0\xintiadd }% +\def\xintiAdd {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiAdd}\xintiadd }% \def\xintiadd #1{\expandafter\XINT_iadd\romannumeral0\xintnum{#1}\xint:}% \def\xintiiAdd {\romannumeral0\xintiiadd }% \def\xintiiadd #1{\expandafter\XINT_iiadd\romannumeral`&&@#1\xint:}% @@ -19222,13 +19244,15 @@ $1$ or $-1$. % \begin{macrocode} \def\XINT_add_o #1{\if #12\expandafter\XINT_add_l\else\expandafter\XINT_add_ke \fi}% % \end{macrocode} -% \subsection{\csh{xintCmp}, \csh{xintiiCmp}} +% \subsection{\csh{xintiiCmp}} % \lverb|Moved from xint.sty to xintcore.sty and rewritten for 1.2l. % % 1.2l's \xintiiCmp is robust against non terminated input. -% | +% +% 1.2o deprecates \xintCmp, with xintfrac loaded it will get overwritten anyhow. +%| % \begin{macrocode} -\def\xintCmp {\romannumeral0\xintcmp }% +\def\xintCmp {\romannumeral0\XINT_signaldeprecated{xintcore}{xintCmp}\xintcmp }% \def\xintcmp #1{\expandafter\XINT_icmp\romannumeral0\xintnum{#1}\xint:}% \def\xintiiCmp {\romannumeral0\xintiicmp }% \def\xintiicmp #1{\expandafter\XINT_iicmp\romannumeral`&&@#1\xint:}% @@ -19333,7 +19357,7 @@ $1$ or $-1$. \def\XINT_cmp_gt#1{\def\XINT_cmp_gt\fi ##1\W ##2\W {\fi#11}}\XINT_cmp_gt{ }% \def\XINT_cmp_equal #1\W #2\W { 0}% % \end{macrocode} -% \subsection{\csh{xintiSub}, \csh{xintiiSub}} +% \subsection{\csh{xintiiSub}} % \lverb|Entirely rewritten for 1.2. % % Refactored at 1.2l. I was initially aiming at clinching some internal format @@ -19365,7 +19389,7 @@ $1$ or $-1$. \expandafter\XINT_sub_nfork\expandafter #1\romannumeral`&&@#3\xint:#2\xint: }% -\def\xintiSub {\romannumeral0\xintisub }% +\def\xintiSub {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiSub}\xintisub }% \def\xintisub #1{\expandafter\XINT_isub\romannumeral0\xintnum{#1}\xint:}% \def\XINT_isub #1#2\xint:#3% {% @@ -19678,12 +19702,12 @@ $1$ or $-1$. % \begin{macrocode} \def\XINT_sub_comp_clean 1#1{+#1\relax}% % \end{macrocode} -% \subsection{\csh{xintiMul}, \csh{xintiiMul}} +% \subsection{\csh{xintiiMul}} % \lverb|Completely rewritten for 1.2. % % 1.2l: \xintiiMul made robust against non terminated input.| % \begin{macrocode} -\def\xintiMul {\romannumeral0\xintimul }% +\def\xintiMul {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiMul}\xintimul }% \def\xintimul #1% {% \expandafter\XINT_imul\romannumeral0\xintnum{#1}\xint: @@ -19918,8 +19942,7 @@ $1$ or $-1$. 1#6#7\expandafter!\the\numexpr \xint_c_x^viii+#1#2#3#4#5+#8!% }% % \end{macrocode} -% \subsection{\csh{xintiDivision}, \csh{xintiQuo}, \csh{xintiRem}, -% \csh{xintiiDivision}, \csh{xintiiQuo}, \csh{xintiiRem}} +% \subsection{\csh{xintiiDivision}} % \lverb|Completely rewritten for 1.2. % % WARNING: some comments below try to describe the flow of tokens but they @@ -19939,23 +19962,12 @@ $1$ or $-1$. % the way the code was structured has disappeared. % % -% 1.2l: \xintiiDivision et al. made robust against non terminated input.| -% \begin{macrocode} -\def\xintiiQuo {\romannumeral0\xintiiquo }% -\def\xintiiRem {\romannumeral0\xintiirem }% -\def\xintiiquo {\expandafter\xint_firstoftwo_thenstop\romannumeral0\xintiidivision }% -\def\xintiirem {\expandafter\xint_secondoftwo_thenstop\romannumeral0\xintiidivision }% -\def\xintiQuo {\romannumeral0\xintiquo }% -\def\xintiRem {\romannumeral0\xintirem }% -\def\xintiquo {\expandafter\xint_firstoftwo_thenstop\romannumeral0\xintidivision }% -\def\xintirem {\expandafter\xint_secondoftwo_thenstop\romannumeral0\xintidivision }% -%%\let\xintQuo\xintiQuo\let\xintquo\xintiquo % now removed -%%\let\xintRem\xintiRem\let\xintrem\xintirem % now removed -% \end{macrocode} +% 1.2l: \xintiiDivision et al. made robust against non terminated input. +% | % \lverb-#1 = A, #2 = B. On calcule le quotient et le reste dans la division % euclidienne de A par B: A=BQ+R, 0<= R < |B|.- % \begin{macrocode} -\def\xintiDivision {\romannumeral0\xintidivision }% +\def\xintiDivision {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiDivision}\xintidivision }% \def\xintidivision #1{\expandafter\XINT_idivision\romannumeral0\xintnum{#1}\xint:}% \def\XINT_idivision #1#2\xint:#3{\expandafter\XINT_iidivision_a\expandafter #1% \romannumeral0\xintnum{#3}\xint:#2\xint:}% @@ -20047,7 +20059,7 @@ $1$ or $-1$. \def\XINT_div_BisTwo #1#2% {% \expandafter\expandafter\expandafter\XINT_div_BisTwo_a - \ifodd\xintiiLDg{#2} \expandafter1\else \expandafter0\fi {#2}% + \ifodd\xintLDg{#2} \expandafter1\else \expandafter0\fi {#2}% }% \def\XINT_div_BisTwo_a #1#2% {% @@ -20800,13 +20812,28 @@ $1$ or $-1$. % \end{macrocode} % \subsection*{Derived arithmetic} % \addcontentsline{toc}{subsection}{Derived arithmetic} -% \subsection{\csh{xintiDivRound}, \csh{xintiiDivRound}} +% \subsection{\csh{xintiiQuo}, \csh{xintiiRem}} +% \begin{macrocode} +\def\xintiiQuo {\romannumeral0\xintiiquo }% +\def\xintiiRem {\romannumeral0\xintiirem }% +\def\xintiiquo + {\expandafter\xint_firstoftwo_thenstop\romannumeral0\xintiidivision }% +\def\xintiirem + {\expandafter\xint_secondoftwo_thenstop\romannumeral0\xintiidivision }% +\def\xintiQuo {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiQuo}\xintiquo }% +\def\xintiRem {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiRem}\xintirem }% +\def\xintiquo + {\expandafter\xint_firstoftwo_thenstop\romannumeral0\xintidivision }% +\def\xintirem + {\expandafter\xint_secondoftwo_thenstop\romannumeral0\xintidivision }% +% \end{macrocode} +% \subsection{\csh{xintiiDivRound}} % \lverb|1.1, transferred from first release of bnumexpr. Rewritten for 1.2. % Ending rewritten for 1.2i. (new \xintDSRr). % % 1.2l: \xintiiDivRound made robust against non terminated input.| % \begin{macrocode} -\def\xintiDivRound {\romannumeral0\xintidivround }% +\def\xintiDivRound {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiDivRound}\xintidivround }% \def\xintidivround #1% {\expandafter\XINT_idivround\romannumeral0\xintnum{#1}\xint:}% \def\xintiiDivRound {\romannumeral0\xintiidivround }% @@ -20848,10 +20875,10 @@ $1$ or $-1$. \xint_bye\xint_Bye3456789\xint_bye/\xint_c_x\relax }% % \end{macrocode} -% \subsection{\csh{xintiDivTrunc}, \csh{xintiiDivTrunc}} +% \subsection{\csh{xintiiDivTrunc}} % \lverb|1.2l: \xintiiDivTrunc made robust against non terminated input.| % \begin{macrocode} -\def\xintiDivTrunc {\romannumeral0\xintidivtrunc }% +\def\xintiDivTrunc {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiDivTrunc}\xintidivtrunc }% \def\xintidivtrunc #1{\expandafter\XINT_iidivtrunc\romannumeral0\xintnum{#1}\xint:}% \def\xintiiDivTrunc {\romannumeral0\xintiidivtrunc }% \def\xintiidivtrunc #1{\expandafter\XINT_iidivtrunc\romannumeral`&&@#1\xint:}% @@ -20882,9 +20909,9 @@ $1$ or $-1$. {\expandafter\xint_firstoftwo_thenstop \romannumeral0\XINT_div_prepare {#2}{#1#3}}% % \end{macrocode} -% \subsection{\csh{xintiMod}, \csh{xintiiMod}} +% \subsection{\csh{xintiiMod}} % \begin{macrocode} -\def\xintiMod {\romannumeral0\xintimod }% +\def\xintiMod {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiMod}\xintimod }% \def\xintimod #1{\expandafter\XINT_iimod\romannumeral0\xintnum{#1}\xint:}% \def\xintiiMod {\romannumeral0\xintiimod }% \def\xintiimod #1{\expandafter\XINT_iimod\romannumeral`&&@#1\xint:}% @@ -20915,7 +20942,7 @@ $1$ or $-1$. {\expandafter\xint_secondoftwo_thenstop\romannumeral0\XINT_div_prepare {#2}{#1#3}}% % \end{macrocode} -% \subsection{\csh{xintiSqr}, \csh{xintiiSqr}} +% \subsection{\csh{xintiiSqr}} % \lverb|1.2l: \xintiiSqr made robust against non terminated input.| % \begin{macrocode} \def\xintiiSqr {\romannumeral0\xintiisqr }% @@ -20923,7 +20950,7 @@ $1$ or $-1$. {% \expandafter\XINT_sqr\romannumeral0\xintiiabs{#1}\xint: }% -\def\xintiSqr {\romannumeral0\xintisqr }% +\def\xintiSqr {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiSqr}\xintisqr }% \def\xintisqr #1% {% \expandafter\XINT_sqr\romannumeral0\xintiabs{#1}\xint: @@ -20976,7 +21003,7 @@ $1$ or $-1$. 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W }% % \end{macrocode} -% \subsection{\csh{xintiPow}, \csh{xintiiPow}} +% \subsection{\csh{xintiiPow}} % \lverb|& % The exponent is not limited but with current default settings of tex memory, % with xint 1.2, the maximal exponent for 2^N is N = 2^17 = 131072. @@ -20995,7 +21022,7 @@ $1$ or $-1$. \expandafter\xint_pow\the\numexpr #2\expandafter .\romannumeral`&&@#1\xint: }% -\def\xintiPow {\romannumeral0\xintipow }% +\def\xintiPow {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiPow}\xintipow }% \def\xintipow #1#2% {% \expandafter\xint_pow\the\numexpr #2\expandafter @@ -21144,9 +21171,15 @@ $1$ or $-1$. \the\numexpr\XINT_pow_mulbutcheckifsmall #3\W #3\W #2\W }% % \end{macrocode} -% \subsection{\csh{xintiFac}, \csh{xintiiFac}} +% \subsection{\csh{xintiiFac}} % \lverb|Moved here from xint.sty with release 1.2 (to be usable by \bnumexpr). % +% An \xintiFac is needed by xintexpr.sty. Prior to 1.2o it was defined here +% as an alias to \xintiiFac, then redefined by xintfrac to use \xintNum. This +% was incoherent. Contrarily to other similarly named macros, +% \xintiiFac uses \numexpr on its input. This is also incoherent with the +% naming scheme, alas. +% % Partially rewritten with release 1.2 to benefit from the inner format of the % 1.2 multiplication. % @@ -21199,12 +21232,16 @@ $1$ or $-1$. % untouched. % % +% +% 1.2o modifies \xintiFac to be coherent with \xintiBinomial: only with +% xintfrac.sty loaded does it use \xintNum. It is documented only as macro of +% xintfrac.sty, not as macro of xint.sty. % | % \begin{macrocode} \def\xintiiFac {\romannumeral0\xintiifac }% \def\xintiifac #1{\expandafter\XINT_fac_fork\the\numexpr#1.}% -\def\xintiFac {\romannumeral0\xintifac }% -\let\xintifac\xintiifac +\def\xintiFac {\romannumeral0\XINT_signaldeprecated{xintcore}{xintiFac}\xintifac }% +\let\xintifac \xintiifac % redefined by xintfrac \def\XINT_fac_fork #1#2.% {% \xint_UDzerominusfork @@ -21245,181 +21282,756 @@ $1$ or $-1$. \the\numexpr #1+\xint_c_ii\expandafter.% \the\numexpr #2\expandafter.\the\numexpr\XINT_fac_bigloop_mul #1!% }% -\def\XINT_fac_bigloop_exit #1!{\XINT_mul_out}% -\def\XINT_fac_bigloop_mul #1!% +\def\XINT_fac_bigloop_exit #1!{\XINT_mul_out}% +\def\XINT_fac_bigloop_mul #1!% +{% + \expandafter\XINT_smallmul + \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!% +}% +\def\XINT_fac_medloop_a #1.% +{% + \expandafter\XINT_fac_medloop_b + \the\numexpr #1+\xint_c_i-\xint_c_iii*((#1-100)/\xint_c_iii).#1.% +}% +\def\XINT_fac_medloop_b #1.#2.% +{% + \expandafter\XINT_fac_smallloop_a + \the\numexpr #1-\xint_c_i.{\XINT_fac_medloop_loop #1.#2.}% +}% +\def\XINT_fac_medloop_loop #1.#2.% +{% + \ifnum #1>#2 \expandafter\XINT_fac_loop_exit\fi + \expandafter\XINT_fac_medloop_loop + \the\numexpr #1+\xint_c_iii\expandafter.% + \the\numexpr #2\expandafter.\the\numexpr\XINT_fac_medloop_mul #1!% +}% +\def\XINT_fac_medloop_mul #1!% +{% + \expandafter\XINT_smallmul + \the\numexpr + \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% +}% +\def\XINT_fac_smallloop_a #1.% +{% + \csname + XINT_fac_smallloop_\the\numexpr #1-\xint_c_iv*(#1/\xint_c_iv)\relax + \endcsname #1.% +}% +\expandafter\def\csname XINT_fac_smallloop_1\endcsname #1.% +{% + \XINT_fac_smallloop_loop 2.#1.100000001!1;!% +}% +\expandafter\def\csname XINT_fac_smallloop_-2\endcsname #1.% +{% + \XINT_fac_smallloop_loop 3.#1.100000002!1;!% +}% +\expandafter\def\csname XINT_fac_smallloop_-1\endcsname #1.% +{% + \XINT_fac_smallloop_loop 4.#1.100000006!1;!% +}% +\expandafter\def\csname XINT_fac_smallloop_0\endcsname #1.% +{% + \XINT_fac_smallloop_loop 5.#1.1000000024!1;!% +}% +\def\XINT_fac_smallloop_loop #1.#2.% +{% + \ifnum #1>#2 \expandafter\XINT_fac_loop_exit\fi + \expandafter\XINT_fac_smallloop_loop + \the\numexpr #1+\xint_c_iv\expandafter.% + \the\numexpr #2\expandafter.\the\numexpr\XINT_fac_smallloop_mul #1!% +}% +\def\XINT_fac_smallloop_mul #1!% +{% + \expandafter\XINT_smallmul + \the\numexpr + \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% +}% +\def\XINT_fac_loop_exit #1!#2;!#3{#3#2;!}% +% \end{macrocode} +% \subsection{\csh{XINT_signaldeprecated}} +% \lverb|1.2o| +% \begin{macrocode} +\def\XINT_signaldeprecated #1#2% +{% + \XINT_ifFlagRaised{#2}% + {}% already encountered (if not hidden in a group...) + {\XINT_RaiseFlag{Deprecated-#1}\XINT_RaiseFlag{#2}% + \expandafter\XINT_expandableerror\expandafter + {\csname#2\endcsname (#1) is deprecated! (RET to proceed)}}% +}% +% \end{macrocode} +% \subsection*{At End of \LaTeX\ Document deprecation message} +% \addcontentsline{toc}{subsection}{At End of \LaTeX\ Document deprecation message} +% \lverb|1.2o| +% \begin{macrocode} +\ifdefined\documentclass\ifdefined\AtEndDocument + \AtEndDocument{% +\XINT_ifFlagRaised{Deprecated-xintcore}% + {\PackageError{xintcore} +{Usage of deprecated macros!} +{These deprecated macros from xintcore.sty have been detected:\MessageBreak +\XINT_useiimessage{xintSgn}% +\XINT_useiimessage{xintCmp}% +\XINT_ifFlagRaised{xintiOpp}{\string\xintiOpp\MessageBreak}{}% +\XINT_ifFlagRaised{xintiAbs}{\string\xintiAbs\MessageBreak}{}% +\XINT_ifFlagRaised{xintiiFDg}{\string\xintiiFDg\space(renamed to \string\xintFDg!)\MessageBreak}{}% +\XINT_ifFlagRaised{xintiiLDg}{\string\xintiiLDg\space(renamed to \string\xintLDg!)\MessageBreak}{}% +\XINT_ifFlagRaised{xintiAdd}{\string\xintiAdd\MessageBreak}{}% +\XINT_ifFlagRaised{xintiSub}{\string\xintiSub\MessageBreak}{}% +\XINT_ifFlagRaised{xintiMul}{\string\xintiMul\MessageBreak}{}% +\XINT_ifFlagRaised{xintiDivision}{\string\xintiDivision\MessageBreak}{}% +\XINT_ifFlagRaised{xintiQuo}{\string\xintiQuo\MessageBreak}{}% +\XINT_ifFlagRaised{xintiRem}{\string\xintiRem\MessageBreak}{}% +\XINT_ifFlagRaised{xintiDivRound}{\string\xintiDivRound\MessageBreak}{}% +\XINT_ifFlagRaised{xintiDivTrunc}{\string\xintiDivTrunc\MessageBreak}{}% +\XINT_ifFlagRaised{xintiMod}{\string\xintiMod\MessageBreak}{}% +\XINT_ifFlagRaised{xintiSqr}{\string\xintiSqr\MessageBreak}{}% +\XINT_ifFlagRaised{xintiPow}{\string\xintiPow\MessageBreak}{}% +\XINT_ifFlagRaised{xintiFac}{\string\xintiFac\MessageBreak}{}% +They will get removed at some future release.}}% + {% no deprecated macro used (at top level...) + }% +}\fi\fi +% \end{macrocode} +% \subsection{\csh{XINT_useiimessage}} +% \lverb|1.2o| +% \begin{macrocode} +\def\XINT_useiimessage #1% used in LaTeX only +{% + \XINT_ifFlagRaised {#1}% + {\@backslashchar#1 + (load xintfrac or use \@backslashchar xintii\xint_gobble_iv#1!)\MessageBreak}% + {}% +}% +\XINT_restorecatcodes_endinput% +% \end{macrocode} +% +% \StoreCodelineNo {xintcore} +% +%\gardesactifs +%\let\relax +%\let<*xint>\gardesinactifs +%^^A--------------------------------------------------- +%<*xint>^^A------------------------------------------------------- +% \clearpage +% \section{Package \xintnameimp implementation} +% \label{sec:xintimp} +% +% \localtableofcontents +% +% With release |1.1| the core arithmetic routines |\xintiiAdd|, +% |\xintiiSub|, |\xintiiMul|, |\xintiiQuo|, |\xintiiPow| were separated to be +% the main component of the then new +% \xintcorenameimp. +% \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 % : + \let\z\endgroup + \expandafter\let\expandafter\x\csname ver@xint.sty\endcsname + \expandafter\let\expandafter\w\csname ver@xintcore.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 xintcore.sty + \ifx\w\relax % but xintkernel.sty not yet loaded. + \def\z{\endgroup\input xintcore.sty\relax}% + \fi + \else + \def\empty {}% + \ifx\x\empty % LaTeX, first loading, + % variable is initialized, but \ProvidesPackage not yet seen + \ifx\w\relax % xintcore.sty not yet loaded. + \def\z{\endgroup\RequirePackage{xintcore}}% + \fi + \else + \aftergroup\endinput % xint already loaded. + \fi + \fi + \fi +\z% +\XINTsetupcatcodes% defined in xintkernel.sty (loaded by xintcore.sty) +% \end{macrocode} +% \subsection{Package identification} +% \begin{macrocode} +\XINT_providespackage +\ProvidesPackage{xint}% + [2017/08/29 1.2o Expandable operations on big integers (JFB)]% +% \end{macrocode} +% \subsection{More token management} +% \begin{macrocode} +\long\def\xint_firstofthree #1#2#3{#1}% +\long\def\xint_secondofthree #1#2#3{#2}% +\long\def\xint_thirdofthree #1#2#3{#3}% +\long\def\xint_firstofthree_thenstop #1#2#3{ #1}% 1.09i +\long\def\xint_secondofthree_thenstop #1#2#3{ #2}% +\long\def\xint_thirdofthree_thenstop #1#2#3{ #3}% +% \end{macrocode} +% \subsection{\csh{xintLen}} +% \lverb|\xintLen gets extended to fractions by xintfrac.sty: A/B is given +% length len(A)+len(B)-1 (somewhat arbitrary). It applies \xintNum to its +% argument. A minus sign is accepted and ignored. +% +% +% For parallelism with \xintiNum/\xintNum, 1.2o defines \xintiLen. +% | +% \begin{macrocode} +\def\xintiLen {\romannumeral0\xintilen }% +\def\xintilen #1{\def\xintilen ##1% +{% + \expandafter#1\the\numexpr + \expandafter\XINT_len_fork\romannumeral0\xintinum{##1}% + \xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint: + \xint_c_viii\xint_c_vii\xint_c_vi\xint_c_v + \xint_c_iv\xint_c_iii\xint_c_ii\xint_c_i\xint_c_\xint_bye\relax +}}\xintilen{ }% +\def\xintLen {\romannumeral0\xintlen }% +\let\xintlen\xintilen +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\XINT_len_fork #1% +{% + \expandafter\XINT_length_loop\xint_UDsignfork#1{}-#1\krof +}% +% \end{macrocode} +% \subsection{\csh{xintReverseDigits}} +% \lverb|& +% 1.2. +% +% This puts digits in reverse order, not suppressing leading zeros +% after reverse. Despite lacking the "ii" in its name, it does not apply +% \xintNum to its argument (contrarily to \xintLen, this is not very coherent). +% +% 1.2l variant is robust against non terminated \the\numexpr input. +% +% This macro is currently not used elsewhere in xint code. +% | +% \begin{macrocode} +\def\xintReverseDigits {\romannumeral0\xintreversedigits }% +\def\xintreversedigits #1% +{% + \expandafter\XINT_revdigits\romannumeral`&&@#1% + {\XINT_microrevsep_end\W}\XINT_microrevsep_end + \XINT_microrevsep_end\XINT_microrevsep_end + \XINT_microrevsep_end\XINT_microrevsep_end + \XINT_microrevsep_end\XINT_microrevsep_end\XINT_microrevsep_end\Z + 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W +}% +\def\XINT_revdigits #1% +{% + \xint_UDsignfork + #1{\expandafter-\romannumeral0\XINT_revdigits_a}% + -{\XINT_revdigits_a #1}% + \krof +}% +\def\XINT_revdigits_a +{% + \expandafter\XINT_revdigits_b\expandafter{\expandafter}% + \the\numexpr\XINT_microrevsep +}% +\def\XINT_microrevsep #1#2#3#4#5#6#7#8#9% +{% + 1#9#8#7#6#5#4#3#2#1\expandafter!\the\numexpr\XINT_microrevsep +}% +\def\XINT_microrevsep_end #1\W #2\expandafter #3\Z{\relax#2!}% +\def\XINT_revdigits_b #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!% +{% + \xint_gob_til_R #9\XINT_revdigits_end\R + \XINT_revdigits_b {#9#8#7#6#5#4#3#2#1}% +}% +\def\XINT_revdigits_end#1{% +\def\XINT_revdigits_end\R\XINT_revdigits_b ##1##2\W + {\expandafter#1\xint_gob_til_Z ##1}% +}\XINT_revdigits_end{ }% +\let\xintRev\xintReverseDigits +% \end{macrocode} +% \subsection{\csh{xintiiE}} +% \lverb|Originally was used in \xintiiexpr. Transferred from xintfrac for +% 1.1. +% Code rewritten for 1.2i. +%%÷ Used in \xintMod +% | +% \begin{macrocode} +\def\xintiiE {\romannumeral0\xintiie }% +\def\xintiie #1#2% + {\expandafter\XINT_iie_fork\the\numexpr #2\expandafter.\romannumeral`&&@#1;}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\XINT_iie_fork #1% +{% + \xint_UDsignfork + #1\XINT_iie_neg + -\XINT_iie_a + \krof #1% +}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\XINT_iie_a #1.% + {\expandafter\XINT_dsx_append\romannumeral\XINT_rep #1\endcsname 0.}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\XINT_iie_neg #1.#2;{ #2}% +% \end{macrocode} +% \subsection{\csh{xintDecSplit}} +% \lverb!DECIMAL SPLIT +% +% The macro \xintDecSplit {x}{A} cuts A which is composed of digits (leading +% zeroes ok, but no sign) (*) into two (each possibly empty) pieces L and R. +% The concatenation LR always reproduces A. +% +% The position of the cut is specified by the first argument x. If x is zero +% or positive the cut location is x slots to the left of the right end of the +% number. If x becomes equal to or larger than the length of the number then L +% becomes empty. If x is negative the location of the cut is |x| slots to the +% right of the left end of the number. +% +% (*) versions earlier than 1.2i first replaced A with its absolute value. +% This is not the case anymore. This macro should NOT be used for A with a +% leading sign (+ or -). +% +% Entirely rewritten for 1.2i (2016/12/11). +% +% Attention: \xintDecSplit not robust against non terminated second argument. +% ! +% \begin{macrocode} +\def\xintDecSplit {\romannumeral0\xintdecsplit }% +\def\xintdecsplit #1#2% +{% + \expandafter\XINT_split_finish + \romannumeral0\expandafter\XINT_split_xfork + \the\numexpr #1\expandafter.\romannumeral`&&@#2% + \xint_bye2345678\xint_bye..% +}% +\def\XINT_split_finish #1.#2.{{#1}{#2}}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\XINT_split_xfork #1% +{% + \xint_UDzerominusfork + #1-\XINT_split_zerosplit + 0#1\XINT_split_fromleft + 0-{\XINT_split_fromright #1}% + \krof +}% +\def\XINT_split_zerosplit .#1\xint_bye#2\xint_bye..{ #1..}% +\def\XINT_split_fromleft + {\expandafter\XINT_split_fromleft_a\the\numexpr\xint_c_viii-}% +\def\XINT_split_fromleft_a #1% +{% + \xint_UDsignfork + #1\XINT_split_fromleft_b + -{\XINT_split_fromleft_end_a #1}% + \krof +}% +\def\XINT_split_fromleft_b #1.#2#3#4#5#6#7#8#9% +{% + \expandafter\XINT_split_fromleft_clean + \the\numexpr1#2#3#4#5#6#7#8#9\expandafter + \XINT_split_fromleft_a\the\numexpr\xint_c_viii-#1.% +}% +\def\XINT_split_fromleft_end_a #1.% +{% + \expandafter\XINT_split_fromleft_clean + \the\numexpr1\csname XINT_split_fromleft_end#1\endcsname +}% +\def\XINT_split_fromleft_clean 1{ }% +\expandafter\def\csname XINT_split_fromleft_end7\endcsname #1% + {#1\XINT_split_fromleft_end_b}% +\expandafter\def\csname XINT_split_fromleft_end6\endcsname #1#2% + {#1#2\XINT_split_fromleft_end_b}% +\expandafter\def\csname XINT_split_fromleft_end5\endcsname #1#2#3% + {#1#2#3\XINT_split_fromleft_end_b}% +\expandafter\def\csname XINT_split_fromleft_end4\endcsname #1#2#3#4% + {#1#2#3#4\XINT_split_fromleft_end_b}% +\expandafter\def\csname XINT_split_fromleft_end3\endcsname #1#2#3#4#5% + {#1#2#3#4#5\XINT_split_fromleft_end_b}% +\expandafter\def\csname XINT_split_fromleft_end2\endcsname #1#2#3#4#5#6% + {#1#2#3#4#5#6\XINT_split_fromleft_end_b}% +\expandafter\def\csname XINT_split_fromleft_end1\endcsname #1#2#3#4#5#6#7% + {#1#2#3#4#5#6#7\XINT_split_fromleft_end_b}% +\expandafter\def\csname XINT_split_fromleft_end0\endcsname #1#2#3#4#5#6#7#8% + {#1#2#3#4#5#6#7#8\XINT_split_fromleft_end_b}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\XINT_split_fromleft_end_b #1\xint_bye#2\xint_bye.{.#1}% puis . +\def\XINT_split_fromright #1.#2\xint_bye +{% + \expandafter\XINT_split_fromright_a + \the\numexpr#1-\numexpr\XINT_length_loop + #2\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint: + \xint_c_viii\xint_c_vii\xint_c_vi\xint_c_v + \xint_c_iv\xint_c_iii\xint_c_ii\xint_c_i\xint_c_\xint_bye + .#2\xint_bye +}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\XINT_split_fromright_a #1% +{% + \xint_UDsignfork + #1\XINT_split_fromleft + -\XINT_split_fromright_Lempty + \krof +}% +\def\XINT_split_fromright_Lempty #1.#2\xint_bye#3..{.#2.}% +% \end{macrocode} +% \subsection{\csh{xintDecSplitL}} +% \begin{macrocode} +\def\xintDecSplitL {\romannumeral0\xintdecsplitl }% +\def\xintdecsplitl #1#2% +{% + \expandafter\XINT_splitl_finish + \romannumeral0\expandafter\XINT_split_xfork + \the\numexpr #1\expandafter.\romannumeral`&&@#2% + \xint_bye2345678\xint_bye..% +}% +\def\XINT_splitl_finish #1.#2.{ #1}% +% \end{macrocode} +% \subsection{\csh{xintDecSplitR}} +% \begin{macrocode} +\def\xintDecSplitR {\romannumeral0\xintdecsplitr }% +\def\xintdecsplitr #1#2% +{% + \expandafter\XINT_splitr_finish + \romannumeral0\expandafter\XINT_split_xfork + \the\numexpr #1\expandafter.\romannumeral`&&@#2% + \xint_bye2345678\xint_bye..% +}% +\def\XINT_splitr_finish #1.#2.{ #2}% +% \end{macrocode} +% \subsection{\csh{xintDSHr}} +% \lverb!DECIMAL SHIFTS \xintDSH {x}{A}$\ +% si x <= 0, fait A -> A.10^(|x|). +% si x > 0, et A >=0, fait A -> quo(A,10^(x))$\ +% si x > 0, et A < 0, fait A -> -quo(-A,10^(x))$\ +% (donc pour x > 0 c'est comme DSR itéré x fois)$\ +% \xintDSHr donne le `reste' (si x<=0 donne zéro). +% +% Badly named macros. +% +% Rewritten for 1.2i, this was old code and \xintDSx has changed interface. +% ! +% \begin{macrocode} +\def\xintDSHr {\romannumeral0\xintdshr }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\xintdshr #1#2% +{% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} + \expandafter\XINT_dshr_fork\the\numexpr#1\expandafter.\romannumeral`&&@#2;% +}% +\def\XINT_dshr_fork #1% +{% + \xint_UDzerominusfork + 0#1\XINT_dshr_xzeroorneg + #1-\XINT_dshr_xzeroorneg + 0-\XINT_dshr_xpositive + \krof #1% +}% +\def\XINT_dshr_xzeroorneg #1;{ 0}% +\def\XINT_dshr_xpositive +{% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} + \expandafter\xint_secondoftwo_thenstop\romannumeral0\XINT_dsx_xisPos +}% +% \end{macrocode} +% \subsection{\csh{xintDSH}} +% \begin{macrocode} +\def\xintDSH {\romannumeral0\xintdsh }% +\def\xintdsh #1#2% +{% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} + \expandafter\XINT_dsh_fork\the\numexpr#1\expandafter.\romannumeral`&&@#2;% +}% +\def\XINT_dsh_fork #1% +{% + \xint_UDzerominusfork + #1-\XINT_dsh_xiszero +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} + 0#1\XINT_dsx_xisNeg_checkA + 0-{\XINT_dsh_xisPos #1}% + \krof +}% +\def\XINT_dsh_xiszero #1.#2;{ #2}% +\def\XINT_dsh_xisPos +{% +% \end{macrocode} +% \lverb|& + \expandafter\xint_firstoftwo_thenstop\romannumeral0\XINT_dsx_xisPos +% | +% \begin{macrocode} +}% +% \end{macrocode} +% \subsection{\csh{xintDSx}} +% \lverb!& +% --> Attention le cas x=0 est traité dans la même catégorie que x > 0 <--$\ +% si x < 0, fait A -> A.10^(|x|)$\ +% si x >= 0, et A >=0, fait A -> {quo(A,10^(x))}{rem(A,10^(x))}$\ +% si x >= 0, et A < 0, d'abord on calcule {quo(-A,10^(x))}{rem(-A,10^(x))}$\ +% puis, si le premier n'est pas nul on lui donne le signe -$\ +% si le premier est nul on donne le signe - au second. +% +% On peut donc toujours reconstituer l'original A par 10^x Q \pm R +% où il faut prendre le signe plus si Q est positif ou nul et le signe moins si +% Q est strictement négatif. +% +% Rewritten for 1.2i, this was old code. +% +% ! +% \begin{macrocode} +\def\xintDSx {\romannumeral0\xintdsx }% +\def\xintdsx #1#2% +{% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} + \expandafter\XINT_dsx_fork\the\numexpr#1\expandafter.\romannumeral`&&@#2;% +}% +\def\XINT_dsx_fork #1% {% - \expandafter\XINT_smallmul - \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!% + \xint_UDzerominusfork + #1-\XINT_dsx_xisZero + 0#1\XINT_dsx_xisNeg_checkA + 0-{\XINT_dsx_xisPos #1}% + \krof }% -\def\XINT_fac_medloop_a #1.% +\def\XINT_dsx_xisZero #1.#2;{{#2}{0}}% +\def\XINT_dsx_xisNeg_checkA #1.#2% {% - \expandafter\XINT_fac_medloop_b - \the\numexpr #1+\xint_c_i-\xint_c_iii*((#1-100)/\xint_c_iii).#1.% + \xint_gob_til_zero #2\XINT_dsx_xisNeg_Azero 0% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} + \expandafter\XINT_dsx_append\romannumeral\XINT_rep #1\endcsname 0.#2% }% -\def\XINT_fac_medloop_b #1.#2.% +\def\XINT_dsx_xisNeg_Azero #1;{ 0}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\XINT_dsx_addzeros #1% + {\expandafter\XINT_dsx_append\romannumeral\XINT_rep#1\endcsname0.}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\XINT_dsx_addzerosnofuss #1% + {\expandafter\XINT_dsx_append\romannumeral\xintreplicate{#1}0.}% +\def\XINT_dsx_append #1.#2;{ #2#1}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\XINT_dsx_xisPos #1.#2% {% - \expandafter\XINT_fac_smallloop_a - \the\numexpr #1-\xint_c_i.{\XINT_fac_medloop_loop #1.#2.}% + \xint_UDzerominusfork + #2-\XINT_dsx_AisZero + 0#2\XINT_dsx_AisNeg + 0-\XINT_dsx_AisPos + \krof #1.#2% }% -\def\XINT_fac_medloop_loop #1.#2.% +\def\XINT_dsx_AisZero #1;{{0}{0}}% +\def\XINT_dsx_AisNeg #1.-#2;% {% - \ifnum #1>#2 \expandafter\XINT_fac_loop_exit\fi - \expandafter\XINT_fac_medloop_loop - \the\numexpr #1+\xint_c_iii\expandafter.% - \the\numexpr #2\expandafter.\the\numexpr\XINT_fac_medloop_mul #1!% + \expandafter\XINT_dsx_AisNeg_checkiffirstempty + \romannumeral0\XINT_split_xfork #1.#2\xint_bye2345678\xint_bye..% }% -\def\XINT_fac_medloop_mul #1!% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\XINT_dsx_AisNeg_checkiffirstempty #1% {% - \expandafter\XINT_smallmul - \the\numexpr - \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!% + \xint_gob_til_dot #1\XINT_dsx_AisNeg_finish_zero.% + \XINT_dsx_AisNeg_finish_notzero #1% }% -\def\XINT_fac_smallloop_a #1.% +\def\XINT_dsx_AisNeg_finish_zero.\XINT_dsx_AisNeg_finish_notzero.#1.% {% - \csname - XINT_fac_smallloop_\the\numexpr #1-\xint_c_iv*(#1/\xint_c_iv)\relax - \endcsname #1.% + \expandafter\XINT_dsx_end + \expandafter {\romannumeral0\XINT_num {-#1}}{0}% }% -\expandafter\def\csname XINT_fac_smallloop_1\endcsname #1.% +\def\XINT_dsx_AisNeg_finish_notzero #1.#2.% {% - \XINT_fac_smallloop_loop 2.#1.100000001!1;!% + \expandafter\XINT_dsx_end + \expandafter {\romannumeral0\XINT_num {#2}}{-#1}% }% -\expandafter\def\csname XINT_fac_smallloop_-2\endcsname #1.% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\XINT_dsx_AisPos #1.#2;% {% - \XINT_fac_smallloop_loop 3.#1.100000002!1;!% + \expandafter\XINT_dsx_AisPos_finish + \romannumeral0\XINT_split_xfork #1.#2\xint_bye2345678\xint_bye..% }% -\expandafter\def\csname XINT_fac_smallloop_-1\endcsname #1.% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\XINT_dsx_AisPos_finish #1.#2.% {% - \XINT_fac_smallloop_loop 4.#1.100000006!1;!% + \expandafter\XINT_dsx_end + \expandafter {\romannumeral0\XINT_num {#2}}% + {\romannumeral0\XINT_num {#1}}% }% -\expandafter\def\csname XINT_fac_smallloop_0\endcsname #1.% +\def\XINT_dsx_end #1#2{\expandafter{#2}{#1}}% +% \end{macrocode} +% \subsection{\csh{xintiiEq}} +% \lverb|no \xintiieq.| +% \begin{macrocode} +\def\xintEq {\romannumeral0\XINT_signaldeprecated{xint}{xintEq}\xinteq }% +\def\xinteq #1#2{\xintifeq{#1}{#2}{1}{0}}% +\def\xintiiEq #1#2{\romannumeral0\xintiiifeq{#1}{#2}{1}{0}}% +% \end{macrocode} +% \subsection{\csh{xintiiNotEq}} +% \lverb|Pour xintexpr. Pas de version en lowercase.| +% \begin{macrocode} +\def\xintNeq #1#2{\romannumeral0\XINT_signaldeprecated{xint}{xintNeq}\xintifeq {#1}{#2}{0}{1}}% +\def\xintiiNotEq #1#2{\romannumeral0\xintiiifeq {#1}{#2}{0}{1}}% +% \end{macrocode} +% \subsection{\csh{xintiiGeq}} +% \lverb|& +% PLUS GRAND OU ÉGAL +% attention compare les **valeurs absolues** +% +% 1.2l made \xintiiGeq robust against non terminated items. +% +% 1.2l rewrote \xintiiCmp, but forgot to handle \xintiiGeq too. Done at 1.2m. +% +% This macro should have been called \xintGEq for example. +% | +% \begin{macrocode} +\def\xintGeq {\romannumeral0\XINT_signaldeprecated{xint}{xintGeq}\xintgeq }% +\def\xintgeq #1{\expandafter\XINT_geq\romannumeral0\xintnum{#1}\xint:}% +\def\xintiiGeq {\romannumeral0\xintiigeq }% +\def\xintiigeq #1{\expandafter\XINT_iigeq\romannumeral`&&@#1\xint:}% +\def\XINT_iigeq #1#2\xint:#3% {% - \XINT_fac_smallloop_loop 5.#1.1000000024!1;!% + \expandafter\XINT_geq_fork\expandafter #1\romannumeral`&&@#3\xint:#2\xint: }% -\def\XINT_fac_smallloop_loop #1.#2.% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} +\def\XINT_geq #1#2\xint:#3% {% - \ifnum #1>#2 \expandafter\XINT_fac_loop_exit\fi - \expandafter\XINT_fac_smallloop_loop - \the\numexpr #1+\xint_c_iv\expandafter.% - \the\numexpr #2\expandafter.\the\numexpr\XINT_fac_smallloop_mul #1!% + \expandafter\XINT_geq_fork\expandafter #1\romannumeral0\xintnum{#3}\xint:#2\xint: }% -\def\XINT_fac_smallloop_mul #1!% +\def\XINT_geq_fork #1#2% {% - \expandafter\XINT_smallmul - \the\numexpr - \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!% + \xint_UDzerofork + #1\XINT_geq_firstiszero + #2\XINT_geq_secondiszero + 0{}% + \krof + \xint_UDsignsfork + #1#2\XINT_geq_minusminus + #1-\XINT_geq_minusplus + #2-\XINT_geq_plusminus + --\XINT_geq_plusplus + \krof #1#2% }% -\def\XINT_fac_loop_exit #1!#2;!#3{#3#2;!}% +\def\XINT_geq_firstiszero #1\krof 0#2#3\xint:#4\xint: + {\xint_UDzerofork #2{ 1}0{ 0}\krof }% +\def\XINT_geq_secondiszero #1\krof #20#3\xint:#4\xint:{ 1}% +\def\XINT_geq_plusminus #1-{\XINT_geq_plusplus #1{}}% +\def\XINT_geq_minusplus -#1{\XINT_geq_plusplus {}#1}% +\def\XINT_geq_minusminus --{\XINT_geq_plusplus {}{}}% +\def\XINT_geq_plusplus + {\expandafter\XINT_geq_finish\romannumeral0\XINT_cmp_plusplus}% +\def\XINT_geq_finish #1{\if-#1\expandafter\XINT_geq_no + \else\expandafter\XINT_geq_yes\fi}% +\def\XINT_geq_no 1{ 0}% +\def\XINT_geq_yes { 1}% % \end{macrocode} -% \subsection*{``Load \xintfracnameimp'' macros} -% \addcontentsline{toc}{subsection}{``Load \xintfracnameimp'' macros} -% \lverb|Originally was used in \xintiiexpr. Transferred from xintfrac for 1.1.| +% \subsection{\csh{xintiiGt}} % \begin{macrocode} -\catcode`! 11 -\def\xintAbs {\Did_you_mean_iiAbs?or_load_xintfrac!}% -\def\xintOpp {\Did_you_mean_iiOpp?or_load_xintfrac!}% -\def\xintAdd {\Did_you_mean_iiAdd?or_load_xintfrac!}% -\def\xintSub {\Did_you_mean_iiSub?or_load_xintfrac!}% -\def\xintMul {\Did_you_mean_iiMul?or_load_xintfrac!}% -\def\xintPow {\Did_you_mean_iiPow?or_load_xintfrac!}% -\def\xintSqr {\Did_you_mean_iiSqr?or_load_xintfrac!}% -\def\xintQuo {\Removed!use_xintiQuo_or_xintiiQuo!}% -\def\xintRem {\Removed!use_xintiRem_or_xintiiRem!}% -\catcode`! 12 -\XINT_restorecatcodes_endinput% +\def\xintGt {\romannumeral0\XINT_signaldeprecated{xint}{xintGt}\xintgt }% +\def\xintgt #1#2{\xintifgt{#1}{#2}{1}{0}}% +\def\xintiiGt #1#2{\romannumeral0\xintiiifgt{#1}{#2}{1}{0}}% % \end{macrocode} -% -% \StoreCodelineNo {xintcore} -% -%\gardesactifs -%\let\relax -%\let<*xint>\gardesinactifs -%^^A--------------------------------------------------- -%<*xint>^^A------------------------------------------------------- -% \clearpage -% \section{Package \xintnameimp implementation} -% \label{sec:xintimp} -% -% \localtableofcontents -% -% With release |1.1| the core arithmetic routines |\xintiiAdd|, -% |\xintiiSub|, |\xintiiMul|, |\xintiiQuo|, |\xintiiPow| were separated to be -% the main component of the then new -% \xintcorenameimp. +% \subsection{\csh{xintiiLt}} % \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 % : - \let\z\endgroup - \expandafter\let\expandafter\x\csname ver@xint.sty\endcsname - \expandafter\let\expandafter\w\csname ver@xintcore.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 xintcore.sty - \ifx\w\relax % but xintkernel.sty not yet loaded. - \def\z{\endgroup\input xintcore.sty\relax}% - \fi - \else - \def\empty {}% - \ifx\x\empty % LaTeX, first loading, - % variable is initialized, but \ProvidesPackage not yet seen - \ifx\w\relax % xintcore.sty not yet loaded. - \def\z{\endgroup\RequirePackage{xintcore}}% - \fi - \else - \aftergroup\endinput % xint already loaded. - \fi - \fi - \fi -\z% -\XINTsetupcatcodes% defined in xintkernel.sty (loaded by xintcore.sty) +\def\xintLt {\romannumeral0\XINT_signaldeprecated{xint}{xintLt}\xintlt }% +\def\xintlt #1#2{\xintiflt{#1}{#2}{1}{0}}% +\def\xintiiLt #1#2{\romannumeral0\xintiiiflt{#1}{#2}{1}{0}}% % \end{macrocode} -% \subsection{Package identification} +% \subsection{\csh{xintiiGtorEq}} % \begin{macrocode} -\XINT_providespackage -\ProvidesPackage{xint}% - [2017/08/06 1.2n Expandable operations on big integers (JFB)]% +\def\xintGtorEq #1#2{\romannumeral0\XINT_signaldeprecated{xint}{xintGtorEq}\xintiflt {#1}{#2}{0}{1}}% +\def\xintiiGtorEq #1#2{\romannumeral0\xintiiiflt {#1}{#2}{0}{1}}% % \end{macrocode} -% \subsection{More token management} +% \subsection{\csh{xintiiLtorEq}} % \begin{macrocode} -\long\def\xint_firstofthree #1#2#3{#1}% -\long\def\xint_secondofthree #1#2#3{#2}% -\long\def\xint_thirdofthree #1#2#3{#3}% -\long\def\xint_firstofthree_thenstop #1#2#3{ #1}% 1.09i -\long\def\xint_secondofthree_thenstop #1#2#3{ #2}% -\long\def\xint_thirdofthree_thenstop #1#2#3{ #3}% +\def\xintLtorEq #1#2{\romannumeral0\XINT_signaldeprecated{xint}{xintLtorEq}\xintifgt {#1}{#2}{0}{1}}% +\def\xintiiLtorEq #1#2{\romannumeral0\xintiiifgt {#1}{#2}{0}{1}}% % \end{macrocode} -% \subsection{\csh{xintSgnFork}} -% \lverb|Expandable three-way fork added in 1.07. The argument #1 must expand -% to non-self-ending -1,0 or 1. 1.09i with _thenstop.| +% \subsection{\csh{xintiiIsZero}} +% \lverb|1.09a. restyled in 1.09i. 1.1 adds \xintiiIsZero, etc... for +% optimization in \xintexpr| % \begin{macrocode} -\def\xintSgnFork {\romannumeral0\xintsgnfork }% -\def\xintsgnfork #1% -{% - \ifcase #1 \expandafter\xint_secondofthree_thenstop - \or\expandafter\xint_thirdofthree_thenstop - \else\expandafter\xint_firstofthree_thenstop - \fi -}% +\def\xintIsZero {\romannumeral0\XINT_signaldeprecated{xint}{xintIsZero}\xintiszero }% +\def\xintiszero #1{\if0\xintSgn{#1}\xint_afterfi{ 1}\else\xint_afterfi{ 0}\fi}% +\def\xintiiIsZero {\romannumeral0\xintiiiszero }% +\def\xintiiiszero #1{\if0\xintiiSgn{#1}\xint_afterfi{ 1}\else\xint_afterfi{ 0}\fi}% +% \end{macrocode} +% \subsection{\csh{xintiiIsNotZero}} +% \lverb|1.09a. restyled in 1.09i. 1.1 adds \xintiiIsZero, etc... for +% optimization in \xintexpr| +% \begin{macrocode} +\def\xintIsNotZero {\romannumeral0\XINT_signaldeprecated{xint}{xintIsNotZero}\xintisnotzero }% +\def\xintisnotzero + #1{\if0\xintSgn{#1}\xint_afterfi{ 0}\else\xint_afterfi{ 1}\fi}% +\def\xintiiIsNotZero {\romannumeral0\xintiiisnotzero }% +\def\xintiiisnotzero + #1{\if0\xintiiSgn{#1}\xint_afterfi{ 0}\else\xint_afterfi{ 1}\fi}% % \end{macrocode} -% \subsection{\csh{xintIsOne}, \csh{xintiiIsOne}} +% \subsection{\csh{xintiiIsOne}} % \lverb|Added in 1.03. 1.09a defines \xintIsOne. 1.1a adds \xintiiIsOne. % % \XINT_isOne rewritten for 1.2g. Works with expanded strict integers, @@ -21431,7 +22043,7 @@ $1$ or $-1$. % \begin{macrocode} \def\xintiiIsOne {\romannumeral0\xintiiisone }% \def\xintiiisone #1{\expandafter\XINT_isone\romannumeral`&&@#1XY}% -\def\xintIsOne {\romannumeral0\xintisone }% +\def\xintIsOne {\romannumeral0\XINT_signaldeprecated{xint}{xintIsOne}\xintisone }% \def\xintisone #1{\expandafter\XINT_isone\romannumeral0\xintnum{#1}XY}% \def\XINT_isone #1#2#3Y% {% @@ -21447,86 +22059,108 @@ $1$ or $-1$. \xint_orthat1% }% % \end{macrocode} -% \subsection{\csh{xintReverseDigits}} -% \lverb|& -% 1.2. -% -% This puts digits in reverse order, not suppressing leading zeros -% after reverse. Despite lacking the "ii" in its name, it does not apply -% \xintNum to its argument (contrarily to \xintLen, this is not very coherent). -% -% 1.2l variant is robust against non terminated \the\numexpr input. -% -% This macro is currently not used elsewhere in xint code. -% | +% \subsection{\csh{xintiiOdd}} +% \lverb|\xintOdd is needed for the xintexpr-essions even() and odd() +% functions (and also by \xintNewExpr).| % \begin{macrocode} -\def\xintReverseDigits {\romannumeral0\xintreversedigits }% -\def\xintreversedigits #1% +\def\xintiiOdd {\romannumeral0\xintiiodd }% +\def\xintiiodd #1% {% - \expandafter\XINT_revdigits\romannumeral`&&@#1% - {\XINT_microrevsep_end\W}\XINT_microrevsep_end - \XINT_microrevsep_end\XINT_microrevsep_end - \XINT_microrevsep_end\XINT_microrevsep_end - \XINT_microrevsep_end\XINT_microrevsep_end\XINT_microrevsep_end\Z - 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W + \ifodd\xintLDg{#1} %<- intentional space + \xint_afterfi{ 1}% + \else + \xint_afterfi{ 0}% + \fi }% -\def\XINT_revdigits #1% +\def\xintOdd {\romannumeral0\XINT_signaldeprecated{xint}{xintOdd}\xintodd }% +\def\xintodd #1% {% - \xint_UDsignfork - #1{\expandafter-\romannumeral0\XINT_revdigits_a}% - -{\XINT_revdigits_a #1}% - \krof + \ifodd\xintLDg{\xintNum{#1}} %<- intentional space + \xint_afterfi{ 1}% + \else + \xint_afterfi{ 0}% + \fi }% -\def\XINT_revdigits_a +% \end{macrocode} +% \subsection{\csh{xintiiEven}} +% \begin{macrocode} +\def\xintiiEven {\romannumeral0\xintiieven }% +\def\xintiieven #1% {% - \expandafter\XINT_revdigits_b\expandafter{\expandafter}% - \the\numexpr\XINT_microrevsep + \ifodd\xintLDg{#1} %<- intentional space + \xint_afterfi{ 0}% + \else + \xint_afterfi{ 1}% + \fi }% -\def\XINT_microrevsep #1#2#3#4#5#6#7#8#9% +\def\xintEven {\romannumeral0\XINT_signaldeprecated{xint}{xintEven}\xinteven }% +\def\xinteven #1% {% - 1#9#8#7#6#5#4#3#2#1\expandafter!\the\numexpr\XINT_microrevsep + \ifodd\xintLDg{\xintNum{#1}} %<- intentional space + \xint_afterfi{ 0}% + \else + \xint_afterfi{ 1}% + \fi }% -\def\XINT_microrevsep_end #1\W #2\expandafter #3\Z{\relax#2!}% -\def\XINT_revdigits_b #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!% +% \end{macrocode} +% \subsection{\csh{xintiiMON}} +% \lverb|MINUS ONE TO THE POWER N| +% \begin{macrocode} +\def\xintiiMON {\romannumeral0\xintiimon }% +\def\xintiimon #1% {% - \xint_gob_til_R #9\XINT_revdigits_end\R - \XINT_revdigits_b {#9#8#7#6#5#4#3#2#1}% + \ifodd\xintLDg {#1} %<- intentional space + \xint_afterfi{ -1}% + \else + \xint_afterfi{ 1}% + \fi +}% +\def\xintMON {\romannumeral0\XINT_signaldeprecated{xint}{xintMON}\xintmon }% +\def\xintmon #1% +{% + \ifodd\xintLDg{\xintNum{#1}} %<- intentional space + \xint_afterfi{ -1}% + \else + \xint_afterfi{ 1}% + \fi }% -\def\XINT_revdigits_end#1{% -\def\XINT_revdigits_end\R\XINT_revdigits_b ##1##2\W - {\expandafter#1\xint_gob_til_Z ##1}% -}\XINT_revdigits_end{ }% -\let\xintRev\xintReverseDigits % \end{macrocode} -% \subsection{\csh{xintLen}} -% \lverb|\xintLen is ONLY for (possibly long) integers. Gets extended to -% fractions by xintfrac.sty. It applies \xintNum to its argument. A minus sign -% is accepted and ignored. -% -% | +% \subsection{\csh{xintiiMMON}} +% \lverb|MINUS ONE TO THE POWER N-1| % \begin{macrocode} -\def\xintLen {\romannumeral0\xintlen }% -\def\xintlen #1{\def\xintlen ##1% +\def\xintiiMMON {\romannumeral0\xintiimmon }% +\def\xintiimmon #1% {% - \expandafter#1\the\numexpr - \expandafter\XINT_len_fork\romannumeral0\xintnum{##1}% - \xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint: - \xint_c_viii\xint_c_vii\xint_c_vi\xint_c_v - \xint_c_iv\xint_c_iii\xint_c_ii\xint_c_i\xint_c_\xint_bye\relax -}}\xintlen{ }% -\def\XINT_len_fork #1% + \ifodd\xintLDg {#1} %<- intentional space + \xint_afterfi{ 1}% + \else + \xint_afterfi{ -1}% + \fi +}% +\def\xintMMON {\romannumeral0\XINT_signaldeprecated{xint}{xintMMON}\xintmmon }% +\def\xintmmon #1% {% - \expandafter\XINT_length_loop\xint_UDsignfork#1{}-#1\krof + \ifodd\xintLDg{\xintNum{#1}} %<- intentional space + \xint_afterfi{ 1}% + \else + \xint_afterfi{ -1}% + \fi }% % \end{macrocode} -% \subsection{\csh{xintBool}, \csh{xintToggle}} -% \lverb|1.09c| +% \subsection{\csh{xintSgnFork}} +% \lverb|Expandable three-way fork added in 1.07. The argument #1 must expand +% to non-self-ending -1,0 or 1. 1.09i with _thenstop.| % \begin{macrocode} -\def\xintBool #1{\romannumeral`&&@% - \csname if#1\endcsname\expandafter1\else\expandafter0\fi }% -\def\xintToggle #1{\romannumeral`&&@\iftoggle{#1}{1}{0}}% +\def\xintSgnFork {\romannumeral0\xintsgnfork }% +\def\xintsgnfork #1% +{% + \ifcase #1 \expandafter\xint_secondofthree_thenstop + \or\expandafter\xint_thirdofthree_thenstop + \else\expandafter\xint_firstofthree_thenstop + \fi +}% % \end{macrocode} -% \subsection{\csh{xintifSgn}, \csh{xintiiifSgn}} +% \subsection{\csh{xintiiifSgn}} % \lverb|Expandable three-way fork added in 1.09a. Branches expandably % depending on whether <0, =0, >0. Choice of branch guaranteed in two steps. % @@ -21536,7 +22170,7 @@ $1$ or $-1$. % 1.1 adds \xintiiifSgn for optimization in xintexpr-essions. Should I move % them to xintcore? (for bnumexpr)| % \begin{macrocode} -\def\xintifSgn {\romannumeral0\xintifsgn }% +\def\xintifSgn {\romannumeral0\XINT_signaldeprecated{xint}{xintifSgn}\xintifsgn }% \def\xintifsgn #1% {% \ifcase \xintSgn{#1} @@ -21555,84 +22189,11 @@ $1$ or $-1$. \fi }% % \end{macrocode} -% \subsection{\csh{xintifZero}, \csh{xintifNotZero}, \csh{xintiiifZero}, \csh{xintiiifNotZero}} -% \lverb|Expandable two-way fork added in 1.09a. Branches expandably depending on -% whether the argument is zero (branch A) or not (branch B). 1.09i restyling. By -% the way it appears (not thoroughly tested, though) that \if tests are faster -% than \ifnum tests. 1.1 adds ii versions.| -% \begin{macrocode} -\def\xintifZero {\romannumeral0\xintifzero }% -\def\xintifzero #1% -{% - \if0\xintSgn{#1}% - \expandafter\xint_firstoftwo_thenstop - \else - \expandafter\xint_secondoftwo_thenstop - \fi -}% -\def\xintifNotZero {\romannumeral0\xintifnotzero }% -\def\xintifnotzero #1% -{% - \if0\xintSgn{#1}% - \expandafter\xint_secondoftwo_thenstop - \else - \expandafter\xint_firstoftwo_thenstop - \fi -}% -\def\xintiiifZero {\romannumeral0\xintiiifzero }% -\def\xintiiifzero #1% -{% - \if0\xintiiSgn{#1}% - \expandafter\xint_firstoftwo_thenstop - \else - \expandafter\xint_secondoftwo_thenstop - \fi -}% -\def\xintiiifNotZero {\romannumeral0\xintiiifnotzero }% -\def\xintiiifnotzero #1% -{% - \if0\xintiiSgn{#1}% - \expandafter\xint_secondoftwo_thenstop - \else - \expandafter\xint_firstoftwo_thenstop - \fi -}% -% \end{macrocode} -% \subsection{\csh{xintifOne},\csh{xintiiifOne}} -% \lverb|added in 1.09i. 1.1a adds \xintiiifOne.| -% \begin{macrocode} -\def\xintiiifOne {\romannumeral0\xintiiifone }% -\def\xintiiifone #1% -{% - \if1\xintiiIsOne{#1}% - \expandafter\xint_firstoftwo_thenstop - \else - \expandafter\xint_secondoftwo_thenstop - \fi -}% -\def\xintifOne {\romannumeral0\xintifone }% -\def\xintifone #1% -{% - \if1\xintIsOne{#1}% - \expandafter\xint_firstoftwo_thenstop - \else - \expandafter\xint_secondoftwo_thenstop - \fi -}% -% \end{macrocode} -% \subsection{\csh{xintifTrueAelseB}, \csh{xintifFalseAelseB}} -% \lverb|1.09i. 1.2i has removed deprecated \xintifTrueFalse, \xintifTrue.| -% \begin{macrocode} -\let\xintifTrueAelseB\xintifNotZero -\let\xintifFalseAelseB\xintifZero -%%\let\xintifTrue\xintifNotZero % now removed -%%\let\xintifTrueFalse\xintifNotZero % now removed -% \end{macrocode} -% \subsection{\csh{xintifCmp}, \csh{xintiiifCmp}} +% \subsection{\csh{xintiiifCmp}} % \lverb|1.09e % \xintifCmp {n}{m}{if nm}. 1.1a adds ii variant| % \begin{macrocode} -\def\xintifCmp {\romannumeral0\xintifcmp }% +\def\xintifCmp {\romannumeral0\XINT_signaldeprecated{xint}{xintifCmp}\xintifcmp }% \def\xintifcmp #1#2% {% \ifcase\xintCmp {#1}{#2} @@ -21651,10 +22212,10 @@ $1$ or $-1$. \fi }% % \end{macrocode} -% \subsection{\csh{xintifEq}, \csh{xintiiifEq}} +% \subsection{\csh{xintiiifEq}} % \lverb|1.09a \xintifEq {n}{m}{YES if n=m}{NO if n<>m}. 1.1a adds ii variant| % \begin{macrocode} -\def\xintifEq {\romannumeral0\xintifeq }% +\def\xintifEq {\romannumeral0\XINT_signaldeprecated{xint}{xintifEq}\xintifeq }% \def\xintifeq #1#2% {% \if0\xintCmp{#1}{#2}% @@ -21671,10 +22232,10 @@ $1$ or $-1$. \fi }% % \end{macrocode} -% \subsection{\csh{xintifGt}, \csh{xintiiifGt}} +% \subsection{\csh{xintiiifGt}} % \lverb|1.09a \xintifGt {n}{m}{YES if n>m}{NO if n<=m}. 1.1a adds ii variant| % \begin{macrocode} -\def\xintifGt {\romannumeral0\xintifgt }% +\def\xintifGt {\romannumeral0\XINT_signaldeprecated{xint}{xintifGt}\xintifgt }% \def\xintifgt #1#2% {% \if1\xintCmp{#1}{#2}% @@ -21682,37 +22243,107 @@ $1$ or $-1$. \else\expandafter\xint_secondoftwo_thenstop \fi }% -\def\xintiiifGt {\romannumeral0\xintiiifgt }% -\def\xintiiifgt #1#2% +\def\xintiiifGt {\romannumeral0\xintiiifgt }% +\def\xintiiifgt #1#2% +{% + \if1\xintiiCmp{#1}{#2}% + \expandafter\xint_firstoftwo_thenstop + \else\expandafter\xint_secondoftwo_thenstop + \fi +}% +% \end{macrocode} +% \subsection{\csh{xintiiifLt}} +% \lverb|1.09a \xintifLt {n}{m}{YES if n=m}. Restyled in 1.09i. +% 1.1a adds ii variant| +% \begin{macrocode} +\def\xintifLt {\romannumeral0\XINT_signaldeprecated{xint}{xintifLt}\xintiflt }% +\def\xintiflt #1#2% +{% + \ifnum\xintCmp{#1}{#2}<\xint_c_ + \expandafter\xint_firstoftwo_thenstop + \else \expandafter\xint_secondoftwo_thenstop + \fi +}% +\def\xintiiifLt {\romannumeral0\xintiiiflt }% +\def\xintiiiflt #1#2% +{% + \ifnum\xintiiCmp{#1}{#2}<\xint_c_ + \expandafter\xint_firstoftwo_thenstop + \else \expandafter\xint_secondoftwo_thenstop + \fi +}% +% \end{macrocode} +% \subsection{\csh{xintiiifZero}} +% \lverb|Expandable two-way fork added in 1.09a. Branches expandably depending on +% whether the argument is zero (branch A) or not (branch B). 1.09i restyling. By +% the way it appears (not thoroughly tested, though) that \if tests are faster +% than \ifnum tests. 1.1 adds ii versions. +% +% 1.2o deprecates \xintifZero.| +% \begin{macrocode} +\def\xintifZero {\romannumeral0\XINT_signaldeprecated{xint}{xintifZero}\xintifzero }% +\def\xintifzero #1% +{% + \if0\xintSgn{#1}% + \expandafter\xint_firstoftwo_thenstop + \else + \expandafter\xint_secondoftwo_thenstop + \fi +}% +\def\xintiiifZero {\romannumeral0\xintiiifzero }% +\def\xintiiifzero #1% +{% + \if0\xintiiSgn{#1}% + \expandafter\xint_firstoftwo_thenstop + \else + \expandafter\xint_secondoftwo_thenstop + \fi +}% +% \end{macrocode} +% \subsection{\csh{xintiiifNotZero}} +% \begin{macrocode} +\def\xintifNotZero {\romannumeral0\XINT_signaldeprecated{xint}{xintifNotZero}\xintifnotzero }% +\def\xintifnotzero #1% +{% + \if0\xintSgn{#1}% + \expandafter\xint_secondoftwo_thenstop + \else + \expandafter\xint_firstoftwo_thenstop + \fi +}% +\def\xintiiifNotZero {\romannumeral0\xintiiifnotzero }% +\def\xintiiifnotzero #1% {% - \if1\xintiiCmp{#1}{#2}% - \expandafter\xint_firstoftwo_thenstop - \else\expandafter\xint_secondoftwo_thenstop + \if0\xintiiSgn{#1}% + \expandafter\xint_secondoftwo_thenstop + \else + \expandafter\xint_firstoftwo_thenstop \fi }% % \end{macrocode} -% \subsection{\csh{xintifLt}, \csh{xintiiifLt}} -% \lverb|1.09a \xintifLt {n}{m}{YES if n=m}. Restyled in 1.09i. -% 1.1a adds ii variant| +% \subsection{\csh{xintiiifOne}} +% \lverb|added in 1.09i. 1.1a adds \xintiiifOne.| % \begin{macrocode} -\def\xintifLt {\romannumeral0\xintiflt }% -\def\xintiflt #1#2% +\def\xintiiifOne {\romannumeral0\xintiiifone }% +\def\xintiiifone #1% {% - \ifnum\xintCmp{#1}{#2}<\xint_c_ - \expandafter\xint_firstoftwo_thenstop - \else \expandafter\xint_secondoftwo_thenstop + \if1\xintiiIsOne{#1}% + \expandafter\xint_firstoftwo_thenstop + \else + \expandafter\xint_secondoftwo_thenstop \fi }% -\def\xintiiifLt {\romannumeral0\xintiiiflt }% -\def\xintiiiflt #1#2% +\def\xintifOne {\romannumeral0\XINT_signaldeprecated{xint}{xintifOne}\xintifone }% +\def\xintifone #1% {% - \ifnum\xintiiCmp{#1}{#2}<\xint_c_ - \expandafter\xint_firstoftwo_thenstop - \else \expandafter\xint_secondoftwo_thenstop + \if1\xintIsOne{#1}% + \expandafter\xint_firstoftwo_thenstop + \else + \expandafter\xint_secondoftwo_thenstop \fi }% % \end{macrocode} -% \subsection{\csh{xintifOdd}, \csh{xintiiifOdd}} +% \subsection{\csh{xintiiifOdd}} % \lverb|1.09e. Restyled in 1.09i. 1.1a adds \xintiiifOdd.| % \begin{macrocode} \def\xintiiifOdd {\romannumeral0\xintiiifodd }% @@ -21724,7 +22355,7 @@ $1$ or $-1$. \expandafter\xint_secondoftwo_thenstop \fi }% -\def\xintifOdd {\romannumeral0\xintifodd }% +\def\xintifOdd {\romannumeral0\XINT_signaldeprecated{xint}{xintifOdd}\xintifodd }% \def\xintifodd #1% {% \if\xintOdd{#1}1% @@ -21734,77 +22365,61 @@ $1$ or $-1$. \fi }% % \end{macrocode} -% \subsection{\csh{xintEq}, \csh{xintGt}, \csh{xintLt}} -% \lverb|1.09a.| -% \begin{macrocode} -\def\xintEq {\romannumeral0\xinteq }\def\xinteq #1#2{\xintifeq{#1}{#2}{1}{0}}% -\def\xintGt {\romannumeral0\xintgt }\def\xintgt #1#2{\xintifgt{#1}{#2}{1}{0}}% -\def\xintLt {\romannumeral0\xintlt }\def\xintlt #1#2{\xintiflt{#1}{#2}{1}{0}}% -% \end{macrocode} -% \subsection{\csh{xintNeq}, \csh{xintGtorEq}, \csh{xintLtorEq}} -% \lverb|1.1. Pour xintexpr. No lowercase macros| -% \begin{macrocode} -\def\xintLtorEq #1#2{\romannumeral0\xintifgt {#1}{#2}{0}{1}}% -\def\xintGtorEq #1#2{\romannumeral0\xintiflt {#1}{#2}{0}{1}}% -\def\xintNeq #1#2{\romannumeral0\xintifeq {#1}{#2}{0}{1}}% -% \end{macrocode} -% \subsection{\csh{xintiiEq}, \csh{xintiiGt}, \csh{xintiiLt}} -% \lverb|1.1a Pour \xintiiexpr. No lowercase macros.| -% \begin{macrocode} -\def\xintiiEq #1#2{\romannumeral0\xintiiifeq{#1}{#2}{1}{0}}% -\def\xintiiGt #1#2{\romannumeral0\xintiiifgt{#1}{#2}{1}{0}}% -\def\xintiiLt #1#2{\romannumeral0\xintiiiflt{#1}{#2}{1}{0}}% -% \end{macrocode} -% \subsection{\csh{xintiiNeq}, \csh{xintiiGtorEq}, \csh{xintiiLtorEq}} -% \lverb|1.1a. Pour \xintiiexpr. No lowercase macros.| +% \subsection{\csh{xintifTrueAelseB}, \csh{xintifFalseAelseB}} +% \lverb|1.09i. 1.2i has removed deprecated \xintifTrueFalse, \xintifTrue. +% +% 1.2o uses \xintiiifNotZero, see comments to \xintAND etc... This will work +% fine with arguments being nested xintfrac.sty macros, without the overhead +% of \xintNum or \xintRaw parsing.| % \begin{macrocode} -\def\xintiiLtorEq #1#2{\romannumeral0\xintiiifgt {#1}{#2}{0}{1}}% -\def\xintiiGtorEq #1#2{\romannumeral0\xintiiiflt {#1}{#2}{0}{1}}% -\def\xintiiNeq #1#2{\romannumeral0\xintiiifeq {#1}{#2}{0}{1}}% +\def\xintifTrueAelseB {\romannumeral0\xintiiifnotzero}% +\def\xintifFalseAelseB{\romannumeral0\xintiiifzero}% % \end{macrocode} -% \subsection{\csh{xintIsZero}, \csh{xintIsNotZero}, \csh{xintiiIsZero}, -% \csh{xintiiIsNotZero}} -% \lverb|1.09a. restyled in 1.09i. 1.1 adds \xintiiIsZero, etc... for -% optimization in \xintexpr| +% \subsection{\csh{xintIsTrue}, \csh{xintIsFalse}} +% \lverb|1.09c. Suppressed at 1.2o. They seem not to have been documented, fortunately.| % \begin{macrocode} -\def\xintIsZero {\romannumeral0\xintiszero }% -\def\xintiszero #1{\if0\xintSgn{#1}\xint_afterfi{ 1}\else\xint_afterfi{ 0}\fi}% -\def\xintIsNotZero {\romannumeral0\xintisnotzero }% -\def\xintisnotzero - #1{\if0\xintSgn{#1}\xint_afterfi{ 0}\else\xint_afterfi{ 1}\fi}% -\def\xintiiIsZero {\romannumeral0\xintiiiszero }% -\def\xintiiiszero #1{\if0\xintiiSgn{#1}\xint_afterfi{ 1}\else\xint_afterfi{ 0}\fi}% -\def\xintiiIsNotZero {\romannumeral0\xintiiisnotzero }% -\def\xintiiisnotzero - #1{\if0\xintiiSgn{#1}\xint_afterfi{ 0}\else\xint_afterfi{ 1}\fi}% +%\let\xintIsTrue \xintIsNotZero +%\let\xintIsFalse\xintIsZero % \end{macrocode} -% \subsection{\csh{xintIsTrue}, \csh{xintNot}, \csh{xintIsFalse}} -% \lverb|1.09c| +% \subsection{\csh{xintNOT}} +% \lverb|1.09c. But it should have been called \xintNOT, not \xintNot. Former +% denomination deprecated at 1.2o. Besides, the macro is now defined as ii-type. +% | % \begin{macrocode} -\let\xintIsTrue\xintIsNotZero -\let\xintNot\xintIsZero -\let\xintIsFalse\xintIsZero +\def\xintNot{\romannumeral0\XINT_signaldeprecated{xint}{xintNot}\xintiiiszero}% +\def\xintNOT{\romannumeral0\xintiiiszero}% % \end{macrocode} % \subsection{\csh{xintAND}, \csh{xintOR}, \csh{xintXOR}} -% \lverb|1.09a. Embarrasing bugs in \xintAND and \xintOR which inserted a space -% token corrected in 1.09i. \xintxor restyled with \if (faster) in 1.09i| +% \lverb|Added with 1.09a. But they used \xintSgn, etc... rather than +% \xintiiSgn. This brings \xintNum overhead which is not really desired, and +% which is not needed for use by xintexpr.sty. At 1.2o I modify them to use +% only ii macros. This is enough for sign or zeroness even for xintfrac +% format, as manipulated inside the \xintexpr. Big hesitation whether there +% should be however \xintiiAND outputting 1 or 0 versus an \xintAND outputting +% 1[0] versus 0[0] for example.| % \begin{macrocode} \def\xintAND {\romannumeral0\xintand }% -\def\xintand #1#2{\if0\xintSgn{#1}\expandafter\xint_firstoftwo +\def\xintand #1#2{\if0\xintiiSgn{#1}\expandafter\xint_firstoftwo \else\expandafter\xint_secondoftwo\fi - { 0}{\xintisnotzero{#2}}}% + { 0}{\xintiiisnotzero{#2}}}% \def\xintOR {\romannumeral0\xintor }% -\def\xintor #1#2{\if0\xintSgn{#1}\expandafter\xint_firstoftwo +\def\xintor #1#2{\if0\xintiiSgn{#1}\expandafter\xint_firstoftwo \else\expandafter\xint_secondoftwo\fi - {\xintisnotzero{#2}}{ 1}}% + {\xintiiisnotzero{#2}}{ 1}}% \def\xintXOR {\romannumeral0\xintxor }% -\def\xintxor #1#2{\if\xintIsZero{#1}\xintIsZero{#2}% +\def\xintxor #1#2{\if\xintiiIsZero{#1}\xintiiIsZero{#2}% \xint_afterfi{ 0}\else\xint_afterfi{ 1}\fi }% % \end{macrocode} % \subsection{\csh{xintANDof}} % \lverb|New with 1.09a. \xintANDof works also with an empty list. Empty items -% however are not accepted.| -% \lverb|1.2l made \xintANDof robust against non terminated items.| +% however are not accepted. +% +% 1.2l made \xintANDof robust against non terminated items. +% +% 1.2o's \xintifTrueAelseB is now an ii macro, actually. +% +% This macro as well as ORof and XORof are actually not used by xintexpr, +% which has its own csv handling macros.| % \begin{macrocode} \def\xintANDof {\romannumeral0\xintandof }% \def\xintandof #1{\expandafter\XINT_andof_a\romannumeral`&&@#1\xint:}% @@ -21818,8 +22433,9 @@ $1$ or $-1$. % \end{macrocode} % \subsection{\csh{xintORof}} % \lverb|New with 1.09a. Works also with an empty list. Empty items -% however are not accepted.| -% \lverb|1.2l made \xintORof robust against non terminated items.| +% however are not accepted. +% +% 1.2l made \xintORof robust against non terminated items.| % \begin{macrocode} \def\xintORof {\romannumeral0\xintorof }% \def\xintorof #1{\expandafter\XINT_orof_a\romannumeral`&&@#1\xint:}% @@ -21834,8 +22450,9 @@ $1$ or $-1$. % \subsection{\csh{xintXORof}} % \lverb|New with 1.09a. Works with an empty list, too. Empty items % however are not accepted. \XINT_xorof_c more -% efficient in 1.09i.| -% \lverb|1.2l made \xintXORof robust against non terminated items.| +% efficient in 1.09i. +% +% 1.2l made \xintXORof robust against non terminated items.| % \begin{macrocode} \def\xintXORof {\romannumeral0\xintxorof }% \def\xintxorof #1{\expandafter\XINT_xorof_a\expandafter @@ -21850,56 +22467,7 @@ $1$ or $-1$. }% \def\XINT_xorof_e #1!#2{ #2}% % \end{macrocode} -% \subsection{\csh{xintGeq}, \csh{xintiiGeq}} -% \lverb|& -% PLUS GRAND OU ÉGAL -% attention compare les **valeurs absolues** -% -% 1.2l made \xintiiGeq robust against non terminated items. -% -% 1.2l rewrote \xintiiCmp, but forgot to handle \xintiiGeq too. Done at 1.2m. -% | -% \begin{macrocode} -\def\xintGeq {\romannumeral0\xintgeq }% -\def\xintgeq #1{\expandafter\XINT_geq\romannumeral0\xintnum{#1}\xint:}% -\def\xintiiGeq {\romannumeral0\xintiigeq }% -\def\xintiigeq #1{\expandafter\XINT_iigeq\romannumeral`&&@#1\xint:}% -\def\XINT_iigeq #1#2\xint:#3% -{% - \expandafter\XINT_geq_fork\expandafter #1\romannumeral`&&@#3\xint:#2\xint: -}% -\def\XINT_geq #1#2\xint:#3% -{% - \expandafter\XINT_geq_fork\expandafter #1\romannumeral0\xintnum{#3}\xint:#2\xint: -}% -\def\XINT_geq_fork #1#2% -{% - \xint_UDzerofork - #1\XINT_geq_firstiszero - #2\XINT_geq_secondiszero - 0{}% - \krof - \xint_UDsignsfork - #1#2\XINT_geq_minusminus - #1-\XINT_geq_minusplus - #2-\XINT_geq_plusminus - --\XINT_geq_plusplus - \krof #1#2% -}% -\def\XINT_geq_firstiszero #1\krof 0#2#3\xint:#4\xint: - {\xint_UDzerofork #2{ 1}0{ 0}\krof }% -\def\XINT_geq_secondiszero #1\krof #20#3\xint:#4\xint:{ 1}% -\def\XINT_geq_plusminus #1-{\XINT_geq_plusplus #1{}}% -\def\XINT_geq_minusplus -#1{\XINT_geq_plusplus {}#1}% -\def\XINT_geq_minusminus --{\XINT_geq_plusplus {}{}}% -\def\XINT_geq_plusplus - {\expandafter\XINT_geq_finish\romannumeral0\XINT_cmp_plusplus}% -\def\XINT_geq_finish #1{\if-#1\expandafter\XINT_geq_no - \else\expandafter\XINT_geq_yes\fi}% -\def\XINT_geq_no 1{ 0}% -\def\XINT_geq_yes { 1}% -% \end{macrocode} -% \subsection{\csh{xintiMax}, \csh{xintiiMax}} +% \subsection{\csh{xintiiMax}} % \lverb|& % At 1.2m, a long-standing bug was fixed: \xintiiMax had the overhead of % applying \xintNum to its arguments due to use of a sub-macro of \xintGeq @@ -21908,7 +22476,7 @@ $1$ or $-1$. % And on this occasion I reduced even more number of times input is grabbed. % | % \begin{macrocode} -\def\xintiMax {\romannumeral0\xintimax }% +\def\xintiMax {\romannumeral0\XINT_signaldeprecated{xint}{xintiMax}\xintimax }% \def\xintimax #1% {% \expandafter\xint_max\romannumeral0\xintnum{#1}\xint: @@ -21976,41 +22544,7 @@ $1$ or $-1$. \unless\if1\romannumeral0\XINT_geq_plusplus{}{}% }% % \end{macrocode} -% \subsection{\csh{xintiMaxof}, \csh{xintiiMaxof}} -% \lverb|New with 1.09a. 1.2 has NO MORE \xintMaxof, requires \xintfracname. -% 1.2a adds \xintiiMaxof, as \xintiiMaxof:csv is not public. -% -% NOT compatible with empty list. -% -% 1.2l made \xintiiMaxof robust against non terminated items.| -% \begin{macrocode} -\def\xintiMaxof {\romannumeral0\xintimaxof }% -\def\xintimaxof #1{\expandafter\XINT_imaxof_a\romannumeral`&&@#1\xint:}% -\def\XINT_imaxof_a -#1{\expandafter\XINT_imaxof_b\romannumeral0\xintnum{#1}!}% -% \end{macrocode} -% \lverb|No \xintnum on #2 which might be \xint:, of course. But if list not -% terminated the \xintNum will be done via \xintimax.| -% \begin{macrocode} -\def\XINT_imaxof_b #1!#2% - {\expandafter\XINT_imaxof_c\romannumeral`&&@#2!{#1}!}% -\def\XINT_imaxof_c #1% - {\xint_gob_til_xint: #1\XINT_imaxof_e\xint:\XINT_imaxof_d #1}% -\def\XINT_imaxof_d #1!% - {\expandafter\XINT_imaxof_b\romannumeral0\xintimax {#1}}% -\def\XINT_imaxof_e #1!#2!{ #2}% -\def\xintiiMaxof {\romannumeral0\xintiimaxof }% -\def\xintiimaxof #1{\expandafter\XINT_iimaxof_a\romannumeral`&&@#1\xint:}% -\def\XINT_iimaxof_a #1{\expandafter\XINT_iimaxof_b\romannumeral`&&@#1!}% -\def\XINT_iimaxof_b #1!#2% - {\expandafter\XINT_iimaxof_c\romannumeral`&&@#2!{#1}!}% -\def\XINT_iimaxof_c #1% - {\xint_gob_til_xint: #1\XINT_iimaxof_e\xint:\XINT_iimaxof_d #1}% -\def\XINT_iimaxof_d #1!% - {\expandafter\XINT_iimaxof_b\romannumeral0\xintiimax {#1}}% -\def\XINT_iimaxof_e #1!#2!{ #2}% -% \end{macrocode} -% \subsection{\csh{xintiMin}, \csh{xintiiMin}} +% \subsection{\csh{xintiiMin}} % \lverb|\xintnum added New with 1.09a. I add \xintiiMin in 1.1 and mark as % deprecated \xintMin, renamed \xintiMin. \xintMin NOW REMOVED (1.2, as % \xintMax, \xintMaxof), only provided by \xintfracnameimp. @@ -22022,7 +22556,7 @@ $1$ or $-1$. % And on this occasion I reduced even more number of times input is grabbed. % | % \begin{macrocode} -\def\xintiMin {\romannumeral0\xintimin }% +\def\xintiMin {\romannumeral0\XINT_signaldeprecated{xint}{xintiMin}\xintimin }% \def\xintimin #1% {% \expandafter\xint_min\romannumeral0\xintnum{#1}\xint: @@ -22074,10 +22608,44 @@ $1$ or $-1$. \unless\if1\romannumeral0\XINT_geq_plusplus{}{}% }% % \end{macrocode} -% \subsection{\csh{xintiMinof}, \csh{xintiiMinof}} +% \subsection{\csh{xintiiMaxof}} +% \lverb|New with 1.09a. 1.2 has NO MORE \xintMaxof, requires \xintfracname. +% 1.2a adds \xintiiMaxof, as \xintiiMaxof:csv is not public. +% +% NOT compatible with empty list. +% +% 1.2l made \xintiiMaxof robust against non terminated items.| +% \begin{macrocode} +\def\xintiMaxof {\romannumeral0\XINT_signaldeprecated{xint}{xintiMaxof}\xintimaxof }% +\def\xintimaxof #1{\expandafter\XINT_imaxof_a\romannumeral`&&@#1\xint:}% +\def\XINT_imaxof_a +#1{\expandafter\XINT_imaxof_b\romannumeral0\xintnum{#1}!}% +% \end{macrocode} +% \lverb|No \xintnum on #2 which might be \xint:, of course. But if list not +% terminated the \xintNum will be done via \xintimax.| +% \begin{macrocode} +\def\XINT_imaxof_b #1!#2% + {\expandafter\XINT_imaxof_c\romannumeral`&&@#2!{#1}!}% +\def\XINT_imaxof_c #1% + {\xint_gob_til_xint: #1\XINT_imaxof_e\xint:\XINT_imaxof_d #1}% +\def\XINT_imaxof_d #1!% + {\expandafter\XINT_imaxof_b\romannumeral0\xintimax {#1}}% +\def\XINT_imaxof_e #1!#2!{ #2}% +\def\xintiiMaxof {\romannumeral0\xintiimaxof }% +\def\xintiimaxof #1{\expandafter\XINT_iimaxof_a\romannumeral`&&@#1\xint:}% +\def\XINT_iimaxof_a #1{\expandafter\XINT_iimaxof_b\romannumeral`&&@#1!}% +\def\XINT_iimaxof_b #1!#2% + {\expandafter\XINT_iimaxof_c\romannumeral`&&@#2!{#1}!}% +\def\XINT_iimaxof_c #1% + {\xint_gob_til_xint: #1\XINT_iimaxof_e\xint:\XINT_iimaxof_d #1}% +\def\XINT_iimaxof_d #1!% + {\expandafter\XINT_iimaxof_b\romannumeral0\xintiimax {#1}}% +\def\XINT_iimaxof_e #1!#2!{ #2}% +% \end{macrocode} +% \subsection{\csh{xintiiMinof}} % \lverb|1.09a. 1.2a adds \xintiiMinof which was lacking.| % \begin{macrocode} -\def\xintiMinof {\romannumeral0\xintiminof }% +\def\xintiMinof {\romannumeral0\XINT_signaldeprecated{xint}{xintiMinof}\xintiminof }% \def\xintiminof #1{\expandafter\XINT_iminof_a\romannumeral`&&@#1\xint:}% \def\XINT_iminof_a #1{\expandafter\XINT_iminof_b\romannumeral0\xintnum{#1}!}% \def\XINT_iminof_b #1!#2% @@ -22128,345 +22696,7 @@ $1$ or $-1$. {\expandafter\XINT_prod_loop_a\romannumeral0\XINT_mul_fork }% \def\XINT_prod_finished\xint:\XINT_prod_loop_c\xint:\xint:#1\xint:\Z { #1}% % \end{macrocode} -% \lverb|& -% & -% -----------------------------------------------------------------$\ -% -----------------------------------------------------------------$\ -% DECIMAL OPERATIONS: FIRST DIGIT, LASTDIGIT, (<- moved to xintcore -% because xintiiLDg needed by division macros) -% ODDNESS, -% MULTIPLICATION BY TEN, QUOTIENT BY TEN, (moved to xintcore 1.2i) -% QUOTIENT OR -% MULTIPLICATION BY POWER OF TEN, SPLIT OPERATION.| -% \subsection{\csh{xintMON}, \csh{xintMMON}, \csh{xintiiMON}, \csh{xintiiMMON}} -% \lverb|& -% MINUS ONE TO THE POWER N and (-1)^{N-1}| -% \begin{macrocode} -\def\xintiiMON {\romannumeral0\xintiimon }% -\def\xintiimon #1% -{% - \ifodd\xintiiLDg {#1} %<- intentional space - \xint_afterfi{ -1}% - \else - \xint_afterfi{ 1}% - \fi -}% -\def\xintiiMMON {\romannumeral0\xintiimmon }% -\def\xintiimmon #1% -{% - \ifodd\xintiiLDg {#1} %<- intentional space - \xint_afterfi{ 1}% - \else - \xint_afterfi{ -1}% - \fi -}% -\def\xintMON {\romannumeral0\xintmon }% -\def\xintmon #1% -{% - \ifodd\xintLDg {#1} %<- intentional space - \xint_afterfi{ -1}% - \else - \xint_afterfi{ 1}% - \fi -}% -\def\xintMMON {\romannumeral0\xintmmon }% -\def\xintmmon #1% -{% - \ifodd\xintLDg {#1} %<- intentional space - \xint_afterfi{ 1}% - \else - \xint_afterfi{ -1}% - \fi -}% -% \end{macrocode} -% \subsection{\csh{xintOdd}, \csh{xintiiOdd}, \csh{xintEven}, \csh{xintiiEven}} -% \begin{macrocode} -\def\xintiiOdd {\romannumeral0\xintiiodd }% -\def\xintiiodd #1% -{% - \ifodd\xintiiLDg{#1} %<- intentional space - \xint_afterfi{ 1}% - \else - \xint_afterfi{ 0}% - \fi -}% -\def\xintiiEven {\romannumeral0\xintiieven }% -\def\xintiieven #1% -{% - \ifodd\xintiiLDg{#1} %<- intentional space - \xint_afterfi{ 0}% - \else - \xint_afterfi{ 1}% - \fi -}% -\def\xintOdd {\romannumeral0\xintodd }% -\def\xintodd #1% -{% - \ifodd\xintLDg{#1} %<- intentional space - \xint_afterfi{ 1}% - \else - \xint_afterfi{ 0}% - \fi -}% -\def\xintEven {\romannumeral0\xinteven }% -\def\xinteven #1% -{% - \ifodd\xintLDg{#1} %<- intentional space - \xint_afterfi{ 0}% - \else - \xint_afterfi{ 1}% - \fi -}% -% \end{macrocode} -% \subsection{\csh{xintDSH}, \csh{xintDSHr}} -% \lverb!DECIMAL SHIFTS \xintDSH {x}{A}$\ -% si x <= 0, fait A -> A.10^(|x|). -% si x > 0, et A >=0, fait A -> quo(A,10^(x))$\ -% si x > 0, et A < 0, fait A -> -quo(-A,10^(x))$\ -% (donc pour x > 0 c'est comme DSR itéré x fois)$\ -% \xintDSHr donne le `reste' (si x<=0 donne zéro). -% -% Badly named macros. -% -% Rewritten for 1.2i, this was old code and \xintDSx has changed interface. -% ! -% \begin{macrocode} -\def\xintDSHr {\romannumeral0\xintdshr }% -\def\xintdshr #1#2% -{% - \expandafter\XINT_dshr_fork\the\numexpr#1\expandafter.\romannumeral`&&@#2;% -}% -\def\XINT_dshr_fork #1% -{% - \xint_UDzerominusfork - 0#1\XINT_dshr_xzeroorneg - #1-\XINT_dshr_xzeroorneg - 0-\XINT_dshr_xpositive - \krof #1% -}% -\def\XINT_dshr_xzeroorneg #1;{ 0}% -\def\XINT_dshr_xpositive -{% - \expandafter\xint_secondoftwo_thenstop\romannumeral0\XINT_dsx_xisPos -}% -\def\xintDSH {\romannumeral0\xintdsh }% -\def\xintdsh #1#2% -{% - \expandafter\XINT_dsh_fork\the\numexpr#1\expandafter.\romannumeral`&&@#2;% -}% -\def\XINT_dsh_fork #1% -{% - \xint_UDzerominusfork - #1-\XINT_dsh_xiszero - 0#1\XINT_dsx_xisNeg_checkA - 0-{\XINT_dsh_xisPos #1}% - \krof -}% -\def\XINT_dsh_xiszero #1.#2;{ #2}% -\def\XINT_dsh_xisPos -{% - \expandafter\xint_firstoftwo_thenstop\romannumeral0\XINT_dsx_xisPos -}% -% \end{macrocode} -% \subsection{\csh{xintDSx}} -% \lverb!& -% --> Attention le cas x=0 est traité dans la même catégorie que x > 0 <--$\ -% si x < 0, fait A -> A.10^(|x|)$\ -% si x >= 0, et A >=0, fait A -> {quo(A,10^(x))}{rem(A,10^(x))}$\ -% si x >= 0, et A < 0, d'abord on calcule {quo(-A,10^(x))}{rem(-A,10^(x))}$\ -% puis, si le premier n'est pas nul on lui donne le signe -$\ -% si le premier est nul on donne le signe - au second. -% -% On peut donc toujours reconstituer l'original A par 10^x Q \pm R -% où il faut prendre le signe plus si Q est positif ou nul et le signe moins si -% Q est strictement négatif. -% -% Rewritten for 1.2i, this was old code. -% -% ! -% \begin{macrocode} -\def\xintDSx {\romannumeral0\xintdsx }% -\def\xintdsx #1#2% -{% - \expandafter\XINT_dsx_fork\the\numexpr#1\expandafter.\romannumeral`&&@#2;% -}% -\def\XINT_dsx_fork #1% -{% - \xint_UDzerominusfork - #1-\XINT_dsx_xisZero - 0#1\XINT_dsx_xisNeg_checkA - 0-{\XINT_dsx_xisPos #1}% - \krof -}% -\def\XINT_dsx_xisZero #1.#2;{{#2}{0}}% -\def\XINT_dsx_xisNeg_checkA #1.#2% -{% - \xint_gob_til_zero #2\XINT_dsx_xisNeg_Azero 0% - \expandafter\XINT_dsx_append\romannumeral\XINT_rep #1\endcsname 0.#2% -}% -\def\XINT_dsx_xisNeg_Azero #1;{ 0}% -\def\XINT_dsx_addzeros #1% - {\expandafter\XINT_dsx_append\romannumeral\XINT_rep#1\endcsname0.}% -\def\XINT_dsx_addzerosnofuss #1% - {\expandafter\XINT_dsx_append\romannumeral\xintreplicate{#1}0.}% -\def\XINT_dsx_append #1.#2;{ #2#1}% -\def\XINT_dsx_xisPos #1.#2% -{% - \xint_UDzerominusfork - #2-\XINT_dsx_AisZero - 0#2\XINT_dsx_AisNeg - 0-\XINT_dsx_AisPos - \krof #1.#2% -}% -\def\XINT_dsx_AisZero #1;{{0}{0}}% -\def\XINT_dsx_AisNeg #1.-#2;% -{% - \expandafter\XINT_dsx_AisNeg_checkiffirstempty - \romannumeral0\XINT_split_xfork #1.#2\xint_bye2345678\xint_bye..% -}% -\def\XINT_dsx_AisNeg_checkiffirstempty #1% -{% - \xint_gob_til_dot #1\XINT_dsx_AisNeg_finish_zero.% - \XINT_dsx_AisNeg_finish_notzero #1% -}% -\def\XINT_dsx_AisNeg_finish_zero.\XINT_dsx_AisNeg_finish_notzero.#1.% -{% - \expandafter\XINT_dsx_end - \expandafter {\romannumeral0\XINT_num {-#1}}{0}% -}% -\def\XINT_dsx_AisNeg_finish_notzero #1.#2.% -{% - \expandafter\XINT_dsx_end - \expandafter {\romannumeral0\XINT_num {#2}}{-#1}% -}% -\def\XINT_dsx_AisPos #1.#2;% -{% - \expandafter\XINT_dsx_AisPos_finish - \romannumeral0\XINT_split_xfork #1.#2\xint_bye2345678\xint_bye..% -}% -\def\XINT_dsx_AisPos_finish #1.#2.% -{% - \expandafter\XINT_dsx_end - \expandafter {\romannumeral0\XINT_num {#2}}% - {\romannumeral0\XINT_num {#1}}% -}% -\def\XINT_dsx_end #1#2{\expandafter{#2}{#1}}% -% \end{macrocode} -% \subsection{\csh{xintDecSplit}, \csh{xintDecSplitL}, \csh{xintDecSplitR}} -% \lverb!DECIMAL SPLIT -% -% The macro \xintDecSplit {x}{A} cuts A which is composed of digits (leading -% zeroes ok, but no sign) (*) into two (each possibly empty) pieces L and R. -% The concatenation LR always reproduces A. -% -% The position of the cut is specified by the first argument x. If x is zero -% or positive the cut location is x slots to the left of the right end of the -% number. If x becomes equal to or larger than the length of the number then L -% becomes empty. If x is negative the location of the cut is |x| slots to the -% right of the left end of the number. -% -% (*) versions earlier than 1.2i first replaced A with its absolute value. -% This is not the case anymore. This macro should NOT be used for A with a -% leading sign (+ or -). -% -% Entirely rewritten for 1.2i (2016/12/11). -% -% Attention: \xintDecSplit not robust against non terminated second argument. -% ! -% \begin{macrocode} -\def\xintDecSplit {\romannumeral0\xintdecsplit }% -\def\xintdecsplit #1#2% -{% - \expandafter\XINT_split_finish - \romannumeral0\expandafter\XINT_split_xfork - \the\numexpr #1\expandafter.\romannumeral`&&@#2% - \xint_bye2345678\xint_bye..% -}% -\def\xintDecSplitL {\romannumeral0\xintdecsplitl }% -\def\xintdecsplitl #1#2% -{% - \expandafter\XINT_splitl_finish - \romannumeral0\expandafter\XINT_split_xfork - \the\numexpr #1\expandafter.\romannumeral`&&@#2% - \xint_bye2345678\xint_bye..% -}% -\def\xintDecSplitR {\romannumeral0\xintdecsplitr }% -\def\xintdecsplitr #1#2% -{% - \expandafter\XINT_splitr_finish - \romannumeral0\expandafter\XINT_split_xfork - \the\numexpr #1\expandafter.\romannumeral`&&@#2% - \xint_bye2345678\xint_bye..% -}% -\def\XINT_split_finish #1.#2.{{#1}{#2}}% -\def\XINT_splitl_finish #1.#2.{ #1}% -\def\XINT_splitr_finish #1.#2.{ #2}% -\def\XINT_split_xfork #1% -{% - \xint_UDzerominusfork - #1-\XINT_split_zerosplit - 0#1\XINT_split_fromleft - 0-{\XINT_split_fromright #1}% - \krof -}% -\def\XINT_split_zerosplit .#1\xint_bye#2\xint_bye..{ #1..}% -\def\XINT_split_fromleft - {\expandafter\XINT_split_fromleft_a\the\numexpr\xint_c_viii-}% -\def\XINT_split_fromleft_a #1% -{% - \xint_UDsignfork - #1\XINT_split_fromleft_b - -{\XINT_split_fromleft_end_a #1}% - \krof -}% -\def\XINT_split_fromleft_b #1.#2#3#4#5#6#7#8#9% -{% - \expandafter\XINT_split_fromleft_clean - \the\numexpr1#2#3#4#5#6#7#8#9\expandafter - \XINT_split_fromleft_a\the\numexpr\xint_c_viii-#1.% -}% -\def\XINT_split_fromleft_end_a #1.% -{% - \expandafter\XINT_split_fromleft_clean - \the\numexpr1\csname XINT_split_fromleft_end#1\endcsname -}% -\def\XINT_split_fromleft_clean 1{ }% -\expandafter\def\csname XINT_split_fromleft_end7\endcsname #1% - {#1\XINT_split_fromleft_end_b}% -\expandafter\def\csname XINT_split_fromleft_end6\endcsname #1#2% - {#1#2\XINT_split_fromleft_end_b}% -\expandafter\def\csname XINT_split_fromleft_end5\endcsname #1#2#3% - {#1#2#3\XINT_split_fromleft_end_b}% -\expandafter\def\csname XINT_split_fromleft_end4\endcsname #1#2#3#4% - {#1#2#3#4\XINT_split_fromleft_end_b}% -\expandafter\def\csname XINT_split_fromleft_end3\endcsname #1#2#3#4#5% - {#1#2#3#4#5\XINT_split_fromleft_end_b}% -\expandafter\def\csname XINT_split_fromleft_end2\endcsname #1#2#3#4#5#6% - {#1#2#3#4#5#6\XINT_split_fromleft_end_b}% -\expandafter\def\csname XINT_split_fromleft_end1\endcsname #1#2#3#4#5#6#7% - {#1#2#3#4#5#6#7\XINT_split_fromleft_end_b}% -\expandafter\def\csname XINT_split_fromleft_end0\endcsname #1#2#3#4#5#6#7#8% - {#1#2#3#4#5#6#7#8\XINT_split_fromleft_end_b}% -\def\XINT_split_fromleft_end_b #1\xint_bye#2\xint_bye.{.#1}% puis . -\def\XINT_split_fromright #1.#2\xint_bye -{% - \expandafter\XINT_split_fromright_a - \the\numexpr#1-\numexpr\XINT_length_loop - #2\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint: - \xint_c_viii\xint_c_vii\xint_c_vi\xint_c_v - \xint_c_iv\xint_c_iii\xint_c_ii\xint_c_i\xint_c_\xint_bye - .#2\xint_bye -}% -\def\XINT_split_fromright_a #1% -{% - \xint_UDsignfork - #1\XINT_split_fromleft - -\XINT_split_fromright_Lempty - \krof -}% -\def\XINT_split_fromright_Lempty #1.#2\xint_bye#3..{.#2.}% -% \end{macrocode} -% \subsection{\csh{xintiiSqrt}, \csh{xintiiSqrtR}, \csh{xintiiSquareRoot}} +% \subsection{\csh{xintiiSquareRoot}} % \lverb|First done with 1.08. % % 1.1 added \xintiiSquareRoot. @@ -22505,24 +22735,8 @@ $1$ or $-1$. % | % % \begin{macrocode} -\def\xintiiSqrt {\romannumeral0\xintiisqrt }% -\def\xintiiSqrtR {\romannumeral0\xintiisqrtr }% \def\xintiiSquareRoot {\romannumeral0\xintiisquareroot }% -\def\xintiSqrt {\romannumeral0\xintisqrt }% -\def\xintiSqrtR {\romannumeral0\xintisqrtr }% -\def\xintiSquareRoot {\romannumeral0\xintisquareroot }% -\def\xintisqrt {\expandafter\XINT_sqrt_post\romannumeral0\xintisquareroot }% -\def\xintisqrtr {\expandafter\XINT_sqrtr_post\romannumeral0\xintisquareroot }% -\def\xintiisqrt {\expandafter\XINT_sqrt_post\romannumeral0\xintiisquareroot }% -\def\xintiisqrtr {\expandafter\XINT_sqrtr_post\romannumeral0\xintiisquareroot }% -\def\XINT_sqrt_post #1#2{\XINT_dec #1\XINT_dec_bye234567890\xint_bye}% -% \end{macrocode} -% \lverb|N = (#1)^2 - #2 avec #1 le plus petit possible et #2>0 (hence #2<2*#1). -% (#1-.5)^2=#1^2-#1+.25=N+#2-#1+.25. Si 0<#2<#1, <= N-0.75#1 -% si #2>=#1, (#1-.5)^2>=N+.25>N, donc rounded->#1-1.| -% \begin{macrocode} -\def\XINT_sqrtr_post #1#2{\xintiiifLt {#2}{#1}% - { #1}{\XINT_dec #1\XINT_dec_bye234567890\xint_bye}}% +\def\xintiSquareRoot{\romannumeral0\XINT_signaldeprecated{xint}{xintiSquareRoot}\xintisquareroot}% \def\xintisquareroot #1% {\expandafter\XINT_sqrt_checkin\romannumeral0\xintnum{#1}\xint:}% \def\xintiisquareroot #1{\expandafter\XINT_sqrt_checkin\romannumeral`&&@#1\xint:}% @@ -22557,14 +22771,26 @@ $1$ or $-1$. \fi #1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_bE #1.#2#3#4% {% \XINT_sqrt_c {#3#4}#2{#1}#3#4% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_bO #1.#2#3% {% \XINT_sqrt_c #3#2{#1}#3% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_c #1#2% {% \expandafter #2% @@ -22576,16 +22802,28 @@ $1$ or $-1$. 10\else 9\fi \else 8\fi \else 7\fi \else 6\fi \else 5\fi \else 4\fi \else 3\fi \else 2\fi \else 1\fi .% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_small_d #1.#2% {% \expandafter\XINT_sqrt_small_e \the\numexpr #1\ifcase \numexpr #2/\xint_c_ii-\xint_c_i\relax \or 0\or 00\or 000\or 0000\fi .% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_small_e #1.#2.% {% \expandafter\XINT_sqrt_small_ea\the\numexpr #1*#1-#2.#1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_small_ea #1% {% \if0#1\xint_dothis\XINT_sqrt_small_ez\fi @@ -22594,21 +22832,37 @@ $1$ or $-1$. }% \def\XINT_sqrt_small_ez 0.#1.{\expandafter{\the\numexpr#1+\xint_c_i \expandafter}\expandafter{\the\numexpr #1*\xint_c_ii+\xint_c_i}}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_small_eb -#1.#2.% {% \expandafter\XINT_sqrt_small_ec \the\numexpr (#1-\xint_c_i+#2)/(\xint_c_ii*#2).#1.#2.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_small_ec #1.#2.#3.% {% \expandafter\XINT_sqrt_small_f \the\numexpr -#2+\xint_c_ii*#3*#1+#1*#1\expandafter.\the\numexpr #3+#1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_small_f #1.#2.% {% \expandafter\XINT_sqrt_small_g \the\numexpr (#1+#2)/(\xint_c_ii*#2)-\xint_c_i.#1.#2.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_small_g #1#2.% {% \if 0#1% @@ -22618,6 +22872,10 @@ $1$ or $-1$. \fi #1#2.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_small_h #1.#2.#3.% {% \expandafter\XINT_sqrt_small_f @@ -22625,21 +22883,41 @@ $1$ or $-1$. \the\numexpr #3-#1.% }% \def\XINT_sqrt_small_end #1.#2.#3.{{#3}{#2}}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_d #1.#2% {% \ifodd #2 \xint_dothis{\expandafter\XINT_sqrt_big_eO}\fi \xint_orthat{\expandafter\XINT_sqrt_big_eE}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \the\numexpr (#2-\xint_c_i)/\xint_c_ii.#1;% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_eE #1;#2#3#4#5#6#7#8#9% {% \XINT_sqrt_big_eE_a #1;{#2#3#4#5#6#7#8#9}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_eE_a #1.#2;#3% {% \expandafter\XINT_sqrt_bigormed_f \romannumeral0\XINT_sqrt_small_e #2000.#3.#1;% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_eO #1;#2#3#4#5#6#7#8#9% {% \XINT_sqrt_big_eO_a #1;{#2#3#4#5#6#7#8#9}% @@ -22649,6 +22927,10 @@ $1$ or $-1$. \expandafter\XINT_sqrt_bigormed_f \romannumeral0\XINT_sqrt_small_e #20000.#3#4.#1;% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_bigormed_f #1#2#3;% {% \ifnum#3<\xint_c_ix @@ -22660,28 +22942,48 @@ $1$ or $-1$. \def\XINT_sqrt_med_fvi {\XINT_sqrt_med_fa 0.}% \def\XINT_sqrt_med_fvii {\XINT_sqrt_med_fa 00.}% \def\XINT_sqrt_med_fviii{\XINT_sqrt_med_fa 000.}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_med_fa #1.#2.#3.#4;% {% \expandafter\XINT_sqrt_med_fb \the\numexpr (#30#1-5#1)/(\xint_c_ii*#2).#1.#2.#3.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_med_fb #1.#2.#3.#4.#5.% {% \expandafter\XINT_sqrt_small_ea \the\numexpr (#40#2-\xint_c_ii*#3*#1)*10#2+(#1*#1-#5)\expandafter.% \the\numexpr #30#2-#1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_f #1;#2#3#4#5#6#7#8#9% {% \XINT_sqrt_big_fa #1;{#2#3#4#5#6#7#8#9}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_fa #1.#2.#3;#4% {% \expandafter\XINT_sqrt_big_ga \the\numexpr #3-\xint_c_viii\expandafter.% \romannumeral0\XINT_sqrt_med_fa 000.#1.#2.;#4.% }% +% \end{macrocode} +% \lverb|& % +% | +% \begin{macrocode} \def\XINT_sqrt_big_ga #1.#2#3% {% \ifnum #1>\xint_c_viii @@ -22689,12 +22991,20 @@ $1$ or $-1$. \expandafter\XINT_sqrt_big_ka \fi #1.#3.#2.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_gb #1.#2.#3.% {% \expandafter\XINT_sqrt_big_gc \the\numexpr (\xint_c_ii*#2-\xint_c_i)*\xint_c_x^viii/(\xint_c_iv*#3).% #3.#2.#1;% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_gc #1.#2.#3.% {% \expandafter\XINT_sqrt_big_gd @@ -22703,14 +23013,26 @@ $1$ or $-1$. {\xintiiSqr {#1}}.% \romannumeral0\xintiisub{#200000000}{#1}.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_gd #1.#2.% {% \expandafter\XINT_sqrt_big_ge #2.#1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_ge #1;#2#3#4#5#6#7#8#9% {\XINT_sqrt_big_gf #1.#2#3#4#5#6#7#8#9;}% \def\XINT_sqrt_big_gf #1;#2#3#4#5#6#7#8#9% {\XINT_sqrt_big_gg #1#2#3#4#5#6#7#8#9.}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_gg #1.#2.#3.#4.% {% \expandafter\XINT_sqrt_big_gloop @@ -22718,15 +23040,27 @@ $1$ or $-1$. \the\numexpr #3-\xint_c_viii\expandafter.% \romannumeral0\xintiisub {#2}{\xintiNum{#4}}.#1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_gloop #1.#2.% {% \unless\ifnum #1<#2 \xint_dothis\XINT_sqrt_big_ka \fi \xint_orthat{\XINT_sqrt_big_gi #1.}#2.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_gi #1.% {% \expandafter\XINT_sqrt_big_gj\romannumeral\xintreplicate{#1}0.#1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_gj #1.#2.#3.#4.#5.% {% \expandafter\XINT_sqrt_big_gk @@ -22734,22 +23068,42 @@ $1$ or $-1$. {\XINT_dbl #5\xint_bye2345678\xint_bye*\xint_c_ii\relax}.% #1.#5.#2.#3.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_gk #1#2.#3.#4.% {% \expandafter\XINT_sqrt_big_gl \romannumeral0\xintiiadd {#2#3}{\xintiiSqr{#1}}.% \romannumeral0\xintiisub {#4#3}{#1}.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_gl #1.#2.% {% \expandafter\XINT_sqrt_big_gm #2.#1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_gm #1.#2.#3.#4.#5.% {% \expandafter\XINT_sqrt_big_gn +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \romannumeral0\XINT_split_fromleft\xint_c_ii*#3.#5\xint_bye2345678\xint_bye..% #1.#2.#3.#4.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_gn #1.#2.#3.#4.#5.#6.% {% \expandafter\XINT_sqrt_big_gloop @@ -22757,9 +23111,17 @@ $1$ or $-1$. \the\numexpr #6-#5\expandafter.% \romannumeral0\xintiisub{#4}{\xintiNum{#1}}.#3.#2.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_ka #1.#2.#3.#4.% {% \expandafter\XINT_sqrt_big_kb +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \romannumeral0\XINT_dsx_addzeros {#1}#3;.% \romannumeral0\xintiisub {\XINT_dsx_addzerosnofuss {\xint_c_ii*#1}#2;}% @@ -22769,6 +23131,10 @@ $1$ or $-1$. {% \expandafter\XINT_sqrt_big_kc #2.#1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_kc #1% {% \if0#1\xint_dothis\XINT_sqrt_big_kz\fi @@ -22784,12 +23150,20 @@ $1$ or $-1$. {% \expandafter{\romannumeral0\xintinc{#2}}{#1}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_kloop #1.#2.% {% \expandafter\XINT_sqrt_big_ke \romannumeral0\xintiidivision{#1}% {\romannumeral0\XINT_dbl #2\xint_bye2345678\xint_bye*\xint_c_ii\relax}{#2}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_ke #1% {% \if0\XINT_Sgn #1\xint: @@ -22797,6 +23171,10 @@ $1$ or $-1$. \else \expandafter \XINT_sqrt_big_kf \fi {#1}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_kf #1#2#3% {% \expandafter\XINT_sqrt_big_kg @@ -22807,9 +23185,32 @@ $1$ or $-1$. {% \expandafter\XINT_sqrt_big_kloop #2.#1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_sqrt_big_end #1#2#3{{#3}{#2}}% % \end{macrocode} -% \subsection{\csh{xintiiBinomial}, \csh{xintiBinomial}} +% \subsection{\csh{xintiiSqrt}, \csh{xintiiSqrtR}} +% \begin{macrocode} +\def\xintiiSqrt {\romannumeral0\xintiisqrt }% +\def\xintiisqrt {\expandafter\XINT_sqrt_post\romannumeral0\xintiisquareroot }% +\def\XINT_sqrt_post #1#2{\XINT_dec #1\XINT_dec_bye234567890\xint_bye}% +\def\xintiiSqrtR {\romannumeral0\xintiisqrtr }% +\def\xintiisqrtr {\expandafter\XINT_sqrtr_post\romannumeral0\xintiisquareroot }% +% \end{macrocode} +% \lverb|N = (#1)^2 - #2 avec #1 le plus petit possible et #2>0 (hence #2<2*#1). +% (#1-.5)^2=#1^2-#1+.25=N+#2-#1+.25. Si 0<#2<#1, <= N-0.75#1 +% si #2>=#1, (#1-.5)^2>=N+.25>N, donc rounded->#1-1.| +% \begin{macrocode} +\def\XINT_sqrtr_post #1#2% + {\xintiiifLt {#2}{#1}{ #1}{\XINT_dec #1\XINT_dec_bye234567890\xint_bye}}% +\def\xintiSqrt {\romannumeral0\XINT_signaldeprecated{xint}{xintiSqrt}\xintisqrt}% +\def\xintisqrt {\expandafter\XINT_sqrt_post\romannumeral0\xintisquareroot }% +\def\xintiSqrtR{\romannumeral0\XINT_signaldeprecated{xint}{xintiSqrtr}\xintisqrtr}% +\def\xintisqrtr {\expandafter\XINT_sqrtr_post\romannumeral0\xintisquareroot }% +% \end{macrocode} +% \subsection{\csh{xintiiBinomial}} % \lverb|2015/11/28-29 for 1.2f. % % 2016/11/19 for 1.2h: I truly can't understand why I hard-coded last @@ -22817,7 +23218,11 @@ $1$ or $-1$. % formula. Naturally there should be no error but a rather a 0 return % value for binomial(x,y), if y<0 or x\xint_c_ \xint_dothis{#1!}\fi\xint_orthat{}}% + {\expandafter\XINT_dthb_again + \the\numexpr + \ifnum #1>\xint_c_ + \xint_afterfi{\expandafter\XINT_dthb_update\the\numexpr#1}% + \fi}% {\ifnum #1>\xint_c_ \xint_dothis{#2#1!}\fi\xint_orthat{!#2!}}% }% \def\XINT_tofourhex #1!% @@ -24086,7 +24499,7 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintgcd}% - [2017/08/06 1.2n Euclide algorithm with xint package (JFB)]% + [2017/08/29 1.2o Euclide algorithm with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintGCD}, \csh{xintiiGCD}} % \begin{macrocode} @@ -24753,7 +25166,36 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintfrac}% - [2017/08/06 1.2n Expandable operations on fractions (JFB)]% + [2017/08/29 1.2o Expandable operations on fractions (JFB)]% +% \end{macrocode} +% \subsection{Macros now deprecated in \xintcorenameimp or \xintnameimp} +% \lverb|1.2o| +% \begin{macrocode} +\def\xintSgn {\romannumeral0\xintsgn }% deprecated from xintcore +\def\xintCmp {\romannumeral0\xintcmp }% deprecated from xintcore +\def\xintEq {\romannumeral0\xinteq }% deprecated from xint +\def\xintNeq #1#2% renamed into \xintNotEq + {\romannumeral0\XINT_signaldeprecated{xintfrac}{xintNeq}\xintifeq {#1}{#2}{0}{1}}% +\def\xintNotEq #1#2{\romannumeral0\xintifeq {#1}{#2}{0}{1}}% +%\def\xintGeq {\romannumeral0\xintgeq }% further down +\def\xintGt {\romannumeral0\xintgt }% +\def\xintLt {\romannumeral0\xintlt }% +\def\xintGtorEq #1#2{\romannumeral0\xintiflt {#1}{#2}{0}{1}}% +\def\xintLtorEq #1#2{\romannumeral0\xintifgt {#1}{#2}{0}{1}}% +\def\xintIsZero {\romannumeral0\xintiszero }% +\def\xintIsNotZero{\romannumeral0\xintisnotzero }% +\def\xintIsOne {\romannumeral0\xintisone }% +\def\xintOdd {\romannumeral0\xintodd }% +\def\xintEven {\romannumeral0\xinteven }% +\def\xintifSgn{\romannumeral0\xintifsgn }% +\def\xintifCmp{\romannumeral0\xintifcmp }% +\def\xintifEq {\romannumeral0\xintifeq }% +\def\xintifGt {\romannumeral0\xintifgt }% +\def\xintifLt {\romannumeral0\xintiflt }% +\def\xintifZero {\romannumeral0\xintifzero }% +\def\xintifNotZero{\romannumeral0\xintifnotzero }% +\def\xintifOne {\romannumeral0\xintifone }% +\def\xintifOdd {\romannumeral0\xintifodd }% % \end{macrocode} % \subsection{\csh{XINT_cntSgnFork}} % \lverb|1.09i. Used internally, #1 must expand to \m@ne, \z@, or \@ne or @@ -24781,6 +25223,10 @@ $1$ or $-1$. \def\XINT_flen#1{\def\XINT_flen ##1##2##3% {% \expandafter#1% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \the\numexpr \XINT_abs##1+% \XINT_len_fork ##2##3\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint: \xint_c_viii\xint_c_vii\xint_c_vi\xint_c_v @@ -25015,10 +25461,18 @@ $1$ or $-1$. \def\XINT_frac_gen_Cc #1.#2~#3!#4e#5e#6\XINT_T {% \expandafter\XINT_frac_gen_F\the\numexpr #5-#2-% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \numexpr\XINT_length_loop #1\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint: \xint_c_viii\xint_c_vii\xint_c_vi\xint_c_v \xint_c_iv\xint_c_iii\xint_c_ii\xint_c_i\xint_c_\xint_bye +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \relax\expandafter~% \romannumeral0\expandafter\XINT_num_cleanup\the\numexpr\XINT_num_loop #3\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\Z @@ -25199,6 +25653,10 @@ $1$ or $-1$. {% \expandafter\XINT_rawz_fork\romannumeral0\XINT_infrac }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_rawz_fork #1% {% \ifnum#1<\xint_c_ @@ -25263,6 +25721,10 @@ $1$ or $-1$. }% \def\XINT_denom_fork #1% {% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \ifnum#1<\xint_c_ \expandafter\XINT_denom_B \else @@ -25640,8 +26102,16 @@ $1$ or $-1$. \xint_orthat\XINT_trunc_b #1+#4.{#2}{#3}#5#4.% }% \def\XINT_trunc_zero #1.#2.{ 0}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_trunc_b {\expandafter\XINT_trunc_B\the\numexpr}% \def\XINT_trunc_sp_b {\expandafter\XINT_trunc_sp_B\the\numexpr}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_trunc_B #1% {% \xint_UDsignfork @@ -25649,6 +26119,10 @@ $1$ or $-1$. -\XINT_trunc_D \krof #1% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_trunc_sp_B #1% {% \xint_UDsignfork @@ -25656,12 +26130,20 @@ $1$ or $-1$. -\XINT_trunc_sp_D \krof #1% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_trunc_C -#1.#2#3% {% \expandafter\XINT_trunc_CE \romannumeral0\XINT_dsx_addzeros{#1}#3;.{#2}% }% \def\XINT_trunc_CE #1.#2{\XINT_trunc_E #2.{#1}}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_trunc_sp_C -#1.#2#3{\XINT_trunc_sp_Ca #2.#1.}% \def\XINT_trunc_sp_Ca #1% {% @@ -25673,6 +26155,10 @@ $1$ or $-1$. \def\XINT_trunc_sp_Cb #1#2.#3.% {% \expandafter\XINT_trunc_sp_Cc +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \romannumeral0\expandafter\XINT_split_fromright_a \the\numexpr#3-\numexpr\XINT_length_loop #2\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint:\xint: @@ -25680,6 +26166,10 @@ $1$ or $-1$. \xint_c_iv\xint_c_iii\xint_c_ii\xint_c_i\xint_c_\xint_bye .#2\xint_bye2345678\xint_bye..#1% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_trunc_sp_Cc #1% {% \if.#1\xint_dothis{\XINT_trunc_sp_Cd 0.}\fi @@ -25736,6 +26226,10 @@ $1$ or $-1$. \def\XINT_trunc_Hb #1#2#3% {% \expandafter #3\expandafter0\expandafter.% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \romannumeral\xintreplicate{#1}0#2% }% % \end{macrocode} @@ -25749,7 +26243,6 @@ $1$ or $-1$. % \end{macrocode} % \subsection{\csh{xintNum}} % \begin{macrocode} -\let\xintNum \xintTTrunc \let\xintnum \xintttrunc % \end{macrocode} % \subsection{\csh{xintRound}, \csh{xintiRound}} @@ -25805,7 +26298,15 @@ $1$ or $-1$. {% \expandafter\XINT_xtrunc_b\the\numexpr\ifnum#1<\xint_c_i \xint_c_i-\fi #1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_b #1.#2{\XINT_xtrunc_c #2{#1}}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_c #1% {% \xint_UDzerominusfork @@ -25815,6 +26316,10 @@ $1$ or $-1$. \krof }%[ \def\XINT_xtrunc_zero #1#2]{0.\romannumeral\xintreplicate{#1}0}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_d #1#2#3/#4[#5]% {% \XINT_xtrunc_prepare_a#4\R\R\R\R\R\R\R\R {10}0000001\W @@ -25838,6 +26343,10 @@ $1$ or $-1$. \or\expandafter\XINT_xtrunc_BisEight \fi\XINT_xtrunc_BisSmall {#2}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_BisOne\XINT_xtrunc_BisSmall #1#2#3#4% {\XINT_xtrunc_sp_e {#2}{#4}{#3}}% \def\XINT_xtrunc_BisTwo\XINT_xtrunc_BisSmall #1#2#3#4% @@ -25871,6 +26380,10 @@ $1$ or $-1$. \the\numexpr #1/\xint_c_ii\expandafter .\the\numexpr \xint_c_x^viii+#1!}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_small_a #1.#2!#3% {% \expandafter\XINT_div_small_b\the\numexpr #1\expandafter @@ -25878,6 +26391,10 @@ $1$ or $-1$. \romannumeral0\XINT_div_small_ba #3\R\R\R\R\R\R\R\R{10}0000001\W #3\XINT_sepbyviii_Z_end 2345678\relax }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_prepare_b {\expandafter\XINT_xtrunc_prepare_c\romannumeral0\XINT_zeroes_forviii }% \def\XINT_xtrunc_prepare_c #1!% @@ -25907,7 +26424,15 @@ $1$ or $-1$. \R\xint:\xint_c_iv \R\xint:\xint_c_ii \R\xint:\xint_c_\W \X }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_prepare_g #1;{\XINT_xtrunc_e {#1}}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_e #1#2% {% \ifnum #2<\xint_c_ @@ -25916,14 +26441,26 @@ $1$ or $-1$. \expandafter\XINT_xtrunc_II \fi #2\xint:{#1}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_I -#1\xint:#2#3#4% {% \expandafter\XINT_xtrunc_I_a\romannumeral0#2{#4}{#2}{#1}{#3}% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_I_a #1#2#3#4#5% {% \expandafter\XINT_xtrunc_I_b\the\numexpr #4-#5\xint:#4\xint:{#5}{#2}{#3}{#1}% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_I_b #1% {% \xint_UDsignfork @@ -25931,6 +26468,10 @@ $1$ or $-1$. -\XINT_xtrunc_IB_c \krof #1% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_IA_c -#1\xint:#2\xint:#3#4#5#6% {% \expandafter\XINT_xtrunc_IA_d @@ -25938,6 +26479,10 @@ $1$ or $-1$. \expandafter\XINT_xtrunc_IA_xd \the\numexpr (#1+\xint_c_ii^v)/\xint_c_ii^vi-\xint_c_i\xint:#1\xint:{#5}{#4}% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_IA_d #1% {% \xint_UDsignfork @@ -25945,32 +26490,60 @@ $1$ or $-1$. -\XINT_xtrunc_IAB_e \krof #1% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_IAA_e -#1\xint:#2% {% \romannumeral0\XINT_split_fromleft #1.#2\xint_gobble_i\xint_bye2345678\xint_bye..% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_IAB_e #1\xint:#2% {% 0.\romannumeral\XINT_rep#1\endcsname0#2% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_IA_xd #1\xint:#2\xint:% {% \expandafter\XINT_xtrunc_IA_xe\the\numexpr #2-\xint_c_ii^vi*#1\xint:#1\xint:% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_IA_xe #1\xint:#2\xint:#3#4% {% \XINT_xtrunc_loop {#2}{#4}{#3}{#1}% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_IB_c #1\xint:#2\xint:#3#4#5#6% {% \expandafter\XINT_xtrunc_IB_d \romannumeral0\XINT_split_xfork #1.#6\xint_bye2345678\xint_bye..{#3}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_IB_d #1.#2.#3% {% \expandafter\XINT_xtrunc_IA_d\the\numexpr#3-\xintLength {#1}\xint:{#1}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_II #1\xint:% {% \expandafter\XINT_xtrunc_II_a\romannumeral\xintreplicate{#1}0\xint:% @@ -25985,10 +26558,18 @@ $1$ or $-1$. {% \expandafter\XINT_xtrunc_II_c\the\numexpr #2-\xint_c_ii^vi*#1\xint:#1\xint:% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_II_c #1\xint:#2\xint:#3#4#5% {% #3.\XINT_xtrunc_loop {#2}{#4}{#5}{#1}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_loop #1% {% \ifnum #1=\xint_c_ \expandafter\XINT_xtrunc_transition\fi @@ -26005,6 +26586,10 @@ $1$ or $-1$. \romannumeral\xintreplicate{\xint_c_ii^vi-\xintLength{#1}}0#1% \XINT_xtrunc_loop {#3}{#2}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_transition \expandafter\XINT_xtrunc_loop_a\the\numexpr #1\xint:#2#3#4% {% @@ -26020,6 +26605,10 @@ $1$ or $-1$. {% \romannumeral\xintreplicate{#3-\xintLength{#1}}0#1% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_sp_e #1% {% \ifnum #1<\xint_c_ @@ -26028,10 +26617,18 @@ $1$ or $-1$. \expandafter\XINT_xtrunc_sp_II \fi #1\xint:% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_sp_I -#1\xint:#2#3% {% \expandafter\XINT_xtrunc_sp_I_a\the\numexpr #1-#3\xint:#1\xint:{#3}{#2}% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_sp_I_a #1% {% \xint_UDsignfork @@ -26039,11 +26636,19 @@ $1$ or $-1$. -\XINT_xtrunc_sp_IB_b \krof #1% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_sp_IA_b -#1\xint:#2\xint:#3#4% {% \expandafter\XINT_xtrunc_sp_IA_c \the\numexpr#2-\xintLength{#4}\xint:{#4}\romannumeral\XINT_rep#1\endcsname0% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_sp_IA_c #1% {% \xint_UDsignfork @@ -26051,24 +26656,44 @@ $1$ or $-1$. -\XINT_xtrunc_sp_IAB \krof #1% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_sp_IAA -#1\xint:#2% {% \romannumeral0\XINT_split_fromleft #1.#2\xint_gobble_i\xint_bye2345678\xint_bye..% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_sp_IAB #1\xint:#2% {% 0.\romannumeral\XINT_rep#1\endcsname0#2% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_sp_IB_b #1\xint:#2\xint:#3#4% {% \expandafter\XINT_xtrunc_sp_IB_c \romannumeral0\XINT_split_xfork #1.#4\xint_bye2345678\xint_bye..{#3}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_xtrunc_sp_IB_c #1.#2.#3% {% \expandafter\XINT_xtrunc_sp_IA_c\the\numexpr#3-\xintLength {#1}\xint:{#1}% }% +% \end{macrocode} +% \lverb@& +% @ +% \begin{macrocode} \def\XINT_xtrunc_sp_II #1\xint:#2#3% {% #2\romannumeral\XINT_rep#1\endcsname0.\romannumeral\XINT_rep#3\endcsname0% @@ -26309,37 +26934,44 @@ $1$ or $-1$. }% \def\XINT_fpow_pos_B #1#2{\XINT_outfrac {#2}{#1}}% % \end{macrocode} -% \subsection{\csh{xintiFac}} -% \lverb|& -% -% Note pour 1.2f: il y avait un peu de confusion avec \xintFac, \xintiFac, -% \xintiiFac, car \xintiFac aurait dû aussi utiliser \xintNum une fois -% xintfrac.sty chargé ce qu'elle ne faisait pas. \xintNum est nécessaire pour -% gérer des inputs fractionnaires ou avec [N], car il les transforme en entiers -% stricts, et la doc dit que les macros avec "i" l'utilise. Maintenant -% \xintiFac fait la chose correcte. \xintFac est synonyme. -% -% 2015/11/29: NO MORE a \xintFac, only \xintiFac/\xintiiFac.| +% \subsection{\csh{xintFac}} +% \lverb|Factorial coefficients: variant which can be chained with other +% xintfrac macros. \xintiFac deprecated at 1.2o; \xintFac used by xintexpr.sty.| % \begin{macrocode} -\def\xintifac #1{\expandafter\XINT_fac_fork\the\numexpr \xintNum{#1}.}% +\def\xintifac #1{\expandafter\XINT_fac_fork\the\numexpr\xintNum{#1}.}% +\def\xintFac {\romannumeral0\xintfac}% +\def\xintfac #1{\expandafter\XINT_fac_fork\the\numexpr\xintNum{#1}.[0]}% % \end{macrocode} -% \subsection{\csh{xintiBinomial}} -% \lverb|1.2f. Binomial coefficients.| +% \subsection{\csh{xintBinomial}} +% \lverb|1.2f. Binomial coefficients. \xintiBinomial deprecated at 1.2o; +% \xintBinomial needed by xintexpr.sty.| % \begin{macrocode} \def\xintibinomial #1#2% {% \expandafter\XINT_binom_pre \the\numexpr\xintNum{#1}\expandafter.\the\numexpr\xintNum{#2}.% }% +\def\xintBinomial {\romannumeral0\xintbinomial}% +\def\xintbinomial #1#2% +{% + \expandafter\XINT_binom_pre + \the\numexpr\xintNum{#1}\expandafter.\the\numexpr\xintNum{#2}.[0]% +}% % \end{macrocode} -% \subsection{\csh{xintiPFactorial}} -% \lverb|1.2f. Partial factorial.| +% \subsection{\csh{xintPFactorial}} +% \lverb|1.2f. Partial factorial. For needs of xintexpr.sty.| % \begin{macrocode} \def\xintipfactorial #1#2% {% \expandafter\XINT_pfac_fork \the\numexpr\xintNum{#1}\expandafter.\the\numexpr\xintNum{#2}.% }% +\def\xintPFactorial {\romannumeral0\xintpfactorial}% +\def\xintpfactorial #1#2% +{% + \expandafter\XINT_pfac_fork + \the\numexpr\xintNum{#1}\expandafter.\the\numexpr\xintNum{#2}.[0]% +}% % \end{macrocode} % \subsection{\csh{xintPrd}} % \lverb|There was (not documented anymore since 1.09d, 2013/10/22) a macro @@ -26504,6 +27136,10 @@ $1$ or $-1$. -{\XINT_fgeq_Fn #1}% \krof }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_fgeq_Fd #1\Z #2#3% {% \expandafter\XINT_fgeq_Fe @@ -26691,6 +27327,10 @@ $1$ or $-1$. -{\XINT_fcmp_Fn #1}% \krof }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_fcmp_Fd #1\Z #2#3% {% \expandafter\XINT_fcmp_Fe @@ -27259,6 +27899,10 @@ $1$ or $-1$. \expandafter\XINT_pfloat_a \romannumeral0\xintfloat [\XINTdigits]{#1};\XINTdigits.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_pfloat_opt [\xint:#1]% {% \expandafter\XINT_pfloat_opt_a \the\numexpr #1.% @@ -27275,8 +27919,16 @@ $1$ or $-1$. 0-\XINT_pfloat_pos \krof #1% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_pfloat_zero #1;#2.{ 0.}% \def\XINT_pfloat_neg-{\expandafter-\romannumeral0\XINT_pfloat_pos }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_pfloat_pos #1.#2e#3;#4.% {% \ifnum #3>\xint_c_v \xint_dothis\XINT_pfloat_no\fi @@ -27288,7 +27940,8 @@ $1$ or $-1$. \def\XINT_pfloat_no #1#2;{ #1.#2}% % \end{macrocode} % \lverb|This is all simpler coded, now that 1.2k's \xintFloat always -% outputs a mantissa with exactly one digits before decimal mark always.| +% outputs a mantissa with exactly one digits before decimal mark always. +% | % \begin{macrocode} \def\XINT_pfloat_N #1e-#2;% {% @@ -27299,6 +27952,10 @@ $1$ or $-1$. \def\XINT_pfloat_N_iii{ 0.00}% \def\XINT_pfloat_N_iv { 0.000}% \def\XINT_pfloat_N_v { 0.0000}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_pfloat_P #1e#2;% {% \csname XINT_pfloat_P_\romannumeral#2\endcsname #1% @@ -27309,6 +27966,10 @@ $1$ or $-1$. \def\XINT_pfloat_P_iii#1#2#3#4{ #1#2#3#4.}% \def\XINT_pfloat_P_iv #1#2#3#4#5{ #1#2#3#4#5.}% \def\XINT_pfloat_P_v #1#2#3#4#5#6{ #1#2#3#4#5#6.}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_pfloat_Ps #1e#2;% {% \csname XINT_pfloat_Ps\romannumeral#2\endcsname #100000;% @@ -27383,15 +28044,27 @@ $1$ or $-1$. {% \xint_gob_til_zero #1\XINT_FL_add_zero 0\XINT_FL_add_b #1% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_FL_add_zero #1.#2{#2}%[[ \def\XINT_FL_add_b #1]#2.#3% {% \expandafter\XINT_FL_add_c\romannumeral0\XINTinfloat[#2]{#3}#2.#1]% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_FL_add_c #1% {% \xint_gob_til_zero #1\XINT_FL_add_zero 0\XINT_FL_add_d #1% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_FL_add_d #1[#2]#3.#4[#5]% {% \ifnum\numexpr #2-#3-#5>\xint_c_\xint_dothis\xint_firstoftwo\fi @@ -27473,6 +28146,10 @@ $1$ or $-1$. {% \expandafter\XINT_FL_mul_b\romannumeral0\XINTinfloatS[#3]{#4}#1[#2]% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_FL_mul_b #1[#2]#3[#4]{\xintiiMul{#3}{#1}/1[#4+#2]}% % \end{macrocode} % \subsection{\csh{xintFloatDiv}, \csh{XINTinFloatDiv}} @@ -27501,6 +28178,10 @@ $1$ or $-1$. \else\expandafter\XINT_fldiv_noopt \fi #1#2% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_fldiv_noopt #1#2\xint:#3% {% #1[\XINTdigits]% @@ -27511,6 +28192,10 @@ $1$ or $-1$. {% \expandafter\XINT_fldiv_opt_a\the\numexpr #2.#1% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_fldiv_opt_a #1.#2#3#4% {% #2[#1]{\expandafter\XINT_FL_div_a\romannumeral0\XINTinfloatS[#1]{#4}#1.{#3}}% @@ -27519,6 +28204,10 @@ $1$ or $-1$. {% \expandafter\XINT_FL_div_b\romannumeral0\XINTinfloatS[#3]{#4}/#1e#2% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_FL_div_b #1[#2]{#1e#2}% % \end{macrocode} % \subsection{\csh{xintFloatPow}, \csh{XINTinFloatPow}} @@ -27570,6 +28259,10 @@ $1$ or $-1$. \krof }% \def\XINT_flpow_BisZero .#1.#2#3{#3{1[0]}}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpow_checkB_b #1#2.#3.% {% \expandafter\XINT_flpow_checkB_c @@ -27582,19 +28275,34 @@ $1$ or $-1$. \expandafter\XINT_flpow_checkB_d\the\numexpr#1+#2.#1.#2.% }% % \end{macrocode} -%\lverb|1.2f rounds input to P digits, first.| +% \lverb|& +% +% 1.2f rounds input to P digits, first. +% | % \begin{macrocode} \def\XINT_flpow_checkB_d #1.#2.#3.#4.#5#6% {% \expandafter \XINT_flpow_aa \romannumeral0\XINTinfloat [#3]{#6}{#2}{#1}{#4}{#5}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpow_aa #1[#2]#3% {% \expandafter\XINT_flpow_ab\the\numexpr #2-#3\expandafter.% \romannumeral\XINT_rep #3\endcsname0.#1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpow_ab #1.#2.#3.{\XINT_flpow_a #3#2[#1]}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpow_a #1% {% \xint_UDzerominusfork @@ -27610,16 +28318,28 @@ $1$ or $-1$. {\XINT_signalcondition{DivisionByZero}{0 to the power #4}{}{0[0]}}% }% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpow_b #1#2[#3]#4#5% {% \XINT_flpow_loopI #5.#3.#2.#4.{#1\ifodd #5 \xint_c_i\fi\fi}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpow_truncate #1.#2.#3.% {% \expandafter\XINT_flpow_truncate_a \romannumeral0\XINT_split_fromleft #3.#2\xint_bye2345678\xint_bye..#1.#3.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpow_truncate_a #1.#2.#3.{#3+\xintLength{#2}.#1.}% \def\XINT_flpow_loopI #1.% {% @@ -27631,10 +28351,18 @@ $1$ or $-1$. \fi #1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpow_ItoIII\ifodd #1\fi #2.#3.#4.#5.#6% {% \expandafter\XINT_flpow_III\the\numexpr #6+\xint_c_.#3.#4.#5.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpow_loopI_even #1.#2.#3.%#4.% {% \expandafter\XINT_flpow_loopI @@ -27681,6 +28409,10 @@ $1$ or $-1$. \the\numexpr\xint_c_ii*#5\expandafter.\romannumeral0\xintiisqr{#6}.#3.% #1.#2.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpow_IItoIII\ifodd #1\fi #2.#3.#4.#5.#6.#7.#8% {% \expandafter\XINT_flpow_III\the\numexpr #8+\xint_c_\expandafter.% @@ -27717,6 +28449,10 @@ $1$ or $-1$. -{{#3[#2]}}% \krof #1% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpow_IIIend #1#2#3% {#3{\if#21\xint_afterfi{\expandafter-\romannumeral`&&@}\fi#1}}% % \end{macrocode} @@ -27755,14 +28491,22 @@ $1$ or $-1$. % through \xintiTrunc1.| % \begin{macrocode} \def\XINTinFloatPowerH {\romannumeral0\XINTinfloatpowerh }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINTinfloatpowerh #1#2% {% \expandafter\XINT_flpowerh_a\romannumeral0\xintitrunc1{#2};% \XINTdigits.{#1}{\XINTinfloatS[\XINTdigits]}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpowerh_a #1;% {% - \if0\xintiiLDg{#1}\expandafter\XINT_flpowerh_int + \if0\xintLDg{#1}\expandafter\XINT_flpowerh_int \else\expandafter\XINT_flpowerh_b \fi #1.% }% @@ -27779,7 +28523,7 @@ $1$ or $-1$. }% \def\XINT_flpowerh_c #1.% {% - \ifodd\xintiiLDg{#1} %<- intentional space + \ifodd\xintLDg{#1} %<- intentional space \expandafter\XINT_flpowerh_d\else\expandafter\XINT_flpowerh_e \fi #1.% }% @@ -27829,15 +28573,27 @@ $1$ or $-1$. \expandafter\XINT_flpower_checkB_c \the\numexpr\xintLength{#2}+\xint_c_iii.#3.#2.{#1}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpower_checkB_c #1.#2.% {% \expandafter\XINT_flpower_checkB_d\the\numexpr#1+#2.#1.#2.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpower_checkB_d #1.#2.#3.#4.#5#6% {% \expandafter \XINT_flpower_aa \romannumeral0\XINTinfloat [#3]{#6}{#2}{#1}{#4}{#5}% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flpower_aa #1[#2]#3% {% \expandafter\XINT_flpower_ab\the\numexpr #2-#3\expandafter.% @@ -27859,9 +28615,13 @@ $1$ or $-1$. \def\XINT_flpower_loopI #1.% {% \if1\XINT_isOne {#1}\xint_dothis\XINT_flpower_ItoIII\fi - \ifodd\xintiiLDg{#1} %<- intentional space + \ifodd\xintLDg{#1} %<- intentional space \xint_dothis{\expandafter\XINT_flpower_loopI_odd}\fi \xint_orthat{\expandafter\XINT_flpower_loopI_even}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \romannumeral0\XINT_half #1\xint_bye\xint_Bye345678\xint_bye *\xint_c_v+\xint_c_v)/\xint_c_x-\xint_c_i\relax.% @@ -27888,9 +28648,13 @@ $1$ or $-1$. \def\XINT_flpower_loopII #1.% {% \if1\XINT_isOne{#1}\xint_dothis\XINT_flpower_IItoIII\fi - \ifodd\xintiiLDg{#1} %<- intentional space + \ifodd\xintLDg{#1} %<- intentional space \xint_dothis{\expandafter\XINT_flpower_loopII_odd}\fi \xint_orthat{\expandafter\XINT_flpower_loopII_even}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \romannumeral0\XINT_half#1\xint_bye\xint_Bye345678\xint_bye *\xint_c_v+\xint_c_v)/\xint_c_x-\xint_c_i\relax.% }% @@ -28557,17 +29321,29 @@ $1$ or $-1$. \the\numexpr #3\ifodd #2 \xint_dothis {+\xint_c_iii.(#2+\xint_c_i).0}\fi \xint_orthat {+\xint_c_ii.#2.{}}#100.#3.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flsqrt #1.#2.% {% \expandafter\XINT_flsqrt_a \the\numexpr #2/\xint_c_ii-(#1-\xint_c_i)/\xint_c_ii.#1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flsqrt_a #1.#2.#3#4.#5.% {% \expandafter\XINT_flsqrt_b \the\numexpr (#2-\xint_c_i)/\xint_c_ii\expandafter.% \romannumeral0\XINT_sqrt_start #2.#4#3.#5.#2.#4#3.#5.#1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flsqrt_b #1.#2#3% {% \expandafter\XINT_flsqrt_c @@ -28576,28 +29352,52 @@ $1$ or $-1$. {\xintiiDivRound{\XINT_dsx_addzeros {#1}#3;}% {\XINT_dbl#2\xint_bye2345678\xint_bye*\xint_c_ii\relax}}.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flsqrt_c #1.#2.% {% \expandafter\XINT_flsqrt_d \romannumeral0\XINT_split_fromleft#2.#1\xint_bye2345678\xint_bye..% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flsqrt_d #1.#2#3.% {% \ifnum #2=\xint_c_v \expandafter\XINT_flsqrt_f\else\expandafter\XINT_flsqrt_finish\fi #2#3.#1.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flsqrt_finish #1#2.#3.#4.#5.#6.#7.#8{#8[#6]{#3#1[#7]}}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flsqrt_f 5#1.% {\expandafter\XINT_flsqrt_g\romannumeral0\xintinum{#1}\relax.}% \def\XINT_flsqrt_g #1#2#3.{\if\relax#2\xint_dothis{\XINT_flsqrt_h #1}\fi \xint_orthat{\XINT_flsqrt_finish 5.}}% \def\XINT_flsqrt_h #1{\ifnum #1<\xint_c_iii\xint_dothis{\XINT_flsqrt_again}\fi \xint_orthat{\XINT_flsqrt_finish 5.}}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flsqrt_again #1.#2.% {% \expandafter\XINT_flsqrt_again_a\the\numexpr #2+\xint_c_viii.% }% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_flsqrt_again_a #1.#2.#3.% {% \expandafter\XINT_flsqrt_b @@ -28648,6 +29448,10 @@ $1$ or $-1$. }%[ \def\XINT_floate_zero #1]#2.#3{ 0.e0}% \def\XINT_floate_neg-{\expandafter-\romannumeral0\XINT_floate_pos}% +% \end{macrocode} +% \lverb|& +% | +% \begin{macrocode} \def\XINT_floate_pos #1#2[#3]#4.#5% {% \expandafter\XINT_float_pos_done\the\numexpr#3+#4+#5-\xint_c_i.#1.#2;% @@ -28667,6 +29471,24 @@ $1$ or $-1$. {\romannumeral0\XINTinfloat[#1]{#3}}{#1}}% \def\XINT_infloatmod #1#2{\expandafter\XINT_infloatmod_a\expandafter {#2}{#1}}% \def\XINT_infloatmod_a #1#2#3{\XINTinfloat [#3]{\xintMod {#2}{#1}}}% +% \end{macrocode} +% \subsection*{At End of \LaTeX\ Document deprecation message} +% \addcontentsline{toc}{subsection}{At End of \LaTeX\ Document deprecation message} +% \lverb|1.2o| +% \begin{macrocode} +\ifdefined\documentclass\ifdefined\AtEndDocument + \AtEndDocument{% +\XINT_ifFlagRaised{Deprecated-xintfrac}% + {\PackageError{xintfrac} +{Usage of deprecated macros!} +{This deprecated macro from xintfrac.sty has been detected:\MessageBreak +%\XINT_ifFlagRaised{xintNeq}{% +\string\xintNeq\space(use \string\xintNotEq\space or xint's \string\xintiiNotEq!)\MessageBreak +%}{}% +It will get removed at some future release.}}% + {% no deprecated macro used (at top level...) + }% +}\fi\fi \XINT_restorecatcodes_endinput% % \end{macrocode} % @@ -28742,7 +29564,7 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintseries}% - [2017/08/06 1.2n Expandable partial sums with xint package (JFB)]% + [2017/08/29 1.2o Expandable partial sums with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintSeries}} % \begin{macrocode} @@ -29240,7 +30062,7 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcfrac}% - [2017/08/06 1.2n Expandable continued fractions with xint package (JFB)]% + [2017/08/29 1.2o Expandable continued fractions with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintCFrac}} % \begin{macrocode} @@ -29577,12 +30399,12 @@ $1$ or $-1$. }% \def\XINT_fgtc_e #1% {% - \xintifZero {#1}{\expandafter\xint_firstofone\xint_gobble_iii}% + \xintiiifZero {#1}{\expandafter\xint_firstofone\xint_gobble_iii}% {\XINT_fgtc_f {#1}}% }% \def\XINT_fgtc_f #1#2% {% - \xintifZero {#2}{\xint_thirdofthree}{\XINT_fgtc_g {#1}{#2}}% + \xintiiifZero {#2}{\xint_thirdofthree}{\XINT_fgtc_g {#1}{#2}}% }% \def\XINT_fgtc_g #1#2#3% {% @@ -30491,7 +31313,7 @@ $1$ or $-1$. % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintexpr}% - [2017/08/06 1.2n Expandable expression parser (JFB)]% + [2017/08/29 1.2o Expandable expression parser (JFB)]% \catcode`! 11 \let\XINT_Cmp \xintiiCmp % \end{macrocode} @@ -31551,9 +32373,9 @@ $1$ or $-1$. \XINT_expr_defbin_b {expr} {>=} {v}{vi} {xintGtorEq}% \XINT_expr_defbin_b {flexpr}{>=} {v}{vi} {xintGtorEq}% \XINT_expr_defbin_b {iiexpr}{>=} {v}{vi} {xintiiGtorEq}% -\XINT_expr_defbin_b {expr} {!=} {v}{vi} {xintNeq}% -\XINT_expr_defbin_b {flexpr}{!=} {v}{vi} {xintNeq}% -\XINT_expr_defbin_b {iiexpr}{!=} {v}{vi} {xintiiNeq}% +\XINT_expr_defbin_b {expr} {!=} {v}{vi} {xintNotEq}% +\XINT_expr_defbin_b {flexpr}{!=} {v}{vi} {xintNotEq}% +\XINT_expr_defbin_b {iiexpr}{!=} {v}{vi} {xintiiNotEq}% \XINT_expr_defbin_b {expr} {..} {iii}{vi} {xintSeq::csv}% \XINT_expr_defbin_b {flexpr}{..} {iii}{vi} {xintSeq::csv}% \XINT_expr_defbin_b {iiexpr}{..} {iii}{vi} {xintiiSeq::csv}% @@ -32333,12 +33155,12 @@ $1$ or $-1$. }% % \end{macrocode} % \subsection{! as postfix factorial operator} -% \lverb|A float version \xintFloatFac was at last done 2015/10/06 for 1.2. -% Attention 2015/11/29 for 1.2f: no more \xintFac, but \xintiFac.| +% \lverb|& +% | % \begin{macrocode} \let\XINT_expr_precedence_! \xint_c_x \def\XINT_expr_op_! #1{\expandafter\XINT_expr_getop - \csname .=\xintiFac{\XINT_expr_unlock #1}\endcsname }% + \csname .=\xintFac{\XINT_expr_unlock #1}\endcsname }% \def\XINT_flexpr_op_! #1{\expandafter\XINT_expr_getop \csname .=\XINTinFloatFac{\XINT_expr_unlock #1}\endcsname }% \def\XINT_iiexpr_op_! #1{\expandafter\XINT_expr_getop @@ -33562,7 +34384,7 @@ $1$ or $-1$. {% \expandafter #1\expandafter #2\csname .=% \expandafter\XINT_expr_argandopt - \romannumeral`&&@\XINT_expr_unlock#3,,.\xintiFac\XINTinFloatFac + \romannumeral`&&@\XINT_expr_unlock#3,,.\xintFac\XINTinFloatFac \endcsname }% \def\XINT_flexpr_func_factorial #1#2#3% @@ -33651,7 +34473,7 @@ $1$ or $-1$. \def\XINT_expr_func_binomial #1#2#3% {% \expandafter #1\expandafter #2\csname .=% - \expandafter\expandafter\expandafter\xintiBinomial + \expandafter\expandafter\expandafter\xintBinomial \expandafter\XINT_expr_twoargs \romannumeral`&&@\XINT_expr_unlock #3,\endcsname }% @@ -33672,7 +34494,7 @@ $1$ or $-1$. \def\XINT_expr_func_pfactorial #1#2#3% {% \expandafter #1\expandafter #2\csname .=% - \expandafter\expandafter\expandafter\xintiPFactorial + \expandafter\expandafter\expandafter\xintPFactorial \expandafter\XINT_expr_twoargs \romannumeral`&&@\XINT_expr_unlock #3,\endcsname }% @@ -34196,8 +35018,8 @@ $1$ or $-1$. \xintFor #1 in {DivTrunc,Mod,Round,Trunc,iRound,iTrunc,iQuo,iRem, iiDivTrunc,iiDivRound,iiMod,iiQuo,iiRem,% - Lt,Gt,Eq,LtorEq,GtorEq,Neq,% - iiLt,iiGt,iiEq,iiLtorEq,iiGtorEq,iiNeq,% + Lt,Gt,Eq,LtorEq,GtorEq,NotEq,% + iiLt,iiGt,iiEq,iiLtorEq,iiGtorEq,iiNotEq,% Add,Sub,Mul,Div,Pow,E,% iiAdd,iiSub,iiMul,iiPow,iiE,% AND,OR,XOR,% @@ -34215,8 +35037,8 @@ $1$ or $-1$. % qfloat?). Pas le temps d'y réfléchir. Je ne fais rien. \xintFor #1 in {Num,Irr,Abs,iiAbs,Sgn,iiSgn,TFrac,Floor,iFloor,Ceil,iCeil,% Sqr,iiSqr,iiSqrt,iiSqrtR,iiIsZero,iiIsNotZero,iiifNotZero,iiifSgn,% - Odd,Even,iiOdd,iiEven,Opp,iiOpp,iiifZero,iFac,iBinomial,% - iPFactorial,iiFac,iiBinomial,iiPFactorial,Bool,Toggle}\do + Odd,Even,iiOdd,iiEven,Opp,iiOpp,iiifZero,Fac,Binomial,% + PFactorial,iiFac,iiBinomial,iiPFactorial,Bool,Toggle}\do {\toks0 \expandafter{\the\toks0% \expandafter\let\csname xint#1NE\expandafter\endcsname\csname xint#1\expandafter @@ -34493,11 +35315,11 @@ $1$ or $-1$. \iffalse % grep -c -e "^{%" xint*sty xint.sty:178 -xintbinhex.sty:55 +xintbinhex.sty:53 xintcfrac.sty:183 xintcore.sty:278 xintexpr.sty:168 -xintfrac.sty:439 +xintfrac.sty:441 xintgcd.sty:50 xintkernel.sty:13 xintseries.sty:48 @@ -34508,11 +35330,11 @@ xinttools.sty:138 \iffalse % grep -c -e "^}%" xint*sty xint.sty:177 -xintbinhex.sty:54 +xintbinhex.sty:52 xintcfrac.sty:183 xintcore.sty:275 xintexpr.sty:199 -xintfrac.sty:437 +xintfrac.sty:439 xintgcd.sty:52 xintkernel.sty:14 xintseries.sty:48 @@ -34556,8 +35378,8 @@ xinttools.sty:137 Right bracket \] Circumflex \^ Underscore \_ Grave accent \` Left brace \{ Vertical bar \| Right brace \} Tilde \~} -\CheckSum {30253}% 30303 pour 1.2h, 30403 pour 1.2i, 30750 pour 1.2j, - % 30677 pour 1.2k, 30931 pour 1.2l, 30439 pour 1.2m +\CheckSum {30524}% 30303 pour 1.2h, 30403 pour 1.2i, 30750 pour 1.2j, + % 30677 pour 1.2k, 30931 pour 1.2l, 30439 pour 1.2m, 30253 pour 1.2n \makeatletter\check@checksum\makeatother \Finale %% End of file xint.dtx diff --git a/Master/texmf-dist/source/generic/xint/xint.ins b/Master/texmf-dist/source/generic/xint/xint.ins index ef332270ab9..b1e9a341ec5 100644 --- a/Master/texmf-dist/source/generic/xint/xint.ins +++ b/Master/texmf-dist/source/generic/xint/xint.ins @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.2n 2017/08/06 +%% The xint bundle 1.2o 2017/08/29 %% Copyright (C) 2013-2017 by Jean-Francois Burnol %% --------------------------------------------------------------- %% -- cgit v1.2.3