summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/generic/xint/xint.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2015-10-11 21:21:00 +0000
committerKarl Berry <karl@freefriends.org>2015-10-11 21:21:00 +0000
commitc42b50b291d00f547400888b81ef4d2bcad45142 (patch)
tree9ab2f5792d7627887e9f858a103ba1c7de329a67 /Master/texmf-dist/source/generic/xint/xint.dtx
parentced6522f86e501ede0097c2b6362bc17603b6eef (diff)
xint (11oct15)
git-svn-id: svn://tug.org/texlive/trunk@38612 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/generic/xint/xint.dtx')
-rw-r--r--Master/texmf-dist/source/generic/xint/xint.dtx8641
1 files changed, 4558 insertions, 4083 deletions
diff --git a/Master/texmf-dist/source/generic/xint/xint.dtx b/Master/texmf-dist/source/generic/xint/xint.dtx
index 3a3a4bc6fe3..553962e7b0a 100644
--- a/Master/texmf-dist/source/generic/xint/xint.dtx
+++ b/Master/texmf-dist/source/generic/xint/xint.dtx
@@ -1,25 +1,25 @@
% -*- coding: iso-latin-1; time-stamp-format: "%02d-%02m-%:y at %02H:%02M:%02S %Z" -*-
% N.B.: this dtx file does NOT use \DocInput, only docstrip. The user manual
-% latex source is NOT prefixed with %'s
+% latex source is NOT prefixed with percent characters.
%<*dtx>
-\def\xintdtxtimestamp {Time-stamp: <17-09-2015 at 11:09:20 CEST>}
+\def\xintdtxtimestamp {Time-stamp: <10-10-2015 at 23:42:39 CEST>}
%</dtx>
%<*drv>
%% ---------------------------------------------------------------
-\def\xintdocdate {2015/09/17}
-\def\xintbndldate{2015/09/12}
-\def\xintbndlversion {1.1c}
+\def\xintdocdate {2015/10/10}
+\def\xintbndldate{2015/10/10}
+\def\xintbndlversion {1.2}
%</drv>
%<*dtx>
\iffalse % meta-comment
%</dtx>
%<readme>% README
%<changes>% CHANGE LOG
-%<readme|changes>% xint v1.1c
-%<readme|changes>% 2015/09/12
+%<readme|changes>% xint v1.2
+%<readme|changes>% 2015/10/10
%<*readme|changes>
- Source: xint.dtx v1.1c 2015/09/12 (doc 2015/09/17)
+ Source: xint.dtx v1.2 2015/10/10 (doc 2015/10/10)
Author: Jean-Francois Burnol
Info: Expandable operations on big integers, decimals, fractions
License: LPPL 1.3c
@@ -27,7 +27,7 @@
%</readme|changes>
%<*!readme&!changes&!dohtmlsh&!dopdfsh&!makefile>
%% ---------------------------------------------------------------
-%% The xint bundle v1.1c 2015/09/12
+%% The xint bundle v1.2 2015/10/10
%% Copyright (C) 2013-2015 by Jean-Francois Burnol
%<xintkernel>%% xintkernel: Paraphernalia for the xint packages
%<xinttools>%% xinttools: Expandable and non-expandable utilities
@@ -49,6 +49,34 @@ Change log is to be found in `CHANGES.pdf` or `CHANGES.html`.
The user manual is `xint.pdf`, and the commented source code is
available as `sourcexint.pdf`.
+
+Aim
+===
+
+The basic aim is provide *expandable* computations on big integers,
+and also big fractions. For example
+
+ \xinttheexpr reduce(37189719/183618963+11390170/17310720)^17\relax
+
+will evaluate exactly the fraction (the result has 462 characters
+including the fraction slash). One can also work with dummy
+variables. For example
+
+ \xinttheexpr mul(add(x(x+1)(x+2), x=y..y+15), y=171286,98762,9296)\relax
+
+evaluates to `15979066346135829902328007959448563667099190784`.
+
+It is possible to use the package with Plain as well as with LaTeX.
+
+Sub-units `xintcore`, `xint` and `xintfrac` provide the underlying
+macros, and `xintexpr` loads all of them and provides expandable
+parsers allowing computations such as the above (and more). A more
+light-weight package [bnumexpr](http://www.ctan.org/pkg/bnumexpr)
+(LaTeX only) loads only `xintcore` and provides a parser which
+handles only big integers, the four operations, the power operation
+and the factorial (v1.2).
+
+
Usage
=====
@@ -78,7 +106,8 @@ be loaded in any catcode context such that letters, digits, `\` and
`xintcore.sty` and `xinttools.sty` both import `xintkernel.sty`
which has the catcode handler and package identifier and defines a
-few utilities such as `\oodef` or `\xint_dothis/\xint_orthat`.
+few utilities such as `\oodef`, `\fdef`, or `\xint_dothis/\xint_orthat`.
+
Installation
============
@@ -179,6 +208,7 @@ Finishing the installation in a TDS hierarchy:
Depending on the destination, it may then be necessary to refresh a
filename database.
+
License
=======
@@ -207,6 +237,58 @@ pandoctpl.latex, doHTMLs.sh, doPDFs.sh, xint.dvi, xint.pdf,
Makefile.mk.</div>
%</readme>--------------------------------------------------------
%<*changes>-------------------------------------------------------
+`1.2 (2015/10/10)`
+----
+
+ - the basic arithmetic implemented in **xintcore** has been entirely
+ rewritten. The mathematics remains the elementary school one, but the
+ `TeX` implementation achieves higher speed (except, regarding
+ addition/subtraction, for numbers up to about thirty digits), the
+ gains becoming quite significant for numbers with hundreds of digits.
+
+ - the inputs must have less than 19959 digits. But computations with
+ thousands of digits take time.
+
+ - a previously standing limitation of `\xintexpr`, `\xintiiexpr`, and
+ of `\xintfloatexpr` to numbers of less than 5000 digits has been
+ lifted.
+
+ - a *qint* function is provided to help the parser gather huge integers
+ in one-go, as an exception to its normal mode of operation which
+ expands token by token.
+
+ - new `\xintFloatFac` macro for computing the factorials of integers as
+ floating point numbers to a given precision. The `!` postfix operator
+ inside `\xintfloatexpr` maps to this new macro rather than to the
+ exact factorial as used by `\xintexpr` and `xintiiexpr`.
+
+ - the macros `\xintAdd`, `\xintSub`, ..., now require package
+ **xintfrac**. With only **xintcore** or **xint** loaded, one _must_
+ use `\xintiiAdd`, `\xintiiSub`, ..., or `\xintiAdd`, `\xintiSub`,
+ etc...
+
+ - there is more flexibility in the parsing done by the macros from
+ **xintfrac** on fractional input: the decimal parts of both the
+ numerator and the denominator may arise from a separate expansion via
+ ``\romannumeral-`0``. Also the strict `A/B[N]` format is a bit
+ relaxed: `N` may be empty or anything understood by `\numexpr`.
+
+ - on the other hand an isolated dot `.` is not legal syntax anymore
+ inside the expression parsers: there must be digits either before or
+ after. It remains legal input for the macros of **xintfrac**.
+
+ - added `\ht`, `\dp`, `\wd`, `\fontcharht`, etc... to the tokens
+ recognized by the parsers and expanded by `\number`.
+
+ - an obscure bug in package **xintkernel** has been fixed, regarding
+ the sanitization of catcodes: under certain circumstances (which
+ could not occur in a normal `LaTeX` context), unusual catcodes could
+ end up being propagated to the external world.
+
+ - an effort at randomly shuffling around various pieces of the
+ documentation has been done.
+
+
`1.1c (2015/09/12)`
----
@@ -557,13 +639,15 @@ breaking changes
the macros
* **xinttools** defines `\odef`, `\oodef`, `\fdef` (if the names have
- already been assigned, it uses `\xintoodef` etc...). These tools
- are provided for the case one uses the package macros in a
- non-expandable context, particularly `\oodef` which expands twice
- the macro replacement text and is thus a faster alternative to
- `\edef` taking into account that the **xint** bundle macros expand
- already completely in only two steps. This can be significant when
- repeatedly making `\def`-initions expanding to hundreds of digits.
+ already been assigned, it uses `\xintoodef` etc...). These tools are
+ provided for the case one uses the package macros in a non-expandable
+ context. `\oodef` expands twice the macro replacement text, and `\fdef`
+ applies full expansion. They are useful in situations where one does not
+ want a full `\edef`. `\fdef` appears to be faster than `\oodef` in almost
+ all cases (with less than thousand digits in the result), and even faster
+ than `\edef` for expanding the package macros when the result has a few
+ dozens of digits. `\oodef` needs that expansion ends up in thousands of
+ digits to become competitive with the other two.
* some across the board slight efficiency improvement as a result of
modifications of various types to *fork macros* and *branching
@@ -2373,6 +2457,8 @@ pdfpagemode=UseOutlines}
\frenchspacing
\renewcommand\familydefault\sfdefault
+\def\liiibigint{\href{http://latex-project.org/svnroot/experimental/trunk/l3trial/l3bigint}{l3bigint}}
+
\begin{document}\thispagestyle{empty}% \ttzfamily already done
\pdfbookmark[1]{Title page}{TOP}
% \makeatletter % @ n'est plus actif dans dtx 1.1, ouf!
@@ -2617,37 +2703,57 @@ This section provides recommended reading on first discovering the package.
\subsection{The packages of the \xintname bundle}
+
\begin{framed}
The \xintcorename and \xintname packages provide macros dedicated to
\emph{expandable} computations on numbers exceeding the \TeX{} (and \eTeX{})
limit of \dtt{\number"7FFFFFFF} (\emph{i.e.} on numbers of $10$ digits or
more.)
+\medskip
+
With package \xintfracname also decimal numbers (with a dot \dtt{.} as
decimal mark), numbers in scientific notation (with a lowercase \dtt{e}),
and even fractions (with a forward slash \dtt{/}) are acceptable inputs.
+\medskip
+
Package \xintexprname handles expressions
written with the standard infix notations, thus providing a more convenient
- interface.
+ interface.
\begin{everbatim*}
-\xinttheexpr (2981279/2662176-317127/17129791)^3\relax\par
-\noindent\xintthefloatexpr 1.23456789123456789^123456789\relax{}
-(<- notice the exponent size)\par
-\end{everbatim*}
+\xinttheexpr (2981.279/.2662176e2-3.17127e2/3.129791)^3\relax
+\end{everbatim*}\newline
+(the |A/B[n]| notation on output means $(A/B)\times 10^n$), or also:
+\begin{everbatim*}
+\xintthefloatexpr 1.23456789123456789^123456789\relax
+\end{everbatim*} (<- notice the size of this exponent).
+
+\smallskip
-\xintexprname is able to do computations with dummy variables, here an example:
+ Furthermore \xintexprname is also able since release |1.1| of |2014/10/28| to
+ do computations with dummy variables, as in this example:
\begin{everbatim*}
-\xinttheexpr reduce(add(1/x, x=1..100))\relax\par
+\xinttheexpr seq(1+reduce(add(mul((x-i+1)/i,i=1..j),j=1..floor(x/2))),
+ x=10..20, 31, 51)\relax
\end{everbatim*}
-The reasonable range of use of the package arithmetics is with numbers of less
-than $\boxed{100}$ digits (integer+decimal parts combined), as it allows to do
-hundreds, even thousands of such computations with an acceptable time impact.
-When developing in 2013 the basic macros still in \xintcorename, the author's
-priority was the speed of operations for numbers in that range.
+ The reasonable range of use of the package arithmetics is with numbers of
+ less than \emph{one hundred or perhaps two hundred digits.} Release |1.2|
+ has significantly improved the speed of the basic operations for numbers
+ with more than $50$ digits, the speed gains getting better for bigger
+ numbers. Although numbers up to about \dtt{19950} digits are acceptable
+ inputs, the package is not at his peak efficiency when confronted with such
+ really big numbers having thousands of digits.\footnotemark
\end{framed}
+\footnotetext{The maximal handled size for inputs to multiplication is
+ \dtt{19959} digits. This limit is observed with the current default values
+ of some parameters of the tex executable (input save stack size at 5000,
+ maximal expansion depth at 10000). Nesting of macros will reduce it and it
+ is best to restrain numbers to at most \dtt{19900} digits. The output, as
+ naturally is the case with multiplication, may exceed the bound.}
+
The \eTeX{} extensions (dating back to 1999) must be enabled; this is the case
by default in modern distributions, except for the |tex| executable itself
which has to be the pure \textsc{D.~Knuth} software with no additions. The
@@ -2659,11 +2765,6 @@ All components may be loaded with \LaTeX{} |\usepackage| or
|\RequirePackage| or, for any other format based on \TeX{}, directly via
\string\input{}, e.g. |\input xint.sty\relax|. There are no package
options.
-%
-% {\makeatother\footnote{\csa{empty}, \csa{space}, \csa{z@},
-% \csa{@ne}, and \csa{m@ne} should have the same meaning as in Plain and
-% \LaTeX.}}
-%
Each package automatically loads those not already loaded it depends on (but
in a few rare cases there are some extra dependencies, for example the |gcd|
function in \xintexprname expressions requires explicit loading of package
@@ -2777,7 +2878,12 @@ Additional derived parsers:
bool, togl, add, mul, seq, subs, rseq, rrseq, iter}. And |"| may serve for
hexadecimal input (uppercase only; package \xintbinhexname required).
- See also \autoref{ssec:syntax}, as well as \autoref{sec:expr11}.
+ |1.2| has added \dtt{qint, qfrac, qfloat} to tell the parser to skip its usual
+ token by token expansion when gathering the digits of a number.
+
+ See \autoref{ssec:syntax} for the complete syntax, as well as
+ \autoref{sec:expr11} which focused on the extensions brought with |xintexpr
+ 1.1|.
\end{framed}
Here is an example of a computation:
@@ -2818,18 +2924,10 @@ it will naturally not be able to digest a number in scientific notation or a
fraction. Fixed point decimal numbers however can be understood by \TeX{} in
the context of manipulation of dimensions.
-The constraint of expandability exerces its spell on the programmer as a
-challenge to raise, and has its rewards: this is my only excuse for pretending
-that computing expandably with fractions of dozens of digits has any use. The
-initial release of \xintname (|2013/03/28|) was quickly followed by
-\xintfracname which handles exactly fractions, decimal numbers, scientific
-numbers, hence in a derived way floating point numbers. A bit later
-(|2013/05/25|) \xintexprname implemented an expandable parser of expressions
-with the usual infix notations for the basic operations.
-The core big integer routines (now in \xintcorename) have not been much
-changed since (although my knowledge of \TeX{} programming increased a lot),
-the effort of development going mainly in \xintexprname which was extended
-first in september 2013, then substantially in october 2014.
+% The constraint of expandability exerces its spell on the programmer as a
+% challenge to raise, and has its rewards: this is my only excuse for pretending
+% that computing expandably with fractions of dozens of digits has any use.
+
% The implementation is also maximally complicated as many functionalities of
% the \TeX{} macro language can't be used in the source code of \xintname by the
@@ -2844,11 +2942,11 @@ first in september 2013, then substantially in october 2014.
% gains could be achieved via a complete rewrite of all basic macros of the
% package.
-The underlying macros to which |\xinttheexpr ...\relax| maps operations
-are thus provided by packages \xintcorename, \xintname (for long) integers and
-\xintfracname (for fractions, decimal numbers, scientific numbers). They are
-nestable. For example to do |21+32*43|, the syntax would be (only
-\xintcorename needed):
+The underlying macros to which |\xinttheexpr ...\relax| and the other parsers
+map the infix operations are provided by packages \xintcorename, \xintname (for
+integers) and \xintfracname (for fractions, decimal numbers, and scientific
+numbers). They are nestable. For example to do something like |21+32*43|, the
+syntax would be (only \xintcorename is needed):
\begin{everbatim*}
\xintiiAdd{21}{\xintiiMul{32}{43}}\par
\noindent\xintiiMul{21283978192739181739}{\xintiiSub {130938109831081320}{29810810281}}
@@ -2862,11 +2960,11 @@ Needless to say this quickly becomes a bit painful. One more example (needs
\end{everbatim*}
This shows that package \xintfracname knows natively how to handle fractions
-|A/B| (notice that |*|, |+| and |-| contrarily to |/| are not generally
-accepted in the arguments to the \xintfracname macros; but see
-\autoref{sec:inputs} and \autoref{sec:useofcount}) and that it has
-a command \csbxint{Irr} to reduce to smallest terms (in an
-|\xintexpr..\relax| this would be the |reduce| function).
+|A/B|. Notice that |*|, |+| and |-| contrarily to the |/| which is treated as
+a special optional delimiter are not accepted in the arguments to the
+\xintfracname macros (see \autoref{sec:inputs} and \autoref{sec:useofcount}
+for some exceptions). There is \csbxint{Irr} to reduce to smallest terms (in
+an |\xintexpr..\relax| this would be the |reduce| function).
Again, all computations done by |\xinttheexpr..\relax| are completely exact.
Thus, very quickly very big numbers are created (and computation times
@@ -2879,8 +2977,8 @@ assignment to |\xintDigits|):
(<- notice the size of the power of ten: this surely largely exceeds your pocket
calculator abilities).
-It is also possible
-to do some computer algebra like evaluations (only numerically though):
+It is also possible to do some (expandable...) computer algebra like
+evaluations (only numerically though):
\begin{everbatim*}
\xinttheiiexpr add(i^5, i=100..200)\relax\par
\noindent\xinttheexpr add(x/(x+1), x = 1000..[3]..1020)\relax
@@ -2895,31 +2993,31 @@ Make sure to read \autoref{ssec:userinterface}, \autoref{sec:expr11} and
\subsection {Changes}
-On |TeXLive| (and presumably |MikTeX|), issue in a console |texdoc --list
-xint| to get access to the documentation files, among them |CHANGES.html|
-provides the detailed cumulative change log since the initial release.
+The initial \xintname (|2013/03/28|) was followed by \xintfracname
+(|2013/04/14|) which handled exactly fractions and decimal numbers. Later came
+\xintexprname (|2013/05/25|) and at the same time \xintfracname got extended
+to handle floating point numbers. Later, \xinttoolsname was detached
+(|2013/11/22|). The main focus of development during late 2013 and early 2014
+was kept on \xintexprname. One year later it got a significant upgrade with
+|1.1| of |2014/10/28|. The core integer routines remained essentially
+unmodified during all this time (apart from a slight improvement of division
+early 2014) until their complete rewrite with release
+|1.2| from |2015/10/10|.
-It is also available on \href{http://ctan.org}{CTAN} via
-\href{http://mirrors.ctan.org/macros/generic/xint/CHANGES.html}{this link}.
-Or, running |etex xint.dtx| in a working repertory will extract a |CHANGES.md|
-file with Markdown syntax.
-
-The most recent major changes came with release |1.1| from |2014/10/28|.
-
-Since, |xint| saw only minor modifications such as enhancements to the
-documentation and a few bug fixes (|1.1c 2015/09/12| fixed a bug with
-\csbxint{Assign}, |1.1b 2015/08/31| transferred some macros which had been
-left in |xint.sty| and should have been part of |xintcore.sty|, and earlier
-|1.1a 2014/11/07| had corrected a problem with \csbxint{NewExpr}).
-
-|1.1 2014/10/28| brought many additions, most of them to package
-\xintexprname, such as for example the evaluation of expressions with dummy
-variables, possibly iteratively, and with allowed nesting. See
-\autoref{sec:expr11} for a description of these new functionalities.
-
-Apart from that, |1.1| brought also two main other changes:
+\begin{description}
+\item [|1.2 (2015/10/10):|] complete rewrite of the core arithmetic routines.
+ The efficiency for numbers with less than $20$ or $30$ digits is slightly
+ compromised (for addition/subtraction) but it is increased for bigger
+ numbers. For multiplication and division the gains are there for almost all
+ sizes, and become quite noticeable for numbers with hundreds of digits. The
+ allowable inputs are constrained to have less than about $19950$ digits
+ ($19968$ for addition, $19959$ for multiplication).
+\item [|1.1 (2014/10/28):|] many extensions to package \xintexprname, such as
+ the evaluation of expressions with dummy variables, possibly iteratively,
+ with allowed nesting. See \autoref{sec:expr11} for a description of
+ these new functionalities. Also worthy of attention:
\begin{enumerate}
-\item |\xintiiexpr...\relax| now associates |/| with the \emph{rounded}
+\item |\xintiiexpr...\relax| associates |/| with the \emph{rounded}
division (the |//| operator being provided for the \emph{truncated}
division) to be in synchrony with the habits of |\numexpr|,
\item the \xintfracname macro \csbxint{Add} (corresponding to |+| in
@@ -2928,13 +3026,24 @@ Apart from that, |1.1| brought also two main other changes:
smallest terms, or systematically computing the |LCM| of the denominators
would be too costly (I think).
\end{enumerate}
-Also worth mentioning is that \xintname does not load \xinttoolsname
-anymore (only \xintexprname does) and that the core arithmetic macros have
-been moved to a new package \xintcorename which is loaded automatically by
-\xintname.
+\xintname does not load \xinttoolsname
+anymore (only \xintexprname does) and the core arithmetic macros are
+moved to a new package \xintcorename (loaded automatically by
+\xintname, itself loaded by \xintfracname, itself loaded by \xintexprname).
Package \href{http://www.ctan.org/pkg/bnumexpr}{bnumexpr} (which is \LaTeX{}
only) now also loads only \xintcorename.
+\end{description}
+
+There is a file |CHANGES.html| (also |CHANGES.pdf|) which provides the
+detailed cumulative change log since the initial release. To access it, issue
+on the command line |texdoc --list xint| (this works |TeXLive| and there is
+probably an equivalent in |MikTeX|).
+
+It is also available on \href{http://ctan.org}{CTAN} via
+\href{http://mirrors.ctan.org/macros/generic/xint/CHANGES.html}{this link}.
+Or, running |etex xint.dtx| in a working repertory will extract a |CHANGES.md|
+file with Markdown syntax.
\subsection{Installation instructions}
\label{ssec:install}
@@ -2979,95 +3088,70 @@ If you have |xint.dtx|, no internet access and can not use the Makefile
method: |etex xint.dtx| extracts all files and among them the |README| as a
file with name |README.md|. Further help and options will be found therein.
-\subsection{FAQ}
-
-\def\liiibigint{\href{http://latex-project.org/svnroot/experimental/trunk/l3trial/l3bigint}{l3bigint}}
+% \subsection{FAQ}
-% pour accéder à l'historique des commits:
-% https://github.com/latex3/latex3/tree/master/l3trial/l3bigint
+% % pour accéder à l'historique des commits:
+% % https://github.com/latex3/latex3/tree/master/l3trial/l3bigint
-We are honoured to present here this interview with the author, dating back to
-late March 2014.
-\begin{description}
-\item[Will \xintexprname implement \texttt{exp}, \texttt{log},
- \texttt{cos}, \texttt{sin} \dots at some point?]
-I guess so.
-
-\item[\xintseriesname already provides generic tools.] Right, although the
- casual user of the \xintname bundle will not quite know how to do variable
- reduction expandably in order to use some series or Pad\'e approximants.
- Besides I wrote the code at the beginning of the project and perhaps I could
- do it better now (I have not looked at it for a while). Anyhow, generic things
- do not help much if one wants to optimize.
-
-\item[Optimizing? isn't \TeX's macro expansion mechanism intrinsically slow?]
- Intensive use of \csa{numexpr} and some token manipulation algorithms
- exploiting to the best I could \TeX{} macros with parameters grant \xintname
- a significant speed up in expandable arithmetic on big integers compared to
- previously available implementations. You can do some comparisons with
- multiplication on numbers with $100$ digits or division of one of $100$
- digits by another of $50$ digits, for example. However expandability is
- antagonist of speed, and I agree it is not very exciting to optimize slow
- things. And I was disappointed last year to realize the slowness of \TeX's
- mouth when it has to keep hundreds of tokens in cheek to mix them later with
- new aliments.
-% https://github.com/latex3/latex3/commit/f46e22cb772ee34aeb2fb200f7907ed3e6192bac
-%
-\footnote{\label{fn:l3bigint2015}\textbf{2015/09/15:} the recent
- (experimental, and partially still in progress) new version of \liiibigint{}
- by Bruno \textsc{Le Floch} works with comparable speed as \xintname for
- numbers with less than (roughly) $100$ digits (the division was not
- available for testing a.t.t.o.w.), and its multiplication becomes then much
- better: about $5x$ faster for numbers with $400$ digits and $20x$ faster for
- numbers with $1000$ digits. Bruno succeeded into implementing expandably
- Karatsuba multiplication and he achieves
- sub-quadratic growth in the computation time, whereas the xint integer
- multiplication time drifts from quadratic to worse than cubic: from $50$ to
- $100$ digits the time factor increases by about $4.6$ for \xintname and
- about $3.1$ for \liiibigint, in the former case |xint| is the faster, in
- the latter it is |l3bigint| the faster. As an illustration squaring a $8000$
- digits number on my computer is $470x$ faster with the new \liiibigint{}
- compared to |xint| ($5.5s$ vz $43m$). As \liiibigint{} is still in progress,
- this may well evolve further (currently it seems to be limited to numbers up
- to $8192$ digits). The addition currently starts getting faster than the one
- from |xint| with about $400$ digits (2013 |xint dev| had a variant of
- addition which I think would be faster than the new one from \liiibigint{}
- in the whole range up to circa $1000$ digits; but it did not make it into
- the release as it was a bit slower than the adopted one up to
- $50$ digits; and adopting it would have sped up multiplication only by a
- factor of $2$ anyhow, and would not have solved the steep shape of the curve
- of computation times.)}
-%
-Believe me, I try not to think too much about the fact that the whole
-enterprise is made irrelevant by Lua\LaTeX's ability to access external
-libraries.
-
-\item[Well, why isn't this \texttt{log} etc\dots thing done yet?]
-I have to decide on the maximal precision to achieve: $24$, $32$, $48$,
-$64$,\dots ; to settle that I would need to implement some initial versions and
-benchmark them.
-
-\item[Fair enough. That's the common lot. So why not yet?] I am a bit
- overworked. It is also an opportunity to think over
- the basic underlying mathematics, and will need devoted thinking for some not
- insignificant amount of time. So far I didn't find the time, or rather I found
- out good means to waste it sillily. I also anticipate that originality could
- very
- well not pay off at all, so small is the window for the precision.
-
-\item[Any chance this could be done in time for TL2014?] No,
- sorry.\newline Release |1.09m| of |[2014/02/26]| was the end of a cycle, and
- this |1.09n| of |[2014/04/01]| is only for a bug fix and inclusion of this
- |FAQ| in the documentation.
-
-\footnotesize
-
-\item[and in time for TL2015?] ... (indistinct mumbles, something like
- \emph{too tired}, \emph{I need a life}, \emph{get yourself a calculator},
- \emph{we'll see}\dots)
-\end{description}
+% We are honoured to present here this interview with the author, dating back to
+% late March 2014.
+% \begin{description}
+% \item[Will \xintexprname implement \texttt{exp}, \texttt{log},
+% \texttt{cos}, \texttt{sin} \dots at some point?]
+% I guess so.
+
+% \item[\xintseriesname already provides generic tools.] Right, although the
+% casual user of the \xintname bundle will not quite know how to do variable
+% reduction expandably in order to use some series or Pad\'e approximants.
+% Besides I wrote the code at the beginning of the project and perhaps I could
+% do it better now (I have not looked at it for a while). Anyhow, generic things
+% do not help much if one wants to optimize.
+
+% \item[Optimizing? isn't \TeX's macro expansion mechanism intrinsically slow?]
+% Intensive use of \csa{numexpr} and some token manipulation algorithms
+% exploiting to the best I could \TeX{} macros with parameters grant \xintname
+% a significant speed up in expandable arithmetic on big integers compared to
+% previously available implementations. You can do some comparisons with
+% multiplication on numbers with $100$ digits or division of one of $100$
+% digits by another of $50$ digits, for example. However expandability is
+% antagonist of speed, and I agree it is not very exciting to optimize slow
+% things. And I was disappointed last year to realize the slowness of \TeX's
+% mouth when it has to keep hundreds of tokens in cheek to mix them later with
+% new aliments.
+% % https://github.com/latex3/latex3/commit/f46e22cb772ee34aeb2fb200f7907ed3e6192bac
+% %
+%
+% Believe me, I try not to think too much about the fact that the whole
+% enterprise is made irrelevant by Lua\LaTeX's ability to access external
+% libraries.
+
+% \item[Well, why isn't this \texttt{log} etc\dots thing done yet?]
+% I have to decide on the maximal precision to achieve: $24$, $32$, $48$,
+% $64$,\dots ; to settle that I would need to implement some initial versions and
+% benchmark them.
+
+% \item[Fair enough. That's the common lot. So why not yet?] I am a bit
+% overworked. It is also an opportunity to think over
+% the basic underlying mathematics, and will need devoted thinking for some not
+% insignificant amount of time. So far I didn't find the time, or rather I found
+% out good means to waste it sillily. I also anticipate that originality could
+% very
+% well not pay off at all, so small is the window for the precision.
+
+% \item[Any chance this could be done in time for TL2014?] No,
+% sorry.\newline Release |1.09m| of |[2014/02/26]| was the end of a cycle, and
+% this |1.09n| of |[2014/04/01]| is only for a bug fix and inclusion of this
+% |FAQ| in the documentation.
+
+% \footnotesize
+
+% \item[and in time for TL2015?] ... (indistinct mumbles, something like
+% \emph{too tired}, \emph{I need a life}, \emph{get yourself a calculator},
+% \emph{we'll see}\dots)
+% \end{description}
\section{Introduction via examples}
+\label{sec:examples}
The main goal is to allow expandable computations with integers and
fractions of arbitrary sizes.
@@ -3108,188 +3192,6 @@ which can be used to achieve this splitting accross lines, and does work
in inline math mode (however it doesn't allow to separate digits by
groups of three, for example).\par
-\subsection{User interface}
-\label{ssec:userinterface}
-
-The user interface for executing operations on numbers is via macros such as
-\csbxint{Add} or \csbxint{Mul} which have two arguments, or via expressions
-\csbxint{expr}|..\relax| which use infix notations such as |+|, |-|, |*|, |/|
-and |^| (or |**|) for the basic operations, and recognize functions of one or
-more comma separated arguments (such as |max|, or |round|, or |sqrt|),
-parentheses, logic operators of conjunction |&&|, disjunction \verb+||+, as
-well as two-way |?| and three-way |??| conditionals and more. A few examples:
-%
-\begin{everbatim*}
-\begin{enumerate}[nosep]
- \item \xintiiAdd {2719873981798137981381789317981279}{13819093809180120910390190}
- \item \xintiiMul {2719873981798137981381789317981279}{13819093809180120910390190}
- \item \xintthefloatexpr (19317/21913+2198/9291)^3\relax
- \item \xintDigits:=64;\xintthefloatexpr (19317/21913+2198/9291)^3\relax
-% Let's compute the inner sum exactly, not as a float, before raising to third power:
- \item \xintDigits:=16;\xintthefloatexpr \xintexpr 19317/21913+2198/9291\relax^3\relax
-\end{enumerate}
-\end{everbatim*}
-In \csbxint{expr}|..\relax| the contents are expanded completely from left to
-right until the ending |\relax| is found and swallowed, and spaces and even
-(to some extent) catcodes do not matter. Algebraic operations are done
-\emph{exactly}.
-
-The \csbxint{floatexpr} variant is for operations which are done using the
-precision set via the |\xintDigits:=N;| assignment (default is with
-significands of \dtt{16} digits).
-
-For all |\xintexpr| variants, prefixing with |\xintthe| allows to print
-the result or use it in other contexts. Shortcuts \csbxint{theexpr},
-\csbxint{thefloatexpr}, \csbxint{theiiexpr}, \dots\ are available.
-
-The \csbxint{iiexpr} variant is only for big integers, it does not know
-fractions.
-
-There are some important differences of syntax between |\numexpr| and
-|\xintiiexpr| and variants:
-\begin{itemize}
-\item Contrarily to |\numexpr|, the |\xintiiexpr| parser will stop expanding
- only after having encountered (and swallowed) a \emph{mandatory} |\relax|
- token.
-\item In particular, spaces between digits (and not only around infix
- operators or parentheses) do not stop |\xintiiexpr|, contrarily to the
- situation with |numexpr|: |\the\numexpr 7 + 3 5\relax| expands (in one step)
- to \dtt{\detokenize\expandafter{\the\numexpr 7 + 3 5\relax}\unskip}, whereas
- |\xintthe\xintiiexpr 7 + 3 5\relax| expands (in two steps) to
- \dtt{\detokenize\expandafter\expandafter\expandafter {\xintthe\xintiiexpr 7
- + 3 5\relax}}.
- \item Also worth mentioning is the fact that |\numexpr -(1)\relax| is
- illegal. But this is perfectly legal and with the expected result in
- |\xintiiexpr...\relax|.
- \item Inside an |\edef|, expressions |\xintiiexpr...\relax| get fully
- evaluated, but need the prefix |\xintthe| to get printed or used as
- arguments to some macros, whereas expansion of |\numexpr| in an |\edef|
- occurs only if prefixed with |\the| or |\number| (or |\romannumeral|, or
- the expression is included in a bigger
- |\numexpr| which will be the one to have to be prefixed\dots .)
-\end{itemize}
-
-For macros such as \csbxint{Add} or
-\csbxint{Mul} the arguments are each subjected to the process of \fexpan sion:
-repeated expansion of the first token until finding something unexpandable (or
-being stopped by a space token).
-
-Conversely this process of \fexpan sion always provokes the complete expansion
-of the package macros and |\xintexpr..\relax| also will expand completely
-under \fexpan sion, but to a private format; the \csbxint{the} prefix allows the
-computation result either to be passed as argument to one of the package
-macros,\footnote{the \csa{xintthe} prefix \fexpan ds the \csa{xintexpr}-ession
- then unlocks it from its private format; it should not be used for
- sub-expressions inside a bigger one as it is more efficient for the
- expression parser to keep the result in the private format.} or also end up on
-the printed page (or in an auxiliary file).
-To recapitulate, all macros dealing with computations
-\begin{enumerate}
-\item \emph{expand completely under the sole process of repeated expansion of
- the first token, (and two expansions suffice)},\footnote{see in
- \autoref{sec:expansions} for more details.}
-
-\item \emph{apply this \fexpan sion to each one of their arguments.}
-\end{enumerate}
-Hence they can be nested one within the other up to arbitrary
-depths. Conditional evaluations either within the macro arguments themselves, or
-with branches defined in terms of these macros are made possible via macros such
-as as \csbxint{ifSgn} or \csbxint{ifCmp}.
-
-\begin{framed}
- There is no notion of \emph{declaration of a variable} to \xintname,
- \xintfracname, or \xintexprname.
- The user employs the |\def|, |\edef|, or
- |\newcommand| (in \LaTeX) as usual, for example: \IMPORTANT
-%
-\begin{everbatim*}
-\def\x{1729728} \def\y{352827927} \edef\z{\xintMul {\x}{\y}}
-\meaning\z
-\end{everbatim*}\ (see below for the |A/B[N]| output format; with |\xintiiMul|
-in place of |\xintMul| there would not be the strange looking |/1[0]|.)
-
-As a faster alternative to |\edef| (when hundreds of digits are involved), the
-package provides |\oodef| which only expands twice its argument. This provokes
-full expansion of the \xintname \fexpan dable macros (nested to possibly many
-levels), inclusive of |\xintexpr| and variants.
-\end{framed}
-
-\begingroup % pour \z, \zz
-The \xintexprname package has a private internal
-representation for the evaluated computation result. With
-%
-\begin{everbatim*}
-\oodef\z {\xintexpr 3.141^18\relax}
-\end{everbatim*}
-%
-the macro |\z| is already fully evaluated (two expansions were applied, and this
-is enough), and can be reused in other |\xintexpr|-essions, such as for example
-%
-\begin{everbatim*}
-\edef\zz {\xintexpr \z+1/\z\relax}
- % (using short macro names such as \z and \zz is not too recommended in real
- % life, some may have already definitions; I did it all in a group).
-\end{everbatim*}
-%
-But to print it, or to use it as argument to one of the package macros,
-it must be prefixed by |\xintthe| (a synonym for |\xintthe\xintexpr| is
-\csbxint{theexpr}). Application of this |\xintthe| prefix outputs the
-value in the \xintfracname semi-private internal format
-|A/B[N]|,\footnote{there is also the notion of \csbxint{floatexpr}, for
- which the output format after the action of \csa{xintthe} is a number in
- floating point scientific notation.} representing the fraction
-$(A/B)\times 10^N$. The |\zz| above produces a somewhat large output:
-\begin{everbatim*}
-\printnumber{\xintthe\zz }${}\approx{}$\xintFloat{\xintthe\zz}
-\end{everbatim*}
-\endgroup % pour \z, \zz
-
- \begin{framed}
- By default, computations done by the macros of \xintfracname or within
- |\xintexpr..\relax| are exact. Inputs containing decimal points or
- scientific parts do not make the package switch to a `floating-point' mode.
- The inputs, however long, are converted into exact internal representations.
-%
- % Floating point evaluations are done via special macros containing
- % `Float' in their names, or inside |\xintfloatexpr|-essions.
-
- Manipulating exactly big fractions quickly leads to \dots bigger fractions.
- There is a command \csbxint{Irr} (or the function |reduce| in an expression)
- to reduce to smallest terms, but it has to be explicitely requested. Prior
- to release |1.1| addition and subtraction blindly multiplied denominators;
- they now check if one is a multiple of the other.\IMPORTANT\ But systematic
- reduction of the result to its smallest terms would be too
- costly.\def\everbatimindent{0pt }
-\begin{everbatim*}
-\xinttheexpr 27/25+46/50\relax\ is a bit simpler than \xinttheexpr (27*50+25*46)/(25*50)\relax,
-but less so than \xinttheexpr reduce(27/25+46/50)\relax. And \xinttheexpr 3/75+4/50+2/100\relax\
-looks weird, but systematically reducing fractions would be too costly.
-\end{everbatim*}
- \end{framed}
-
-%
-The |A/B[N]| shape is the output format of most \xintfracname macros, it
-benefits from accelerated parsing when used on input, compared to the normal
-user syntax which has no |[N]| part. An example of valid user input for a
-fraction is
-%
-\leftedline{|-123.45602e78/+765.987e-123|}
-%
-where both the decimal parts, the scientific exponent parts, and the whole
-denominator are optional components. The corresponding semi-private form in this
-case would be
-%
-\leftedline{\xintRaw{-123.45602e78/+765.987e-123}}
-%
-The forward slash |/| is simply a delimiter to separate numerator and
-denominator, in order to allow inputs having such denominators.
-
-Reduction to the irreducible form of the output must be asked for explicitely
-via the \csbxint{Irr} macro or the |reduce| function within
-|\xintexpr..\relax|. Elementary operations on fractions do very little of the
-simplifications which could be obvious to (some) human beings.
-
-
\subsection{Randomly chosen examples}
Here are some examples of use of the package macros. The first one uses only
@@ -3307,10 +3209,46 @@ Some inputs are simplified by the use of the \xintexprname package.
|\xintTrunc {1500}{1234/56789}\dots|:
\dtt{\printnumber {\xintTrunc {1500}{1234/56789}}\dots }
-\item {$0.99^{-100}$ with 200 digits after the decimal point:}\\
-|\xinttheexpr trunc(.99^-100,200)\relax\dots|:
-\dtt{\printnumber{\xinttheexpr trunc(.99^-100,200)\relax}\dots }
+\item {$0.99^{-100}$ with 200 (+1) digits after the decimal point.}\\
+ |\xinttheiexpr [201] .99^-100\relax|:
+ \dtt{\printnumber{\xinttheiexpr [201] .99^-100\relax}}\\
+ Notice that this is rounded, hence we asked |\xinttheiexpr| for one
+ additional digit. To get a truncated result with 200 digits after the decimal
+ mark, we should have issued
+ |\xinttheexpr trunc(.99^-100,200)\relax|, rather.
+
+\begin{snugframed}
+ The fraction |0.99^-100|'s denominator is first evaluated \emph{exactly}
+ (\emph{i.e.} the integer |99^100| is evaluated exactly and then used to
+ divide the suitable power of ten to get the requested digits); for
+ some longer inputs, such as for example |0.7123045678952^-243|, the
+ exact evaluation before truncation would be costly, and it is more efficient
+ to use floating point numbers:
+%
+\leftedline{|\xintDigits:=20;
+ \np{\xintthefloatexpr .7123045678952^-243\relax}|}%
+%
+\leftedline{\xintDigits:=20;\dtt{\np{\xintthefloatexpr .7123045678952^-243\relax }}}
+%
+\xintDigits:=16;%
+%
+Side note: the exponent |-243| didn't have to be put inside parentheses,
+contrarily to what happens with some professional computational
+software. |;-)|
+% 6.342,022,117,488,416,127,3 10^35
+% maple n'aime pas ^-243 il veut les parenthèses, bon et il donne, en Digits
+% = 24: 0.634202211748841612732270 10^36
+\end{snugframed}
+
+\item {$200!$:}\\
+|\xinttheiiexpr 200!\relax|:
+\dtt{\printnumber{\xinttheiiexpr 200!\relax}}
+\item {$2000!$ as a float. As \xintexprname does not handle |exp/log| so far,
+ the computation is done internally without the Stirling formula,
+ by repeated multiplications truncated suitably:}\\
+ |\xintDigits:=50;|\newline |\xintthefloatexpr 2000!\relax|:
+ {\xintDigits:=50;\dtt{\printnumber{\xintthefloatexpr 2000!\relax}}}
\item Just to show off (again), let's print 300 digits (after the decimal
point) of the decimal expansion of $0.7^{-25}$:%
@@ -3330,28 +3268,11 @@ Some inputs are simplified by the use of the \xintexprname package.
This computation is with \csbxint{theexpr} from package \xintexprname, which
allows to use standard infix notations and function names to access the package
macros, such as here |trunc| which corresponds to the \xintfracname macro
-\csbxint{Trunc}.
-
-\begin{snugframed}
- The fraction |0.7^-25| is first evaluated \emph{exactly}; for some more
- complex inputs, such as |0.7123045678952^-243|, the exact evaluation before
- truncation would be rather costly, and one would rather use floating point
- numbers:
-%
-\leftedline{|\xintDigits:=20;
- \np{\xintthefloatexpr .7123045678952^-243\relax}|}%
-%
-\leftedline{\xintDigits:=20;\dtt{\np{\xintthefloatexpr .7123045678952^-243\relax }}}
-%
-Side note: the exponent |-243| didn't have to be put inside parentheses,
-contrarily to what happens with some professional computational
-software. |;-)|
-% 6.342,022,117,488,416,127,3 10^35
-% maple n'aime pas ^-243 il veut les parenthèses, bon et il donne, en Digits
-% = 24: 0.634202211748841612732270 10^36
-\end{snugframed}
-
-\xintDigits:=16;
+\csbxint{Trunc}. Regarding this computation, please keep in mind that
+\csbxint{theexpr} computes \emph{exactly} the result before truncating. As
+powers with fractions lead quickly to very big ones, it is good to know that
+\xintexprname also provides \csbxint{thefloatexpr} which does computations
+with floating point numbers.
\item Computation of a Bezout identity with |7^200-3^200| and |2^200-1|:
(with \xintgcdname)\par
@@ -3510,51 +3431,57 @@ digits. This is not so many, let us print them here:
examples in \autoref{sec:expr11}.
\end{itemize}
Almost all of the computational results interspersed throughout the
-documentation are not hard-coded in the source of the document. They are
-the result of evaluation of the package macros, and were selected to not
-impact too much the compilation time of this documentation.
-Nevertheless, there are so many computations done that compilation time
-is significantly increased compared to a \LaTeX\ run on a typical
-document of about the same size.
-
-\section{The \xintname bundle}
+documentation are not hard-coded in the source file of this document but are
+obtained via the expansion of the package macros during the \TeX{}
+run.%
+%
+\footnote{The CPU of my computer hates me for all those re-compilations
+ after changing a single letter in the \LaTeX{} source, which require each
+ time to do all the zillions of evaluations contained in this document\dots}
+%
+% on examples which were selected to not impact too much the compilation time of
+% this documentation.
-\subsection{General overview}
+% Nevertheless, there are so many computations done that compilation time
+% is significantly increased compared to a \LaTeX\ run on a typical
+% document of about the same size.
-The main characteristics are:
-\begin{enumerate}
-\item exact algebra on arbitrarily big numbers, integers as well as fractions,
-\item floating point variants with user-chosen precision,
-\item implemented via macros compatible with expansion-only
- context.
-\end{enumerate}
+\section{The \xintname bundle}
-`Arbitrarily big' means with less than
- |2^31-1|\dtt{=\number"7FFFFFFF} digits, as most of the macros will
- have to compute the length of the inputs and these lengths must be treatable
- as \TeX{} integers, which are at most \dtt{\number "7FFFFFFF}
- in absolute value.
- This is a distant irrelevant upper bound, as no such thing can fit
- in \TeX's memory! The \emph{time} taken up by the expansion only
- mechanisms is a much more stringent constraint.
+\subsection{Characteristics}
\begin{framed}
- The reasonable range is for operations with numbers of up to about
- (integer+decimal part) \dtt{100} digits.
+ The main characteristics are:
+ \begin{enumerate}
+ \item exact algebra on arbitrarily big numbers, integers as well as
+ fractions,
+ \item floating point variants with user-chosen precision,
+ \item implemented via macros compatible with expansion-only context,
+ \item and with a parser of infix operations implementing features such as
+ dummy variables, and coming in various incarnations depending on the kind
+ of computation desired: purely on integers, on integers and fractions, or
+ on floating point numbers.
+ \end{enumerate}
+
+ `Arbitrarily big' currently means with less than about \dtt{19950} digits: the
+ maximal%
+ \MyMarginNote[\kern\dimexpr\FrameSep+\FrameRule\relax]{Changed!}
+ number of digits for addition is at \dtt{19968} digits,
+ and it is \dtt{19959} for multiplication.
\end{framed}
-As just recalled, ten-digits integers starting with a $3$ already exceed the
-\TeX{} bound; and \TeX{} does not have a native processing of
-floating point numbers (multiplication by a decimal number of a dimension
-register is allowed --- this is used for example by the
-\href{http://mirror.ctan.org/graphics/pgf/base}{pgf} basic math
-engine.)
+Integers with only $10$ digits and starting with a $3$ already exceed the
+\TeX{} bound; and \TeX{} does not have a native processing of floating point
+numbers (multiplication by a decimal number of a dimension register is allowed
+--- this is used for example by the
+\href{http://mirror.ctan.org/graphics/pgf/base}{pgf} basic math engine.)
\TeX{} elementary operations on numbers are done via the non-expandable
-\emph{advance, multiply, \emph{and} divide} assignments. This was changed with
-\eTeX{}'s |\numexpr| which does expandable computations using standard infix
-notations with \TeX{} integers. But \eTeX{} did not modify the \TeX{} bound on
-acceptable integers, and did not add floating point support.
+\emph{\char92advance, \char92multiply, \emph{and} \char92divide} assignments.
+This was changed with \eTeX{}'s |\numexpr| which does expandable computations
+using standard infix notations with \TeX{} integers. But \eTeX{} did not
+modify the \TeX{} bound on acceptable integers, and did not add floating point
+support.
The \href{http://www.ctan.org/pkg/bigintcalc}{bigintcalc} package by
\textsc{Heiko Oberdiek} provided expandable operations (using some of |\numexpr|
@@ -3581,81 +3508,73 @@ ${}^{\text{,\,}}$%
The \LaTeX3 project has implemented expandably floating-point computations with
16 significant figures
(\href{http://www.ctan.org/pkg/l3kernel}{l3fp}), including
-special functions such as exp, log, sine and cosine.%
-%
-\footnote{at the time of writing (2014/10/28) the
+special functions such as exp, log, sine and cosine.\footnote{at the time of writing (2014/10/28) the
\href{http://www.ctan.org/pkg/l3kernel}{l3fp} (exactly represented) floating
point numbers have their exponents limited to $\pm$\dtt{9999}.}
%
-There is
-also \liiibigint, which is part of the experimental trunk of the
-\href{http://latex-project.org}{\LaTeX3 Project}. Like
-\href{http://www.ctan.org/pkg/bigintcalc}{bigintcalc} and \xintname it
-provides macros for big integer arithmetics. All three implementations of the
-basic arithmetic macros can be mapped to easier infix notations via the
-services of the \href{http://www.ctan.org/pkg/bnumexpr}{bnumexpr}
-package.
-%
-\footnote{2015/09/15: the currently available \liiibigint{} is not compatible
- with the current latest \href{http://www.ctan.org/pkg/bnumexpr}{bnumexpr}
- release (1.1b 2014/10/28).}
-
-The \xintname package can be used for $24$, $40$, etc\dots{} significant figures
-but one rather quickly (not much beyond $100$ figures) hits against a
-`wall' created by the constraint of expandability: currently, multiplying out
-two one-hundred digits numbers takes circa $80$ or $90$ times longer than for
-two ten-digits numbers, which is reasonable, but multiplying out two
-one-thousand digits numbers takes more than $500$ times longer than for two one
-hundred-digits numbers. This shows that the algorithm is drifting from quadratic
-to cubic in that range. On my laptop multiplication of two $1000$-digits numbers
-takes some seconds, so it can not be done routinely in a
-document.%
-%
-\footnote{2013/06/07: without entering into too much technical details, the
- source of this `wall' is that when dealing with two long operands, when one
- wants to pick some digits from the second one, one has to jump above all
- digits constituting the first one, which can not be stored away:
- expandability forbids assignments to memory storage. One may envision some
- sophisticated schemes, dealing with this problem in less naive ways, trying
- to move big chunks of data higher up in the input stream and come back to it
- later, etc...; but each `better' algorithm adds overhead for the smaller
- inputs. For example, I have another version of addition which is twice
- faster on inputs with 500 digits or more, but it is slightly less efficient
- for 50 digits or less. This `wall' dissuaded me to look into implementing
- `intelligent' multiplication which would be sub-quadratic in a model where
- storing and retrieving from memory would not cost much.}
-\footnote{\textbf{2015/09/15:} the new \liiibigint{} has brilliantly
- successfully implemented Karatsuba multiplication, solving the issue faced
- by xint in 2013 (the method is based on a clever preparation of the inputs
- into a form which allows precisely a ``sophisticated scheme'' as above on
- where to locate the data to be manipulated and it has I presume the cost, as
- described above, of a slight overhead for small numbers -- but I did not
- test that point): the speed gain compared to xint for multiplication of
- numbers of about $1000$ digits is about $20x$; for numbers of $100$ digits
- \liiibigint{} is only a bit faster than \xintcorename; for small numbers
- \xintcorename is probably (not tested) a bit faster. See also
- \autoref{fn:l3bigint2015}.}
-
-The conclusion perhaps could be that it is in the end lucky that the speed gains
-brought by \xintname for expandable operations on big numbers do open some
-non-empty range of applicability in terms of the number of kept digits for
-routine floating point operations.
-
-The second conclusion, somewhat depressing after all the hard work, is that if
-one really wants to do computations with \emph{hundreds} of digits, one should
-drop the expandability requirement. Indeed, as clearly demonstrated long ago
-by the \href{http://www.ctan.org/pkg/pi}{pi computing file} by \textsc{D.
- Roegel} one can program \TeX{} to compute with many digits at a much higher
-speed than what \xintname achieves: but, direct access to memory storage in
-one form or another seems a necessity for this kind of speed and one has to
-renounce at the complete expandability.\footnote{2015/09/15: the latest
- developments on the \liiibigint{} side do not really modify this conclusion,
- because the computations remain extremely slow compared to what one can do
- in other programming structures, and also slow in comparison to what one
- could do non-expandably in \TeX{} (although I know to this day no available
- macro package which has done this successfully for big integer arithmetics;
- perhaps I am too optimistic with respect to what one can achieve without the
- burden of expandability?).
+
+More directly related to the \xintname bundle, there is the promising new
+version of the \liiibigint{} package. It was still in development a.t.t.o.w
+(2015/10/09, no division yet) and is part of the experimental trunk of the
+\href{http://latex-project.org}{\LaTeX3 Project}. It is devoted to expandable
+computations on big integers with an associated expression parser. Its author
+(Bruno \textsc{Le Floch}) succeeded brilliantly into implementing expandably
+the Karatsuba multiplication algorithm and he achieves \emph{sub-quadratic
+ growth for the computation time}. This shows up very clearly with numbers
+having more than one thousand digits (up to the maximum which a.t.t.o.w was at
+$8192$ digits).
+
+I report here briefly on a quick comparison, although as \liiibigint{} is work
+in progress, the reported results could well have to be modified soon. The
+test was on a comparison of |\bigint_eval:n {#1*#2}| from the \liiibigint{} as
+available in September 2015, on one hand, and on the other hand
+|\xinttheiiexpr #1*#2\relax| from \xintexprname 1.2 (rather than directly
+|\xintiiMul|, to be fairer to the parsing time induced by use of
+|\bigint_eval:n|) and the computations were done with
+|#1=#2=9999888877999988877...repeated...|. I observed:
+\begin{itemize}
+\item \csbxint{iiexpr}'s multiplication appears slightly faster (about |1.5x|
+ or |2x| to give an average order of magnitude) up to about
+ $900$ digits,
+\item at $1000$ digits, \liiibigint{} runs between |15%| and |20%| faster,
+\item then its sub-quadratic growth shows up, and at $8000$ digits I observed
+ it to be about |7.6x| faster (I tried on two computers and on my laptop the
+ ratio was more like |8.5x--9x|). Its computation time increased from $1000$
+ digits to $8000$ digits by a factor smaller than |30|, whereas for
+ \csbxint{iiexpr} it was a factor only slightly inferior to |200| (|225| on
+ my laptop) ...
+ Karatsuba multiplication brilliantly pays off !
+\item One observes the transition at the powers of two for the \liiibigint{}
+ algorithm, for example I observed \liiibigint{} to be |3.5x| faster at
+ $4000$ digits but only |3.1x| faster at $5000$ digits.
+\end{itemize}
+
+Once one accepts a small overhead, one can on the basis of the lengths decide
+for the best algorithm to use, and it is tempting viewing the above to imagine
+that some mixed approach could combine the best of both. But again all this is
+a bit premature as both packages may still evolve further.
+
+Anyhow, all this being said, even the superior multiplication implementation
+from \liiibigint{} takes of the order of seconds on my laptop for a single
+multiplication of two $5000$-digits numbers. Hence it is not possible to do
+routinely such computations in a document. I have long been thinking that
+without the expandability constraint much higher speeds could be achieved, but
+perhaps I have not given enough thought to sustain that optimistic
+stance.\footnote{The \href{http://www.ctan.org/pkg/apnum}{apnum} package
+ implements non-expandably arbitrary precision arithmetic operations.}
+
+I remain of the opinion that if one really wants to do computations with
+\emph{thousands} of digits, one should drop the expandability requirement.
+Indeed, as clearly demonstrated long ago by the
+\href{http://www.ctan.org/pkg/pi}{pi computing file} by \textsc{D. Roegel} one
+can program \TeX{} to compute with many digits at a much higher speed than
+what \xintname achieves: but, direct access to memory storage in one form or
+another seems a necessity for this kind of speed and one has to renounce at
+the complete expandability.%
+%
+\footnote{2015/09/15: as I said the latest developments on the \liiibigint{}
+ side do not really modify this conclusion, because the computations remain
+ extremely slow compared to what one can do in other programming structures.
Another remark one could do is that it would be tremendously easier to
enhance \eTeX{} than it is to embark into writing hundreds of lines of
sometimes very clever \TeX{} macro programming.}
@@ -3712,9 +3631,16 @@ for \csa{numexpr} has ten digits).
The present package is the result of this initial questioning.
-% \begin{framed}\centering
-% \xintname requires the \eTeX{} extensions.
-% \end{framed}
+For the record, \xintname 1.2 also got its impulse from a fast ``reversing''
+macro, which I wrote after my interest got awakened again as a result of
+correspondance with Bruno \textsc{Le Floch}: this new reverse uses a \TeX nique
+which \emph{requires} the tokens to be digits. I wrote a routine which works
+(expandably) in quasi-linear time, but a less fancy |O(N^2)| variant which I
+developed concurrently proved to be faster all the way up to perhaps $7000$
+digits, thus I dropped the quasi-linear one. The less fancy variant has the
+advantage that \xintname can handle numbers with more than $19900$ digits (but
+not much more than $19950$). This is with the current common values of the input
+save stack and maximal expansion depth: $5000$ and $10000$ respectively.
\subsection{Expansion matters}
\label{sec:expansions}
@@ -3893,47 +3819,195 @@ such expandable macros:
creates the |\AplusBC| macro doing the above and expanding in two expansion
steps.
-\subsection{Efficiency; floating point macros}
-
-The size of the manipulated numbers is limited by two
-factors:\footnote{there is an intrinsic limit of
- \dtt{\number"7FFFFFFF} on the number of digits, but it is
- irrelevant, in view of the other limiting factors.} (1.)~\emph{the
-available memory as configured in the |tex| executable},
-(2.)~\emph{the \emph{time} necessary to fully expand the computations
- themselves}.
-I discovered progressively, during the first few weeks of developing the
-package, that the most limiting factor is the second one, the time
-needed for multiplication, division (even more for powers). It
-explodes with increasing input sizes long before the computations could
-get limited by constraints on \TeX's available memory:
-computations with $100$ digits are still reasonably fast, but the
-situation then deteriorates swiftly and multiplication with $1000$
-digits takes some seconds.%
-%
-\footnote{Perhaps some faster routines could emerge from an approach
- which, while maintaining expandability would renounce at \fexpan
- dability (without impacting the input save stack). There is one such
- routine \csbxint{XTrunc} which is able to write to a file (or inside
- an \csa{edef}) tens of thousands of digits of a (reasonably-sized)
- fraction.}
-%
-\footnote{\textbf{2015/09/15}: faster routines for numbers with more than
- (about) $100$ digits (for multiplication) are part of a new (experimental)
- release \liiibigint{}. It succeeds in implementing Karatsuba multiplication
- (division yet to be done) and this drastically improves the dependency of
- time upon size. See \autoref{fn:l3bigint2015}. Some technical limitations
- of \TeX{} (which can be lifted from recompiling the binary with changed
- settings) currently limit the range to up to $8192$ digits. Nevertheless
- multiplication with $5000$ digits takes about the same time as what
- \xintcorename achieves for $1000$ digits, \emph{i.e.} some seconds on my
- computer. Although the usable range of \liiibigint{} thus goes well into the
- hundreds of digits, which improves greatly on the \xintcorename
- implementation of multiplication (up to some overhead for numbers of a few
- dozen digits), here also computation times become dissuasive far before the
- \TeX{} main memory would be saturated.}
-
-To address this issue, floating
+\subsection{User interface}
+\label{ssec:userinterface}
+
+The user interface for executing operations on numbers is via macros such as
+\csbxint{Add} or \csbxint{Mul} which have two arguments, or via expressions
+\csbxint{expr}|..\relax| which use infix notations such as |+|, |-|, |*|, |/|
+and |^| (or |**|) for the basic operations, and recognize functions of one or
+more comma separated arguments (such as |max|, or |round|, or |sqrt|),
+parentheses, logic operators of conjunction |&&|, disjunction \verb+||+, as
+well as two-way |?| and three-way |??| conditionals and more. A few examples:
+%
+\begin{everbatim*}
+\begin{enumerate}[nosep]
+ \item \xintiiAdd {2719873981798137981381789317981279}{13819093809180120910390190}
+ \item \xintiiMul {2719873981798137981381789317981279}{13819093809180120910390190}
+ \item \xintthefloatexpr (19317/21913+2198/9291)^3\relax
+ \item \xintDigits:=64;\xintthefloatexpr (19317/21913+2198/9291)^3\relax
+% Let's compute the inner sum exactly, not as a float, before raising to third power:
+ \item \xintDigits:=16;\xintthefloatexpr \xintexpr 19317/21913+2198/9291\relax^3\relax
+\end{enumerate}
+\end{everbatim*}
+In \csbxint{expr}|..\relax| the contents are expanded completely from left to
+right until the ending |\relax| is found and swallowed, and spaces and even
+(to some extent) catcodes do not matter. Algebraic operations are done
+\emph{exactly}.
+
+The \csbxint{floatexpr} variant is for operations which are done using the
+precision set via the |\xintDigits:=N;| assignment (default is with
+significands of \dtt{16} digits).
+
+For all |\xintexpr| variants, prefixing with |\xintthe| allows to print
+the result or use it in other contexts. Shortcuts \csbxint{theexpr},
+\csbxint{thefloatexpr}, \csbxint{theiiexpr}, \dots\ are available.
+
+The \csbxint{iiexpr} variant is only for big integers, it does not know
+fractions.
+
+There are some important differences of syntax between |\numexpr| and
+|\xintiiexpr| and variants:
+\begin{itemize}
+\item Contrarily to |\numexpr|, the |\xintiiexpr| parser will stop expanding
+ only after having encountered (and swallowed) a \emph{mandatory} |\relax|
+ token.
+\item In particular, spaces between digits (and not only around infix
+ operators or parentheses) do not stop |\xintiiexpr|, contrarily to the
+ situation with |numexpr|: |\the\numexpr 7 + 3 5\relax| expands (in one step)
+ to \dtt{\detokenize\expandafter{\the\numexpr 7 + 3 5\relax}\unskip}, whereas
+ |\xintthe\xintiiexpr 7 + 3 5\relax| expands (in two steps) to
+ \dtt{\detokenize\expandafter\expandafter\expandafter {\xintthe\xintiiexpr 7
+ + 3 5\relax}}.
+ \item Also worth mentioning is the fact that |\numexpr -(1)\relax| is
+ illegal. But this is perfectly legal and with the expected result in
+ |\xintiiexpr...\relax|.
+ \item Inside an |\edef|, expressions |\xintiiexpr...\relax| get fully
+ evaluated, but need the prefix |\xintthe| to get printed or used as
+ arguments to some macros, whereas expansion of |\numexpr| in an |\edef|
+ occurs only if prefixed with |\the| or |\number| (or |\romannumeral|, or
+ the expression is included in a bigger
+ |\numexpr| which will be the one to have to be prefixed\dots .)
+\end{itemize}
+
+For macros such as \csbxint{Add} or
+\csbxint{Mul} the arguments are each subjected to the process of \fexpan sion:
+repeated expansion of the first token until finding something unexpandable (or
+being stopped by a space token).
+
+Conversely this process of \fexpan sion always provokes the complete expansion
+of the package macros and |\xintexpr..\relax| also will expand completely
+under \fexpan sion, but to a private format; the \csbxint{the} prefix allows the
+computation result either to be passed as argument to one of the package
+macros,\footnote{the \csa{xintthe} prefix \fexpan ds the \csa{xintexpr}-ession
+ then unlocks it from its private format; it should not be used for
+ sub-expressions inside a bigger one as it is more efficient for the
+ expression parser to keep the result in the private format.} or also end up on
+the printed page (or in an auxiliary file).
+To recapitulate, all macros dealing with computations
+\begin{enumerate}
+\item \emph{expand completely under the sole process of repeated expansion of
+ the first token, (and two expansions suffice)},\footnote{see in
+ \autoref{sec:expansions} for more details.}
+
+\item \emph{apply this \fexpan sion to each one of their arguments.}
+\end{enumerate}
+Hence they can be nested one within the other up to arbitrary
+depths. Conditional evaluations either within the macro arguments themselves, or
+with branches defined in terms of these macros are made possible via macros such
+as as \csbxint{ifSgn} or \csbxint{ifCmp}.
+
+\begin{framed}
+ There is no notion of \emph{declaration of a variable} to \xintname,
+ \xintfracname, or \xintexprname.
+ The user employs the |\def|, |\edef|, or
+ |\newcommand| (in \LaTeX) as usual, for example: \IMPORTANT
+%
+\begin{everbatim*}
+\def\x{1729728} \def\y{352827927} \edef\z{\xintMul {\x}{\y}}
+\meaning\z
+\end{everbatim*}\ (see below for the |A/B[N]| output format; with |\xintiiMul|
+in place of |\xintMul| there would not be the strange looking |/1[0]|.)
+
+The package provides |\oodef| which only expands twice its argument. This
+provokes full expansion of the \xintname macros (nested to possibly many
+levels), inclusive of |\xintexpr| and variants. However, it is typically slower
+then |\edef| (and quite slower for small things) when the expansion ends up
+consisting of less than about one thousand digits. The second utility next to
+|\oodef| is |\fdef| which applies full expansion upfront and appears to be
+competitive with and even faster than |\edef| already in the case of expansion
+leading to a few dozen digits.
+\end{framed}
+
+\begingroup % pour \z, \zz
+The \xintexprname package has a private internal
+representation for the evaluated computation result. With
+%
+\begin{everbatim*}
+\edef\z {\xintexpr 3.141^18\relax}
+\end{everbatim*}
+%
+the macro |\z| is already fully evaluated (two expansions were applied, and this
+is enough), and can be reused in other |\xintexpr|-essions, such as for example
+%
+\begin{everbatim*}
+\edef\zz {\xintexpr \z+1/\z\relax}
+ % (using short macro names such as \z and \zz is not too recommended in real
+ % life, some may have already definitions; I did it all in a group).
+\end{everbatim*}
+%
+But to print it, or to use it as argument to one of the package macros,
+it must be prefixed by |\xintthe| (a synonym for |\xintthe\xintexpr| is
+\csbxint{theexpr}). Application of this |\xintthe| prefix outputs the
+value in the \xintfracname semi-private internal format
+|A/B[N]|,\footnote{there is also the notion of \csbxint{floatexpr}, for
+ which the output format after the action of \csa{xintthe} is a number in
+ floating point scientific notation.} representing the fraction
+$(A/B)\times 10^N$. The |\zz| above produces a somewhat large output:
+\begin{everbatim*}
+\printnumber{\xintthe\zz }${}\approx{}$\xintFloat{\xintthe\zz}
+\end{everbatim*}
+\endgroup % pour \z, \zz
+
+ \begin{framed}
+ By default, computations done by the macros of \xintfracname or within
+ |\xintexpr..\relax| are exact. Inputs containing decimal points or
+ scientific parts do not make the package switch to a `floating-point' mode.
+ The inputs, however long, are converted into exact internal representations.
+%
+ % Floating point evaluations are done via special macros containing
+ % `Float' in their names, or inside |\xintfloatexpr|-essions.
+
+ Manipulating exactly big fractions quickly leads to \dots bigger fractions.
+ There is a command \csbxint{Irr} (or the function |reduce| in an expression)
+ to reduce to smallest terms, but it has to be explicitely requested. Prior
+ to release |1.1| addition and subtraction blindly multiplied denominators;
+ they now check if one is a multiple of the other.\IMPORTANT\ But systematic
+ reduction of the result to its smallest terms would be too
+ costly.\def\everbatimindent{0pt }
+\begin{everbatim*}
+\xinttheexpr 27/25+46/50\relax\ is a bit simpler than \xinttheexpr (27*50+25*46)/(25*50)\relax,
+but less so than \xinttheexpr reduce(27/25+46/50)\relax. And \xinttheexpr 3/75+4/50+2/100\relax\
+looks weird, but systematically reducing fractions would be too costly.
+\end{everbatim*}
+ \end{framed}
+
+%
+The |A/B[N]| shape is the output format of most \xintfracname macros, it
+benefits from accelerated parsing when used on input, compared to the normal
+user syntax which has no |[N]| part. An example of valid user input for a
+fraction is
+%
+\leftedline{|-123.45602e78/+765.987e-123|}
+%
+where both the decimal parts, the scientific exponent parts, and the whole
+denominator are optional components. The corresponding semi-private form in this
+case would be
+%
+\leftedline{\xintRaw{-123.45602e78/+765.987e-123}}
+%
+The forward slash |/| is simply a delimiter to separate numerator and
+denominator, in order to allow inputs having such denominators.
+
+Reduction to the irreducible form of the output must be asked for explicitely
+via the \csbxint{Irr} macro or the |reduce| function within
+|\xintexpr..\relax|. Elementary operations on fractions do very little of the
+simplifications which could be obvious to (some) human beings.
+
+
+\subsection{Floating point macros}
+
+Floating
point macros are provided to work with a given arbitrary precision. The default
size for significands is $16$ digits. Working with significands of $24$, $32$,
$48$, $64$, or even $80$ digits is well within the reach of the package. But
@@ -3947,6 +4021,22 @@ values up to $32767$.\footnote{for a one-shot conversion of a fraction to float
overflow may occur if the exponents are a bit too close to the \TeX{} bound
\dtt{$\pm$\number"7FFFFFFF}.}
+\begin{framed}
+ Currently, the only transcendental operation is the square root
+ (\csbxint{FloatSqrt}). The elementary functions are not yet implemented. The
+ power function (\csbxint{FloatPow}, \csbxint{FloatPower}) accept only
+ (positive or negative) integer exponents.
+\end{framed}
+
+\begin{framed}
+ Floating point multiplication of two numbers with |P| digits of precision
+ evaluates \emph{exactly} the exact product with |2P| or |2P-1| digits,
+ before rounding to |P| digits: obviously this is very wasteful when |P| is
+ large. But \xintname is initially an exact algebraic operator, not a
+ floating point one with a fixed maximal size for operands, and the author
+ hasn't yet had the opportunity to re-examine that point.
+\end{framed}
+
Here is such a floating point computation:
%
\leftedline{|\xintFloatPower [48] {1.1547}{\xintiiPow {2}{35}}|}
@@ -3993,25 +4083,40 @@ exponents.
\section{User interface}
-Maintaining complete expandability is not for the faint of heart as it excludes
-doing macro definitions in the midst of the computation; in many cases, one does
-not need complete expandability, and definitions are allowed. In such contexts,
-there is no declaration for the user to be made to the package of a ``typed
-variable'' such as a long integer, or a (long) fraction, or possibly an
-|\xintexpr|-ession. Rather, the user has at its disposal the general tools of
-the \TeX{} language: |\def| and |\edef|. In \LaTeX\ there is |\newcommand| as
-wrapper to |\def|,
-but \LaTeX\ chose not to provide an analogous wrapper for |\edef|. It can still
-be used directly of course.\footnote{I don't know if \LaTeX3 will still allow
- direct use of |\def| and |\edef|\dots}
-
-The \xinttoolsname package provides |\oodef| which expands twice the replacement
-text\footnote{only for parameter less undelimited macros.}, hence forces
-complete expansion when the top level of this replacement
-text is a call to one of the \xintname bundle macros, its arguments being
-themselves chains of such macros. There is also |\fdef| which will apply \fexpan
-sion to the replacement text. Both are in such uses faster alternatives to
-|\edef|.
+{\etocdefaultlines\etocsettocstyle{}{}\localtableofcontents}
+
+
+% Je ne sais pas ce que faisait ce paragraphe ici:
+%
+% Maintaining complete expandability is not for the faint of heart as it excludes
+% doing macro definitions in the midst of the computation; in many cases, one does
+% not need complete expandability, and definitions are allowed. In such contexts,
+% there is no declaration for the user to be made to the package of a ``typed
+% variable'' such as a long integer, or a (long) fraction, or possibly an
+% |\xintexpr|-ession. Rather, the user has at its disposal the general tools of
+% the \TeX{} language: |\def| and |\edef|. In \LaTeX\ there is |\newcommand| as
+% wrapper to |\def|,
+% but \LaTeX\ chose not to provide an analogous wrapper for |\edef|. It can still
+% be used directly of course.\footnote{I don't know if \LaTeX3 will still allow
+% direct use of |\def| and |\edef|\dots}
+
+%%%%%%%%%%%%% pas le bon endroit pour cette discussion
+% The \xinttoolsname package provides |\oodef|, resp. |\fdef|, which expands
+% twice, resp. fully (\fexpan sion), the replacement text\footnote{only for
+% parameter less undelimited macros.}, hence forces complete expansion when
+% this replacement text is a call to one of the \xintname bundle macros, its
+% arguments being either explicit digits or further such macro calls. They are
+% useful as sometimes one does not want |\edef| expansion, \emph{e.g.} with a
+% macro such as \csbxint{Trim} which acts on lists of braced tokens which one
+% might not want to see expanded. Furthermore |\fdef| appears to be faster than
+% |\edef| in (non-trivial) situations already with only a few dozens of digits: I
+% tested it to be a bit faster than |\edef| for expanding |\xintiiPow {2}{100}|
+% (which has $31$ digits). However |\oodef| needs thousands of digits to become
+% competitive.%
+% %
+% \footnote{earlier releases of this manual sort of suggested \csa{oodef} was
+% competitive starting with a ``few hundred'' digits but that was perhaps a bit
+% optimistic. The better choice is \csa{fdef}.}
This section will explain the various inputs which are recognized by the package
macros and the format for their outputs. Inputs have mainly five possible
@@ -4046,13 +4151,8 @@ Outputs are mostly of the following types:
or be used as argument to the package macros.
\end{enumerate}
-{\etocdefaultlines\etocsettocstyle{}{}\localtableofcontents}
-
\subsection {Input formats}\label{sec:inputs}
-% \edef\z {\xintAdd
-% {+--0367.8920280/-++278.289287}{-109.2882/+270.12898}}
-
Some macro arguments are by nature `short' integers,\ntype{\numx} \emph{i.e.}
less than (or equal to) in absolute value \np{\number "7FFFFFFF}. This is
generally the case for arguments which serve to count or index something. They
@@ -4065,13 +4165,13 @@ the allowed input formats for `long numbers' and `fractions' are:
\begin{enumerate}
\item the strict format\ntype{f} is for some macros of \xintname which only
\fexpan d their arguments. After this \fexpan sion the input should be a
- string of digits, optionally preceded by a unique minus sign. The first digit
- can be zero only if the number is zero. A plus sign is not accepted. |-0| is
- not legal in the strict format. A count register can serve as argument of such
- a macro only if prefixed by |\the| or |\number|. Most macros of \xintname are
- like \csbxint{Add} and accept the extended format described in the next item;
- they may have a `strict' variant such as \csbxint{iiAdd} which remains
- available even with \xintfracname loaded, for optimization purposes.
+ string of digits, optionally preceded by a unique minus sign. The first
+ digit can be zero only if the number is zero. A plus sign is not accepted.
+ |-0| is not legal in the strict format. A count register can serve as
+ argument of such a macro only if prefixed by |\the| or |\number|. Macros of
+ \xintname such as \csbxint{iiAdd} with a double |ii| require this `strict'
+ format for the inputs. The macros such as \csbxint{iAdd} with a single |i|
+ will apply the \csbxint{Num} normalizer described in the next item.
\item the macro \csbxint{Num} normalizes into strict format an input having
arbitrarily many minus and plus signs, followed by a string of zeroes, then
@@ -4086,37 +4186,63 @@ the allowed input formats for `long numbers' and `fractions' are:
\csbxint{Num}.%
%
\footnote{A
- \LaTeX{} \texttt{\char 92value\{countername\}} is accepted as macro
+ \LaTeX{} |\value{countername}| is accepted as macro
argument.}
-\item the fraction format\ntype{\Ff} is what is expected by the macros of
- \xintfracname: a fraction is constituted of a numerator |A| and optionally a
- denominator |B|, separated by a forward slash |/| and |A| and |B| may be
- macros which will be automatically given to \csbxint{Num}. Each of |A| and |B|
- may be decimal numbers (the decimal mark must be a |.|). Here is an
- example:%
- %
- \footnote{the square brackets one sees in various outputs are
- explained
- near the end of this section.} %
- %
- \leftedline{|\xintAdd
- {+--0367.8920280/-++278.289287}{-109.2882/+270.12898}|}
- %
- Scientific notation is accepted for both numerator and denominator of a
- fraction, and is produced on output by \csbxint{Float}:
- %
- \begin{quote}
- |\xintAdd{10.1e1}{101.010e3}|\dtt{=\xintAdd{10.1e1}{101.010e3}}\\
- %
- |\xintFloatAdd{10.1e1}{101.010e3}|\dtt{=\xintFloatAdd{10.1e1}{101.010e3}}\\
- %
- |\xintPow {2}{100}|\dtt{=\xintPow {2}{100}}\\
- %
- |\xintFloat{\xintPow {2}{100}}|\dtt{=\xintFloat{\xintPow {2}{100}}}\\
- %
- |\xintFloatPow {2}{100}|\dtt{=\xintFloatPow {2}{100}}
- \end{quote}
+\item the fraction format\ntype{\Ff} is what is expected on input by the
+ macros of \xintfracname. It has two variants:
+ \begin{description}
+ \item[general:] these are inputs of the shape |A.BeC/D.EeF|. Example:
+\begin{everbatim*}
+\noindent\xintRaw{+--0367.8920280e17/-++278.289287e-15}\newline
+\xintRaw{+--+1253.2782e++--3/---0087.123e---5}\par
+\end{everbatim*}
+ Notice that the input process does not reduce fractions to smallest terms.
+ Here are the rules of the format:\footnote{Earlier releases were slightly
+ more strict, the optional decimal parts |B|, |E| were not individually
+ \fexpan ded.}
+ \begin{itemize}
+ \item everything is optional, absent numbers are treated as zero, here are
+ some extreme cases:
+\begin{everbatim*}
+\xintRaw{}, \xintRaw{.}, \xintRaw{./1.e}, \xintRaw{-.e}, \xintRaw{e/-1}
+\end{everbatim*}
+ \item |AB| and |DE| may start with pluses and minuses, then leading
+ zeroes, then digits.
+ \item |C| and |F| will be given to |\numexpr| and can be anything
+ recognized as such and not provoking arithmetic overflow (the lengths of
+ |B| and |E| will also intervene to build the final exponent naturally
+ which must obeys the \TeX{} bound).
+ \item the |/|, |.| (numerator and/or denominator) and |e|
+ (numerator and/or denominator) are all optional components.
+ \item each of |A|, |B|, |C|, |D|, |E| and |F| may arise from \fexpan sion
+ of a macro.
+ \item the whole thing may arise from \fexpan sion, however the |/|, |.|,
+ and |e| should all come from this initial expansion. The |e| of
+ scientific notation is mandatorily lowercased.
+ \end{itemize}
+ \item[restricted:] these are inputs either of the shape |A[N]| or |A/B[N]|
+ (representing the fraction |A/B| times |10^N|) where the whole thing or
+ each of |A|, |B|, |N| (but then not |/| or |[|) may arise from \fexpan
+ sion, |A| (after expansion) \emph{must} have a unique optional minus sign
+ and no leading zeroes, |B| (after expansion) if present \emph{must} be a
+ positive integer with no signs and no leading zeroes, |N| (which may be
+ empty) will be given to |\numexpr|. This format is parsed with smaller
+ overhead than the general one, thus allowing more efficient nesting of
+ macros as it is the one used on output (except for the floating macros).
+ Any deviation from the rules above will result in errors.\footnote{With
+ earlier releases the |N| could not be empty and had to be given as
+ explicit digits, not some macro or expression expanded in |\numexpr|.}
+ \end{description}
+ Examples of inputs and outputs:
+\begin{everbatim*}
+ \xintAdd{+--0367.8920280/-++278.289287}{-109.2882/+270.12898}\newline
+ \xintAdd{10.1e1}{101.010e3}\newline
+ \xintFloatAdd{10.1e1}{101.010e3}\newline
+ \xintiiPow {2}{100}\newline
+ \xintPow {2}{100}\newline
+ \xintFloatPow {2}{100}\par
+\end{everbatim*}
%
Produced fractions having a denominator equal to one are, as a general
rule, nevertheless printed as fractions. In math mode \csbxint{Frac}
@@ -4131,45 +4257,55 @@ the allowed input formats for `long numbers' and `fractions' are:
\item the \hyperref[xintexpr]{expression format} is for inclusion in an
\csbxint{expr}|...\relax|, it uses infix notations, function names, complete
- expansion, and is described in \autoref{sec:expr11} and \autoref{sec:expr}.
+ expansion, recognizes decimal and scientific numbers, and is described in
+ \autoref{sec:expr11} and \autoref{sec:expr}.%
+%
+\footnote{The isolated dot |"."| is not legal anymore\MyMarginNote{Changed!} in expressions with
+ release |1.2|: there must be digits either before or after.}
\end{enumerate}
+Even with \xintfracname loaded, some macros by their nature cannot accept
+fractions on input. Those parsing their inputs through \csbxint{Num} will now
+accept fractions, truncating them first to integers.
+
+% The scientific notation is necessarily (except in |\xintexpr..\relax|) with a
+% lowercase |e|. It may appear both at the numerator and at the denominator of a
+% fraction.
+
Generally speaking, there should be no spaces among the digits in the inputs
-(in arguments to the package macros).
-Although most would be harmless in most macros, there are some cases
-where spaces could break havoc. So the best is to avoid them entirely.
+(in arguments to the package macros). Although most would be harmless in most
+macros, there are some cases where spaces could break havoc.%
+\footnote{The \csbxint{Num} macro does not remove spaces between digits beyond
+ the first non zero ones; however this should not really alter the subsequent
+ functioning of the arithmetic macros, and besides, since \xintcorename v1.2
+ there is an initial parsing of the entire number, during which spaces will
+ be gobbled. However I have not done a complete review of the legacy code to
+ be certain of all possibilities after |v1.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
+ subjected to such a \csa{numexpr} (there are a few other macros with such
+ input types in \xintname). If the input is given as, say |1 2\x| where
+ \csa{x} is a macro, the macro \csa{x} will not be expanded by the
+ \csa{numexpr}, and this will surely cause problems afterwards. Perhaps a
+ later \xintname will force \csa{numexpr} to expand beyond spaces, but I
+ decided that was not really worth the effort. Another immediate cause of
+ problems is an input of the type |\xintiiAdd{<space>\x}{\y}|, because the
+ space will stop the initial expansion; this will most certainly cause an
+ arithmetic overflow later when the \csa{x} will be expanded in a
+ \csa{numexpr}. Thus in conclusion, damages due to spaces are unlikely if
+ only explicit digits are involved in the inputs, or arguments are single
+ macros with no preceding space.}
+%
+% j'avais oublié que mon |...| savait gérer les \ dans les footnote pas besoin
+% de \char92 ou autre!
+%
+So the best is to avoid them entirely.
This is entirely otherwise inside an |\xintexpr|-ession, where spaces are
ignored (except when they occur inside arguments to some macros, thus
escaping the |\xintexpr| parser). See the \hyperref[sec:expr]{documentation}.
-Even with \xintfracname loaded, some macros by their nature can not accept
-fractions on input. Those parsing their inputs through \csbxint{Num} will now
-accept fractions, truncating them first to integers.
-
-With \xintfracname loaded, a number may be empty or start directly with a
-decimal point:
-\begin{quote}
- |\xintRaw{}=\xintRaw{.}|\dtt{=\xintRaw{}}\\
- |\xintPow{-.3/.7}{11}|\dtt{=\xintPow{-.3/+.7}{11}}\\
- |\xinttheexpr (-.3/.7)^11\relax|\dtt{=\xinttheexpr (-.3/.7)^11\relax}
-\end{quote}
-It is also licit to use |\A/\B| as
-input if each of |\A| and |\B| expands (in the sense previously described) to a
-``decimal number'' as examplified above by the numerators and denominators
-(thus, possibly with a `scientific' exponent part, with a lowercase `e'). Or one
-may have just one macro |\C| which expands to such a ``fraction with optional
-decimal points'', or mixed things such as |\A 245/7.77|, where the numerator
-will be the concatenation of the expansion of |\A| and |245|. But, as explained
-already |123\A| is a no-go, \emph{except inside an |\xintexpr|-ession}!
-
-The scientific notation is necessarily (except in |\xintexpr..\relax|) with a
-lowercase |e|. It may appear both at the numerator and at the denominator of a
-fraction.
-%
-\leftedline{|\xintRaw {+--+1253.2782e++--3/---0087.123e---5}|\dtt{=\xintRaw
- {+--+1253.2782e++--3/---0087.123e---5}}}
-
Arithmetic macros of \xintname which parse their arguments automatically through
\csbxint{Num} are signaled by a special
symbol%\ntype{\Numf{\unskip\kern\dimexpr\FrameSep+\FrameRule\relax}}
@@ -4182,79 +4318,39 @@ contain to some extent infix algebra with count registers, see the section
full fraction format with no restriction there is the corresponding symbol
in the margin\ntype{\Ff}.
-The \xintfracname macros generally output
-their result in |A/B[n]| format, representing the fraction |A/B| times |10^n|.
-
-This format with a trailing |[n]| (possibly, |n=0|) is accepted on input
-but it presupposes that the numerator and denominator |A| and |B| are in
-the strict integer format described above. So |16000/289072[17]| or
-|3[-4]| are authorized and it is even possible to use |\A/\B[17]| if
-|\A| expands to |16000| and |\B| to |289072|, or |\A| if |\A| expands to
-|3[-4]|. However, NEITHER the numerator NOR the denominator may then
-have a decimal point\IMPORTANT{}. And, for this format, ONLY the
-numerator may carry a UNIQUE minus sign (and no superfluous leading
-zeroes; and NO plus sign).
-
-It is allowed for user input but the parsing is minimal and it is mandatory to
-follow the above rules. This reduced flexibility, compared to the format without
-the square brackets, allows nesting package macros without too much speed
-impact.
-
\subsection{Output formats}
-With package \xintfracname loaded, the routines \csbxint{Add}, \csbxint{Sub},
-\csbxint{Mul}, \csbxint{Pow}, initiallly synonyms in \xintname of
-\csbxint{iAdd}, \csbxint{iSub}, \csbxint{iMul}, \csbxint{iPow}, are modified
-to become the fraction handling routines.%
-%
-\footnote{the power function does not accept a fractional
- exponent. Or rather, does not expect, and errors will result if one is
- provided.}
-%
-\footnote{as commented upon more later, for that very reason use of
- \csbxint{Add} etc\dots when only \xintname is loaded is strongly
- discouraged.}\,%
-%
-% \footnote{macros \csbxint{iAdd}, \csbxint{iSub}, \csbxint{iMul},
-% \csbxint{iPow}, are the original ones dealing only with integers. They are
-% available as synonyms, also when \xintfracname is not loaded. With
-% \xintfracname loaded they accept on input also fractions, which they first
-% truncate to integers, and then the output format is the integer one. The macros \csbxint{iiAdd}, \csbxint{iiSub}, \csbxint{iiMul},
-% \csbxint{iiPow}, \csbxint{iiSum}, \csbxint{iiPrd} are strictly integer-only:
-% they skip the overhead of parsing their arguments via
-% \csbxint{Num}.}\,%
-%
-% \footnote{also \csbxint{Cmp}, \csbxint{Sgn}, \csbxint{Geq},
-% \csbxint{Opp}, \csbxint{Abs}, \csbxint{Max}, \csbxint{Min} are extended to
-% fractions; and the last four have the integer-only variants \csbxint{iOpp},
-% \csbxint{iAbs}, \csbxint{iMax}, \csbxint{iMin}.}\,%
-% %
-% \footnote{and \csbxint{Fac},
-% \csbxint{Quo}, \csbxint{Rem}, \csbxint{Division}, \csbxint{FDg},
-% \csbxint{LDg}, \csbxint{Odd}, \csbxint{MON}, \csbxint{MMON} all accept a
-% fractional input as long as it reduces to an integer.}
-%
-They produce on output a
-fractional number |f=A/B[n]| where |A| and |B| are integers, with |B| positive,
-and |n| is a ``short'' integer.
-%
-% (\emph{i.e} less in absolute value than |2^{31}-9|).
+Package \xintcorename provides macros \csbxint{iiAdd}, \csbxint{iiSub},
+\csbxint{iiMul}, \csbxint{iiPow}, which only \fexpan d their arguments and
+\csbxint{iAdd}, \csbxint{iSub}, \csbxint{iMul}, \csbxint{iPow} which
+normalize them first to strict format, thus have a bit of overhead. These
+macros always produce integers on output.
+
+With \xintfracname loaded \csbxint{iiAdd}, \csbxint{iiSub}, \csbxint{iiMul},
+... are not modified, and \csbxint{iAdd}, \csbxint{iSub}, \csbxint{iMul}, ...
+are only extended to the extent of accepting fraction inputs but they will be
+truncated to integers.%
%
-This represents |(A/B)| times |10^n|.
+\footnote{the power function does not accept a fractional exponent. Or rather,
+ does not expect, and errors will result if one is provided.}
%
-\footnote{at each stage of the
- computations, the sum of |n| and the length of |A|, or of the absolute value
- of |n| and the length of |B|, must be kept less than
- |2^{31}-9|.}
+The output will be an integer.
\begin{framed}
- The fraction output format for most \xintfracname macros is {|A/B[n]|} which
- stands for |(A/B)|$\times$|10^n|. The |A| and |B| may end in zeroes
- (\emph{i.e}, |n| does not represent all powers of ten), and will generally
- have a common factor. The denominator |B| is always strictly positive.
- Conversely, this format is accepted on input and is parsed more quickly than
- fractions containing decimal points or in scientific notation; the input
- denominator is optional.
+ The fraction handling macros from \xintfracname are called \csbxint{Add},
+ \csbxint{Sub}, \csbxint{Mul}, etc... they are \emph{not} defined in the
+ absence of \xintfracname.\MyMarginNote[\kern\dimexpr\FrameSep+\FrameRule\relax]{Changed!}
+
+ They produce on output a fractional number |f=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 (\emph{i.e} less in absolute value than
+ \dtt{\number"7FFFFFFF}.)
+
+ The output fraction is not reduced to smallest terms. The |A| and |B| may
+ end in zeroes (\emph{i.e}, |n| does not represent all powers of ten). The
+ denominator |B| is always strictly positive. There is no |+| sign on output
+ but only possibly a |-| at the numerator. The output will be expressed as
+ a fraction even if the inputs are both integers.
\end{framed}
\begin{itemize}
@@ -4291,8 +4387,8 @@ $\xintIrr{273.3734e5/3395.7200e-2}$
\item The \csbxint{iiAdd}, \csbxint{iiSub}, \csbxint{iiMul}, \csbxint{iiPow},
and others with `\textcolor{blue}{ii}' in their names accept on input only
- integers in the strict format (they skip the overhead of the \csbxint{Num}
- parsing) and naturally they output an integer, with no fraction slash nor
+ integers in the strict format. They skip the overhead of the \csbxint{Num}
+ parsing and naturally they output integers, with no fraction slash nor
trailing |[n]|.
\end{itemize}
@@ -4658,7 +4754,7 @@ naturally! (but \dtt{F(\xintiiPow2{31}}) would be rather big anyhow...).
In practice, whenever one typesets things, one has left the expansion only
contexts; hence there is no objection to, on the contrary it is recommended,
assign the result of earlier computations to macros via an |\edef| (or an
-|\oodef|, see \ref{oodef}), for later use. The above could thus be coded
+|\fdef|, see \ref{fdef}), for later use. The above could thus be coded
\begin{everbatim}
\begingroup
\def\A {1859} \def\B {1573} \edef\C {\xintiiGCD\A\B}
@@ -4700,28 +4796,33 @@ others are more annoying as they may pass through unsignaled.
\item using one pair of braces too many |\xintIrr{{\xintiPow {3}{13}}/243}| (the
computation goes through with no error signaled, but the result is completely
wrong).
+\item things like |\xintiiAdd { \x}{\y}| as the space will cause \csa{x} to be
+ expanded later, most probably within a |\numexpr| thus provoking possibly an
+ arithmetic overflow.
\item using |[]| and decimal points at the same time |1.5/3.5[2]|, or with a
sign in the denominator |3/-5[7]|. The scientific notation has no such
restriction, the two inputs |1.5/-3.5e-2| and |-1.5e2/3.5| are equivalent:
|\xintRaw{1.5/-3.5e-2}|\dtt{=\xintRaw{1.5/-3.5e-2}},
|\xintRaw{-1.5e2/3.5}|\dtt{=\xintRaw{-1.5e2/3.5}}.
-\item specifying numerators and
- denominators with macros producing fractions when \xintfracname is loaded:
- |\edef\x{|\allowbreak|\xintMul {3}{5}/\xintMul{7}{9}}|. This expands to
- \texttt{\x} which is
- invalid on input. Using this |\x| in a fraction macro will most certainly
- cause a compilation error, with its usual arcane and undecipherable
- accompanying message. The fix here would be to use |\xintiMul|. The simpler
- alternative with package \xintexprname:
- |\xinttheexpr 3*5/(7*9)\relax|.
+% \item specifying numerators and
+% denominators with macros producing fractions when \xintfracname is loaded:
+% |\edef\x{|\allowbreak|\xintMul {3}{5}/\xintMul{7}{9}}|. This expands to
+% \texttt{\x} which is
+% invalid on input. Using this |\x| in a fraction macro will most certainly
+% cause a compilation error, with its usual arcane and undecipherable
+% accompanying message. The fix here would be to use |\xintiMul|. The simpler
+% alternative with package \xintexprname:
+% |\xinttheexpr 3*5/(7*9)\relax|.
\item generally speaking, using in a context expecting an integer (possibly
restricted to the \TeX{} bound) a macro or expression which returns a
fraction: |\xinttheexpr 4/2\relax| outputs \dtt{\xinttheexpr 4/2\relax},
not $2$. Use |\xintNum {\xinttheexpr 4/2\relax}| or |\xinttheiexpr 4/2\relax|
(which rounds the result to the nearest integer, here, the result is already
- an integer) or |\xinttheiiexpr 4/2\relax|.
-\item use of square brackets |[|, |]| in |\xintexpr...\name| has some traps, see
- \autoref{sec:expr}.
+ an integer) or |\xinttheiiexpr 4/2\relax|. Or, divide in your head |4| by
+ |2| and insert the result directly in the \TeX{} source.
+% trop technique
+% \item use of square brackets |[|, |]| in |\xintexpr...\name| has some traps, see
+% \autoref{sec:expr}.
\end{itemize}
\subsection{Error messages}
@@ -4772,6 +4873,29 @@ sequences:
% par ailleurs il y a trop d'espace vertical avant le multicols, mais
% bon.
+There are now a few more if for example one attempts to use |\xintAdd| without
+having loaded \xintfracname (with only \xintname loaded, only |\xintiAdd| and
+|\xintiiAdd| are legal).\MyMarginNote{Changed!}
+\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
+\Did_you_mean_iiPrdExpr?or_load_xintfrac
+\Did_you_mean_iiSumExpr?or_load_xintfrac
+\end{everbatim}
+\end{multicols}
+
Don't forget to set |\errorcontextlines| to at least |2| to get from \LaTeX\
more meaningful error messages. Errors occuring during the parsing of
|\xintexpr-essions| try to provide helpful information about the offending
@@ -4786,9 +4910,11 @@ daring experienced \TeX/\LaTeX\ user.
\subsection{Package namespace, catcodes}
-The \xintname bundle packages presuppose that the \csa{space}, \csa{empty} and
-|\m@ne| control sequences are pre-defined with meanings as in Plain
-\TeX{} or \LaTeX2e.
+% note: v1.2 définit \m@ne si ce count n'existe pas.
+
+The bundle packages needs that the \csa{space} and \csa{empty} control
+sequences are pre-defined with the identical meanings as in Plain \TeX{} or
+\LaTeX2e.
Private macros of \xintkernelname, \xintcorename, \xinttoolsname,
\xintname, \xintfracname, \xintexprname, \xintbinhexname, \xintgcdname,
@@ -4945,7 +5071,7 @@ $2^{100}$ (=\xintiPow {2}{100}) has \xintLen{\xintiPow {2}{100}} digits and the
\end{everbatim*}
It would be more efficient to do once and for all
-|\oodef\z{\xintiPow {2}{100}}|, and then use |\z| in place of
+|\edef\z{\xintiPow {2}{100}}|, and then use |\z| in place of
|\xintiPow {2}{100}| everywhere as this would spare the CPU some repetitions.
Expandably computing primes is done in \autoref{xintSeq}.
@@ -4979,434 +5105,6 @@ expandability. Check it out (\autoref{xintiloop}).
% \noindent\kern\parindent\input README.md
% \endgroup }\x
-\section{New features of the \xintexprname package}
-\label{sec:expr11}
-
-Release |1.1| brought many changes to \xintexprname. This chapter is
-for people already familiar with earlier versions. A more systematic
-item per item syntax description is provided in \autoref{sec:expr}. But be
-sure to come back here as the latter chapter has not been compeletely updated.
-
-First, there were some breaking changes:
-\begin{itemize}[parsep=0pt, labelwidth=\leftmarginii,
- itemindent=\leftmarginii, leftmargin=0em]
- \item in |\xintiiexpr|, |/| does \emph{rounded} division, rather than as
- in earlier releases the
- Euclidean division (for positive arguments, this is truncated division).
- The new |//| operator does truncated division,
- \item the |:| operator for three-way branching is gone, replaced with |??|,
- \item |1e(3+5)| is now illegal. The number parser identifies |e| and |E|
- in the same way it does for the decimal mark, earlier versions treated
- |e| as |E| rather as postfix operators,
- \item the |add| and |mul| have a new syntax, old syntax is with |`+`| and
- |`*`| (quotes mandatory), |sum| and |prd| are gone,
- \item no more special treatment for encountered brace pairs |{..}| by the
- number scanner, |a/b[N]| notation can be used without use of braces (the
- |N| will end up space-stripped in a |\numexpr|, it is not parsed by the
- |\xintexpr|-ession scanner).
- \item although |&| and \verb+|+ are still available as Boolean operators the
- use of |&&| and \verb+||+ is strongly recommended. The single
- letter operators might be assigned some other meaning in later releases
- (bitwise operations, perhaps). Do not use them.
- \item place holders for |\xintNewExpr|
- could be denoted |#1|, |#2|, ... or also, for special purposes |$1|, |$2|,
- ... Only the first form is now accepted and the special cases previously
- treated via the second form are now managed via a |protect(...)| function.
-\end{itemize}
-
-Let's now describle some of the numerous additional functionalities.
-
-\begin{itemize}[parsep=0pt, labelwidth=\leftmarginii,
- itemindent=\leftmarginii, leftmargin=0em]
- \item |\xintiexpr|, |\xinttheiexpr| admit an optional argument within
- brackets |[d]|, it then presents the computation result (or results, if
- comma separated) after rounding to |d| digits after decimal mark, (the
- whole computation is done exactly, as in |xintexpr|),
-\begin{everbatim*}
-\xinttheiexpr [32] 1.23^50, 1.231^50\relax
-\end{everbatim*}
- \item |\xintfloatexpr|, |\xintthefloatexpr| similarly admit an optional
- argument which serves to keep only |d| digits of precision, getting rid
- of cumulated uncertainties in the last digits (the whole computation is
- done according to the precision set via |\xintDigits|),
-\begin{everbatim*}
-\xintDigits:=32;\xintthefloatexpr 1.010101^10-1.0101^10\relax
-
-\xintDigits:=16;\xintthefloatexpr 1.010101^10-1.0101^10\relax
-
-\xintthefloatexpr [12] 1.010101^10-1.0101^10\relax
-\end{everbatim*}
-
- \item |\xinttheexpr| and |\xintthefloatexpr| ``pretty-print'' if possible,
- the former removing unit denominator or |[0]| brackets, the latter
- avoiding scientific notation if decimal notation is practical,
- \item the |//| does truncated division and |/:| is the associated modulo,
- \item multi-character operators |&&|, \verb+||+, |==|, |<=|, |>=|, |!=|,
- |**|,
- \item multi-letter infix binary words |'and'|, |'or'|, |'xor'|, |'mod'|
- (quotes mandatory),
- \item functions |even|, |odd|, |first|, |last|,
- \item |\xintdefvar A3:=3.1415;| for variable definitions (non expandable,
- naturally), usable in subsequent expressions; variable names may contain
- letters, digits, underscores. They should not start with a digit, the
- |@| is reserved, and single lowercase and uppercase Latin letters are
- predefined to work as dummy variables (see next),
- \item generation of comma separated lists |a..b|, |a..[d]..b|,
- \item Python syntax-like list extractors |[list][n:]|, |[list][:n]|, |[list][a:b]|
- and |[list][n]| (|n=0| for the number of list items), the step is always
- |+1|,
- \item function |reversed|, to reverse the order of list items,
- \item itemwise sequence operations |a*[list]|, etc.., on both sides |a*[list]^b|,
- \item dummy variables in |add| and |mul|: |add(x(x+1)(x-1), x=-10..10)|,
- \item variable substitutions with |subs|: |subs(subs(add(x^2+y^2,x=1..y),y=t),t=20)|,
- \item sequence generation using |seq| with a dummy variable: |seq(x^3, x=-10..10)|,
- \item simple recursive sequences with |rseq|, with |@| given the last value,
- |rseq(1;2@+1,i=1..10)|,
- \item higher recursion with |rrseq|, |@1|, |@2|, |@3|, |@4|, and |@@(n)|
- for earlier values, up to |n=K| where |K| is the number of terms of the
- initial stretch |rrseq(0,1;@1+@2,i=2..100)|,
- \item iteration with |iter| which is like |rrseq| but outputs only the
- last |K| terms, where |K| was the number of initial terms,
- \item inside |seq|, |rseq|, |rrseq|, |iter|, possibility to use |omit|,
- |abort| and |break| to control termination,
- \item |n++| potentially infinite index generation for |seq|, |rseq|,
- |rrseq|, and |iter|, it is advised to use |abort| or |break(..)| at
- some point,
- \item the |add|, |mul|, |seq|, ... are nestable,
- \item |\xintthecoords| converts a comma separated list of an even number
- of items to the format as expected by the |TikZ| |coordinates| syntax,
- \item completely rewritten |\xintNewExpr|, new |protect| function to handle
- external macros. However not all constructs are compatible with
- |\xintNewExpr|.
-\end{itemize}
-
-% \subsection{Examples with the \texorpdfstring{\unexpanded{\unexpanded{|v1.1|}}}{v1.1} \csh{xintexpr}}
-
-And now some examples:
-
-\begin{itemize}[parsep=0pt, labelwidth=\leftmarginii,
- itemindent=\leftmarginii, leftmargin=0em]
-\item One can define variables (the definition itself is a non expandable
- step). The allowed names are composed of letters, digits, and underscores.
- The variable should not start with a digit and single letters |a..z|, |A..Z|
- are predefined for use as dummy variables --- see below. The |@| is
- reserved.
-\begin{everbatim*}
-\begingroup
- \xintdefvar a_1 := 3.14159;\xintdefvar a2 := 2.71828;\xinttheiexpr [5] a_1+a2\relax
-\endgroup
-\end{everbatim*}
-\item |add| and |mul| have a new syntax requiring a dummy variable:
-\begin{everbatim*}
-\xinttheexpr add(x, x=1,3,19), mul(x^2, x=1,3,19), add(x(x+1), x= 1,3,19)\relax
-\end{everbatim*}
-
-Use |`+`| and |`*`| (left ticks mandatory) for syntax without dummy variables:
-\begin{everbatim*}
-\xinttheexpr `+`(1,3,19), `*`(1^2,3^2,19^2), `+`(1*2,3*4,19*20)\relax
-\end{everbatim*}
-\item The |seq| function generates sequences according to a given formula:
-\begin{everbatim*}
-\xinttheexpr seq(x(x+1)(x+2), x=1,3,19), `+`(seq(x(x+1)(x+2), x=1,3,19)),
- add(x(x+1)(x+2), x=1,3,19)\relax
-\end{everbatim*}
-\begin{everbatim*}
-And this is nestable!
-\xinttheexpr seq(seq(x^y, y=1..5),x=1..5), add(mul(x^y,y=1..5), x=1..5),
- add(x^15, x=1..5)\relax % 15 = 1+2+3+4+5
-\end{everbatim*}
-
-One should use parentheses appropriately. The \csbxint{expr} parser in normal
-operation is not bad at identifying missing or extra opening or closing
-parentheses, but when it handles |seq|, |add|, |mul| or similar constructs it
-switches to another mode of operation (it starts using delimited macros,
-something which is almost non-existent in all its other operations) and ill-formed
-expressions are much more likely to let the parser fetch tokens from beyond the
-mandatory ending |\relax|. Thus, in case of a missing parenthesis in such
-circumstances the error message from \TeX{} might be very cryptic, even for
-the seasoned \xintname user.
-
-\item As seen in the last example |a..b| constructs the integers from |a| to
- |b|. This is (small) integer only. A more general |a..[d]..b| works with big
- integers, or fractions, from |a| to |b| with step |d|.
-\begin{everbatim*}
-\xinttheexpr seq(2x+1, x=1..10, 100..110, 3/5..[1/5]..7/5)\relax
-\end{everbatim*}
-\item itemwise operations on lists are possible, as well as item extractions:
-\begin{everbatim*}
-\xinttheiiexpr 2*[1,10,100]^3, 5+[2*[1,10,100]^3]*100 \relax
-\end{everbatim*}
-\begin{everbatim*}
-\xinttheiiexpr 1+[seq(3^j, j=1..10, 21..30)][17], 1+3^27\relax
-\end{everbatim*}
-
-We used the |[list][n]| construct which gives the nth item from the list. In
-this context there are also the functions |last| and |first|. There is no real
-concept of a list object, nor list operations, although itemwise manipulation
-are made possible as shown above via the |[..]| constructor. The list
-manipulation utilities are so far a bit limited. There is no notion of an
-``nuple'' object. The variable |nil| is reserved, it represents an empty list.
-
-\item |subs| is similar to |seq| in syntax but is for variable substitution:
-\begin{everbatim*}
-\xinttheexpr subs(100*subs(10*subs(3*x+5,x=y+50)+2,y=z^2),z=10)\relax % 100(10(3*150+5)+2)
-\end{everbatim*}
-\begin{everbatim*}
-\xinttheexpr subs(subs(add(x^2+y^2,x=1..y),y=t),t=20)\relax
-\end{everbatim*}
-
-The substituted variable may be a comma separated list (this is impossible
-with |seq| which will always pick one item after the other of a list).
-\begin{everbatim*}
-\xinttheexpr subs([x]^2,x=-123,17,32)\relax
-\end{everbatim*}
-
-\item last but not least, |seq| has variants |rseq| and |rrseq| which allow
- recursive definitions. They start with at least one initial value, then a
- semi-colon, then the formula, then the list of indices to iterate over. |@|
- (or |@1|) evaluates to the last computed item, and |rrseq| keeps the memory
- of the |K| last results, where |K| was the number of initial terms. One
- accesses them via |@1, @2, @3, @4| and |@@(N)| for |N>4|. It is even
- possible to nest them and use |@@@| to access the values of the master
- recursion...
-\begin{everbatim*}
-\xinttheiiexpr rseq(1; 2*@, i=1..10), `+`(rseq(1; 2*@, i=1..10))\relax
-\end{everbatim*}
-\begin{everbatim*}
-\xinttheiiexpr rseq(2; @(@+1)/2, i=1..5)\relax
-\end{everbatim*}
-\begin{everbatim*}
-\xinttheiiexpr rseq(0,1; (@1,add(x,x=@1)), y=2..10)\relax
-\end{everbatim*}
-
-Some Fibonacci fun
-\begin{everbatim*}
-\xinttheiiexpr rrseq(0,1; @1+@2, x=2..10), last(rrseq(0,1; @1+@2, x=2..100))\relax
-\end{everbatim*}
-\begin{everbatim*}
-Sum of previous last three: \xinttheiiexpr rrseq(0,0,1; @1+@2+@3, i=1..20)\relax
-\end{everbatim*}
-\begin{everbatim*}
-Big numbers: \printnumber{\xinttheexpr rseq(1; @(@+1), j=1..10)\relax }
-\end{everbatim*}
-
-Nested recursion often quickly leads to gigantic outputs. This is an
-experimental feature, susceptible to be removed or altered in the future.
-\begin{everbatim*}
-\xinttheexpr rrseq(1; `+`(rrseq(0,1; @@@(1)+@1+@2, i=1..10)), j=1..5)\relax
-\end{everbatim*}
-
-\item The special keywords |omit|, |abort| and |break(..)| are available
- inside |seq|, |rseq|, |rrseq|, as well as the |n++| for a potentially
- infinite iteration. The |n++| construct in conjunction with an |abort| or
- |break| is often more efficient, because in other cases the list to iterate
- over is first completely constructed.
-\begin{everbatim*}
-First Fibonacci number at least |2^31| and its index
-\xinttheiiexpr iter(0,1; (@1>=2^31)?{break(i)}{@2+@1}, i=1++)\relax
-\end{everbatim*}
-
-\begin{everbatim*}
-Prime numbers are always cool
-\xinttheiiexpr seq((seq((subs((x/:m)?{(m*m>x)?{1}{0}}{-1},m=2n+1))
- ??{break(0)}{omit}{break(1)},n=1++))?{x}{omit},
- x=10001..[2]..10200)\relax
-\end{everbatim*}
-
-The syntax in this last example may look a bit involved. First |x/:m| computes
-|x modulo m| (this is the modulo with respect to truncated division, which
-here for positive arguments is like Euclidean division; in
-|\xintexpr...\relax|, |a/:b| is such that |a = b*(a//b)+a/:b|, with |a//b| the
-algebraic quotient |a/b| truncated to an integer.). The |(x)?{yes}{no}|
-construct checks if |x| (which \emph{must} be within parentheses) is true or
-false, i.e. non zero or zero. It then executes either the |yes| or the |no|
-branch, the non chosen branch is \emph{not} evaluated. Thus if |m| divides |x|
-we are in the second (``false'') branch. This gives a |-1|. This |-1| is the
-argument to a |??| branch which is of the type |(y)??{y<0}{y=0}{y>0}|, thus here
-the |y<0|, i.e., |break(0)| is chosen. This |0| is thus given to another |?|
-which consequently chooses |omit|, hence the number is not kept in the list.
-The numbers which survive are the prime numbers.
-
-% A006877 In the `3x+1' problem, these values for the starting value set new
-% records for number of steps to reach 1. (Formerly M0748) 14 1, 2, 3, 6, 7,
-% 9, 18, 25, 27, 54, 73, 97, 129, 171, 231, 313, 327, 649, 703, 871, 1161,
-% 2223, 2463, 2919, 3711, 6171, 10971, 13255, 17647, 23529, 26623, 34239,
-% 35655, 52527, 77031, 106239, 142587, 156159, 216367, 230631, 410011, 511935,
-% 626331, 837799
-
-\item The |iter| function is like |rrseq| but does not leave a trace of earlier items,
- it starts with |K| initial values, then it iterates: either a fixed number of times,
- or until aborting or breaking. And ultimately it prints |K| final values.
-\begin{everbatim*}
-The first Fibonacci number beyond the \TeX{} bound is
-\xinttheiiexpr subs(iter(0,1;(@1>N)?{break(i)}{@1+@2},i=1++),N=2^31)\relax{}
-and the previous number was its index.
-\end{everbatim*}But this was a bit too easy, what is the smallest Fibonacci number not representable on 64 bits?
-\begin{everbatim*}
-The first Fibonacci number beyond |2^64| bound is
-\xinttheiiexpr subs(iter(0,1;(@1>N)?{break(i)}{@1+@2},i=1++),N=2^64)\relax{}
-and the previous number was its index.
-\end{everbatim*}
-
-One more recursion:
-\begin{everbatim*}
-\def\syr #1{\xinttheiiexpr rseq(#1; (@<=1)?{break(i)}{odd(@)?{3@+1}{@//2}},i=0++)\relax}
-The 3x+1 problem: \syr{231}\par
-\end{everbatim*}
-
-Ok, a final one:
-\begin{everbatim*}
-\def\syrMax #1{\xinttheiiexpr iter(#1,#1;even(i)?
- {(@2<=1)?{break(i/2)}{odd(@2)?{3@2+1}{@2//2}}}
- {(@1>@2)?{@1}{@2}},i=0++)\relax }
-With initial value 1161, the maximal number attained is \syrMax{1161} and that latter
-number is the number of steps which was needed to reach 1.\par
-\end{everbatim*}
-
-Well, one more:
-
-\begin{everbatim*}
-\newcommand\GCD [2]{\xinttheiiexpr rrseq(#1,#2; (@1=0)?{abort}{@2/:@1}, i=1++)\relax }
-\GCD {13^10*17^5*29^5}{2^5*3^6*17^2}
-\end{everbatim*}
-
-and the ultimate:
-
-\begin{everbatim*}
-\newcommand\Factors [1]{\xinttheiiexpr
- subs(seq((i/:3=2)?{omit}{[L][i]},i=1..([L][0])),
- L=rseq(#1;(p^2>[@][1])?{([@][1]>1)?{break(1,[@][1],1)}{abort}}
- {(([@][1])/:p)?{omit}
- {iter(([@][1])//p; (@/:p)?{break(@,p,e)}{@//p},e=1++)}},p=2++))\relax }
-\Factors {41^4*59^2*29^3*13^5*17^8*29^2*59^4*37^6}
-\end{everbatim*}
-
-This might look a bit scary, I admit. \xintexprname has minimal tools and
-is obstinate about doing everything expandably! We are hampered by absence of a
-notion of ``nuple''. The algorithm divides |N| by |2| until no more possible,
-then by |3|, then by |4| (which is silly), then by |5|, then by |6| (silly
-again), \dots.
-
-The variable |L=rseq(#1;...)| expands, if one follows the steps, to a comma
-separated list starting with the initial (evaluated) |N=#1| and then
-pseudo-triplets where the first item is |N| trimmed of small primes, the
-second item is the last prime divisor found, and the third item is its
-exponent in original |N|.
-
-The algorithm needs to keep handy the last computed quotient by prime powers,
-hence all of them, but at the very end it will be cleaner to get rid of them
-(this corresponds to the first line in the code above). This is achieved in a
-cumbersome inefficient way; indeed each item extraction |[L][i]| is costly: it
-is not like accessing an array stored in memory, due to expandability, nothing
-can be stored in memory! Nevertheless, this step could be done here in a far
-less inefficient manner if there was a variant of |seq| which, in the spirit
-of \csbxint{iloopindex}, would know how many steps it had been through so far.
-This is a feature to be added to |\xintexpr|! (as well as a |++| construct
-allowing a non unit step).
-
-Notice that in |iter(([@][1])//p;| the |@| refers to the previous triplet (or
-in the first step to |N|), but the latter |@| showing up in |(@/:p)?| refers
-to the previous value computed by |iter|.
-
-\begin{snugframed}
- Parentheses are essential in |..([y][0])| else the parser will see |..[| and
- end up in ultimate confusion, and also in |([@][1])/:p| else the parser will
- see the itemwise operator |]/| on lists and again be very confused (I could
- implement a |]/:| on lists, but in this situation this would also be very
- confusing to the parser.)
-\end{snugframed}
-
-For comparison, here is an \fexpan dable macro expanding to the same result,
-but coded directly with the \xintname macros. Here |#1| can not be itself an
-expression, naturally. But at least we let |\Factorize| \fexpan d its
-argument.
-\begin{everbatim}
-\makeatletter
-\newcommand\Factorize [1]
- {\romannumeral0\expandafter\factorize\expandafter{\romannumeral-`0#1}}%
-\newcommand\factorize [1]{\xintiiifOne{#1}{ 1}{\factors@a #1.{#1};}}%
-\def\factors@a #1.{\xintiiifOdd{#1}
- {\factors@c 3.#1.}%
- {\expandafter\factors@b \expandafter1\expandafter.\romannumeral0\xinthalf{#1}.}}%
-\def\factors@b #1.#2.{\xintiiifOne{#2}
- {\factors@end {2, #1}}%
- {\xintiiifOdd{#2}{\factors@c 3.#2.{2, #1}}%
- {\expandafter\factors@b \the\numexpr #1+\@ne\expandafter.%
- \romannumeral0\xinthalf{#2}.}}%
-}%
-\def\factors@c #1.#2.{%
- \expandafter\factors@d\romannumeral0\xintiidivision {#2}{#1}{#1}{#2}%
-}%
-\def\factors@d #1#2#3#4{\xintiiifNotZero{#2}
- {\xintiiifGt{#3}{#1}
- {\factors@end {#4, 1}}% ultimate quotient is a prime with power 1
- {\expandafter\factors@c\the\numexpr #3+\tw@.#4.}}%
- {\factors@e 1.#3.#1.}%
-}%
-\def\factors@e #1.#2.#3.{\xintiiifOne{#3}
- {\factors@end {#2, #1}}%
- {\expandafter\factors@f\romannumeral0\xintiidivision {#3}{#2}{#1}{#2}{#3}}%
-}%
-\def\factors@f #1#2#3#4#5{\xintiiifNotZero{#2}
- {\expandafter\factors@c\the\numexpr #4+\tw@.#5.{#4, #3}}%
- {\expandafter\factors@e\the\numexpr #3+\@ne.#4.#1.}%
-}%
-\def\factors@end #1;{\xintlistwithsep{, }{\xintRevWithBraces {#1}}}%
-\makeatother
-\end{everbatim}
-
-The macro |\Factorize| puts a little stress on the input save stack in order
-not be bothered with previously gathered things. I timed it to be about eight
-times faster than |\Factors| in test cases such as
-|16246355912554185673266068721806243461403654781833| and others. Among the
-various things explaining the speed-up, there is fact that we step by
-increments of two, not one, and also that we divide only once, obtaining
-quotient and remainder in one go. These two things already make for a speed-up
-factor of about four. Thus, our earlier |\Factors| was not completely
-inefficient, and was quite easier to come up with than |\Factorize|.
-
-If we only considered small integers, we could write pure |\numexpr| methods
-which would be very much faster (especially if we had a table of small primes
-prepared first) but still ridiculously slow compared to any non expandable
-implementation, not to mention use of programming languages directly accessing
-the CPU registers\dots
-\end{itemize}
-
-%\phantomsection
-\phantomsection\label{sec:expr11coords}
-
-To conclude with this overview of the new features in \xintexprname |1.1|, I
-will mention {\bfseries |\xintthecoords|} which converts a comma separated
-list as produced by |\xintfloatexpr| or |\xintiexpr [d]| to the format
-expected by the |TikZ| |coordinates| syntax.
-\begin{everbatim*}
-{\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 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}\par }
-\end{everbatim*}
-
-% Notice: if x goes no take exactly value 1 or -1, the origin appears slightly
-% off the curve, not MY fault!!!
-
-\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.
-
-\begin{everbatim*}
-\oodef\x{\xintthecoords \xintexpr rrseq(1/2,1/3; @1+@2, x=1..20)\relax }
-\meaning\x +++
-\end{everbatim*}
-
\etocdepthtag.toc {commands}
\indescriptionfalse
\addtocontents{toc}{\gdef\string\sectioncouleur{{joli}}}
@@ -5459,12 +5157,16 @@ them).
There is a similar macro |\odef| with only one expansion of the replacement text
|<stuff>|, and |\fdef| which expands fully |<stuff>| using |\romannumeral-`0|.
-These tools are provided as it is sometimes wasteful (from the point of view
-of running time) to do an |\edef| when one knows that the contents expand in
-only two steps for example, as is the case with all (except \csbxint{loop} and
-\csbxint{iloop}) the expandable macros of the \xintname packages. Each will be
-defined only if \xintkernelname finds them currently undefined. They can be
-prefixed with |\global|.
+% These tools are provided as it is sometimes wasteful (from the point of view
+% of running time) to do an |\edef| when one knows that the contents expand in
+% only two steps for example, as is the case with all (except \csbxint{loop}
+% and \csbxint{iloop}) the expandable macros of the \xintname packages. Each
+% will be defined only if \xintkernelname finds them currently undefined.
+
+They can be prefixed with |\global|. It appears than |\fdef| is generally a bit
+faster than |\edef| when expanding macros from the \xintname bundle, when the
+result has a few dozens of digits. |\oodef| needs thousands of digits it seems
+to become competitive.
\subsection{\csbh{xintReverseOrder}}\label{xintReverseOrder}
@@ -5869,7 +5571,7 @@ then |\xintNthElt| returns nothing.
\subsection{\csbh{xintKeep}}\label{xintKeep}
\csa{xintKeep\x}\marg{list}\etype{\numx f} expands the list argument and returns
-a new list containing only the first |x| elements.\NewWith {1.09m} If |x<0| the
+a new list containing only the first |x| elements. If |x<0| the
macro returns the last \verb+|x|+ elements (in the same order as in the initial
list). If \verb+|x|+ equals or exceeds the length of the list, the list (as
arising from expansion of the second argument) is returned. For |x=0| the empty
@@ -5884,7 +5586,7 @@ brace pairs (either added to a naked token, or initially present), one may use
argument.
%
\begin{everbatim*}
-\oodef\test {\xintKeep {17}{\xintKeep {-69}{\xintSeq {1}{100}}}}\meaning\test
+\fdef\test {\xintKeep {17}{\xintKeep {-69}{\xintSeq {1}{100}}}}\meaning\test
\end{everbatim*}
%
@@ -5892,7 +5594,7 @@ argument.
\csa{xintTrim\x}\marg{list}\etype{\numx f} expands the list argument and
gobbles its first |x| elements. If |x<0| the macro gobbles the last
-\verb+|x|+ elements.\NewWith {1.09m} If \verb+|x|+ equals or exceeds
+\verb+|x|+ elements. If \verb+|x|+ equals or exceeds
the length of the list, the empty list is returned. For |x=0| the full
list is returned.
@@ -5902,7 +5604,7 @@ up braced in the output (if present there).
\csa{xintTrimNoExpand} does the same without first \fexpan ding its list
argument.
\begin{everbatim*}
-\oodef\test {\xintTrim {17}{\xintTrim {-69}{\xintSeq {1}{100}}}}\meaning\test
+\fdef\test {\xintTrim {17}{\xintTrim {-69}{\xintSeq {1}{100}}}}\meaning\test
\end{everbatim*}
\subsection{\csbh{xintListWithSep}}\label{xintListWithSep}
@@ -6569,7 +6271,6 @@ to illustrate use of the general purpose \csbxint{iloop}. A little table giving
the first values of |\SmallestFactor| follows, its coding uses \csbxint{For},
which is described later; none of this uses count registers.
%
-%\tracingmacros1
\begin{everbatim*}
\let\IsPrime\undefined \let\SmallestFactor\undefined % clean up possible previous mess
@@ -7673,9 +7374,9 @@ an optional parameter to \csa{xintAssign}, see \emph{infra}.
\noindent\csa{xintAssign} admits since |1.09i| an
optional parameter, for example |\xintAssign [e]...| or |\xintAssign [oo]
-...|. The latter means that the definitions of the macros initially on the
-right of |\to| will be made with \hyperref[oodef]{\ttfamily\char92oodef} which
-expands twice the replacement text. The default is simply to make the
+...|. With |[f]| for example the definitions of the macros initially on the
+right of |\to| will be made with \hyperref[fdef]{\ttfamily\char92fdef} which
+\fexpan ds the replacement text. The default is simply to make the
definitions with |\def|, corresponding to an empty optional paramter |[]|.
Possibilities: |[], [g], [e], [x], [o], [go], [oo], [goo], [f], [gf]|.
@@ -7739,6 +7440,19 @@ here to make the definitions global. For this, one should rather do
Note that prior to release |1.09j| each item (token or braced material) was
submitted to an |\edef|, but the default is now to use |\def|.
+\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
+
\subsection{\csbh{xintRelaxArray}}\label{xintRelaxArray}
\csa{xintRelaxArray}\csa{myArray} %\ntype{N}
@@ -7986,33 +7700,30 @@ expression, in the arguments to the package macros, see the
\hyperref[sec:useofcount]{Use of count} section.
\begin{framed}
- \xintcorename also provides macros |\xintAdd|, |\xintMul|,\dots as synonyms
- to |\xintiAdd|, |\xintiMul|,\dots. Their usage is
- \fbox{deprecated}\IMPORTANT{} for the following reason: with \xintfracname
- loaded they become the routines dealing fully with fractions on input. But
- this means that they now use fraction format on output, even with integer
- arguments.
-
- Due to this variability of the output format on whether the document uses
- only \xintname or loads additionally \xintfracname, code using these macros
- is fragile, because loading at some later date a package which itself loads
- \xintfracname or \xintexprname will modify their output format, and this is
- catastrophic for example in locations expanded by |\ifnum|, or even in
- arguments to those other macros of \xintname with |ii| in their names.
-
- Prefer thus, when writing code loading only \xintcorename or \xintname, to
- use the macros \csbxint{iAdd}, \csbxint{iMul}, \dots, or \csbxint{iiAdd},
- \csbxint{iiMul}, \dots. They are guaranteed to always output an integer
- without a trailing |/B[n]|. The latter have the less overhead, and the
- former do not complain, if \xintfracname is loaded, even if used with true
- fractions, as they will then truncate their arguments to
- integers.
-
-%\MyMarginNote[\kern\dimexpr\FrameSep+\FrameRule\relax]{Changed}
-
- It was an error for the \xintname package (now \xintcorename) to provide
- macros |\xintAdd|, |\xintMul|, |\xintSub| \dots. They should be used only
- with \xintfracname loaded.
+ Earlier releases of \xintcorename also provided macros |\xintAdd|,
+ |\xintMul|,\dots as synonyms to |\xintiAdd|, |\xintiMul|,\dots, destined to
+ be re-defined by \xintfracname.\IMPORTANT{} It was announced some time ago
+ that their usage was deprecated, because the output formats depended on
+ whether \xintfracname was loaded or not. They now have been \fbox{removed.}
+ \MyMarginNote[\kern\dimexpr\FrameSep+\FrameRule\relax]{Changed}
+
+ % Due to this variability of the output format on whether the document uses
+ % only \xintname or loads additionally \xintfracname, code using these macros
+ % is fragile, because loading at some later date a package which itself loads
+ % \xintfracname or \xintexprname will modify their output format, and this is
+ % catastrophic for example in locations expanded by |\ifnum|, or even in
+ % arguments to those other macros of \xintname with |ii| in their names.
+
+ The macros \csbxint{iAdd}, \csbxint{iMul}, \dots, or \csbxint{iiAdd},
+ \csbxint{iiMul}, \dots which come with \xintcorename are guaranteed to
+ always output an integer without a trailing |/B[n]|. The latter have the
+ lesser overhead, and the former do not complain, if \xintfracname is loaded,
+ even if used with true fractions, as they will then truncate their arguments
+ to integers. But their output format remains unmodified: integers with no
+ fraction slash nor |[N]| thingy.
+ % It was an error for the \xintname package (now \xintcorename) to provide
+ % macros |\xintAdd|, |\xintMul|, |\xintSub| \dots. They should be used only
+ % with \xintfracname loaded.
\end{framed}
The {\color[named]{PineGreen}$\star$}'s in the margin are there to remind of
@@ -8045,15 +7756,13 @@ extended by \xintfracname to fractions.
\subsection{\csbh{xintiOpp}, \csbh{xintiiOpp}}\label{xintiOpp}\label{xintiiOpp}
|\xintiOpp|\n\etype{\Numf} return the opposite |-N| of the number |N|.
-\csbxint{Opp} is initially a synonym but gets extended by \xintfracname to
-fractions (its output format will be a fraction even if the argument is an
-integer) and \csa{xintiiOpp} is the strict integer-only variant which skips
+\csa{xintiiOpp} is the strict integer-only variant which skips
the \csbxint{Num} overhead.\etype{f}
\subsection{\csbh{xintiAbs}, \csbh{xintiiAbs}}\label{xintiAbs}\label{xintiiAbs}
|\xintiAbs|\n\etype{\Numf} returns the absolute value of the number.
-\csbxint{Abs} is a synonym but gets modified by \xintfracname. \csa{xintiiAbs}
+\csa{xintiiAbs}
skips the \csbxint{Num} overhead.\etype{f}
\subsection{\csbh{xintiiFDg}}\label{xintFDg}\label{xintiiFDg}
@@ -8090,67 +7799,63 @@ of parsing via \csbxint{Num}.
\subsection{\csbh{xintiAdd}, \csbh{xintiiAdd}}\label{xintiAdd}\label{xintiiAdd}
|\xintiAdd|\n\m\etype{\Numf\Numf} returns the sum of the two numbers.
-\csbxint{Add} is initially a synonym but gets extended by \xintfracname.
\csa{xintiiAdd} skips the \csbxint{Num} overhead.\etype{ff}
\subsection{\csbh{xintiSub}, \csbh{xintiiSub}}\label{xintiSub}\label{xintiiSub}
-|\xintiSub|\n\m\etype{\Numf\Numf} returns the difference |N-M|. \csbxint{Sub}
-is initially a synonym but gets extended by \xintfracname.
+|\xintiSub|\n\m\etype{\Numf\Numf} returns the difference |N-M|.
\csa{xintiiSub} skips the \csbxint{Num} overhead.\etype{ff}
\subsection{\csbh{xintiMul}, \csbh{xintiiMul}}\label{xintiMul}\label{xintiiMul}
%{\small Modified in release |1.03|.\par}
|\xintiMul|\n\m\etype{\Numf\Numf} returns the product of the two numbers.
-\csbxint{Mul} is the initial synonym modified by \xintfracname, and
\csa{xintiiMul} skips the \csbxint{Num} overhead.\etype{ff}
\subsection{\csbh{xintiSqr}, \csbh{xintiiSqr}}\label{xintiSqr}\label{xintiiSqr}
-|\xintiSqr|\n\etype{\Numf} returns the square. \csbxint{Sqr} is the initial
-synonym extended by \xintfracname to fractions. \csa{xintiiSqr} skips the
+|\xintiSqr|\n\etype{\Numf} returns the square. \csa{xintiiSqr} skips the
\csbxint{Num} overhead.\etype{f}
\subsection{\csbh{xintiPow}, \csbh{xintiiPow}}\label{xintiPow}\label{xintiiPow}
|\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|, or if \verb+|N|>1+
-and |x>100000|, then an error is raised.
+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.
+
+\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 and including |2^17|
+ are allowed (because the power operation works by squaring things and making
+ products).
+\end{framed}
-The |x>100000| condition should perhaps be made more strict: as it stands it
-allows launching operations taking hours to complete. Indeed, observe that
-|2^50000| already has \dtt{\xintLen{\xintFloatPow [1]{2}{50000}}} digits; as
-it turns out each exact multiplication done via \csbxint{iiMul} of two
-numbers with one thousand digits each already takes of the order of seconds,
-and it would take hours for arguments each with circa $15000$ digits. Perhaps
-some completely expandable but not \fexpan dable variants could fare better?
+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.).
\csa{xintiiPow} is an integer only variant skipping the \csbxint{Num}
overhead\etype{f\numx}, it produces the same result as \csa{xintiPow} with
stricter assumptions on the inputs, and is thus a tiny bit faster.
-\csbxint{Pow} is the initial synonym of \csa{xintiPow} which gets extended by
-\xintfracname to fractions (see
-also \csbxint{FloatPow} for which the exponent must still obey the \TeX{} bound
-and \csbxint{FloatPower} which has no restriction at all on the size of the
-exponent). Negative exponents do not then raise errors anymore. The float
-version is able to deal with things such as |2^999999999| without any problem.
-For example |\xintFloatPow[4]{2}{50000}|\dtt{=\xintFloatPow[4]{2}{50000}}
-and |\xintFloatPow[4]{2}{999999999}|
-\dtt{=\xintFloatPow[4]{2}{999999999}}.%
-%
-\footnote{On my laptop \texttt{\detokenize{\xintiiPow {2}{9999}}}
- obtains all |3010| digits in about ten or eleven seconds. In contrast,
- the float versions for |8|, |16|, |24|, or even more significant
- figures, do their jobs in less than one hundredth of a second
- (|1.09j|; we used in the text only four significant digits only for
- reasons of space, not time.) This is done without |log|/|exp| which
- are not (yet?) implemented in \xintfracname. The \LaTeX3
- \href{http://www.ctan.org/pkg/l3kernel}{l3fp} package does this with
- |log|/|exp| and is ten times faster, but allows only |16| significant
- figures and the (exactly represented) floating point numbers must have
- their exponents limited to $\pm$\dtt{9999}.}
+\xintfracname also provides the floating variants \csbxint{FloatPow} (for
+which the exponent must still obey the \TeX{} bound) and \csbxint{FloatPower}
+(which has no restriction at all on the size of the exponent). Negative
+exponents do not then raise errors anymore. The float version is able to deal
+with things such as |2^999999999| without any problem.
+\begin{everbatim*}
+$\xintFloatPow[32]{2}{50000}<\xintFloatPow[32]{2}{999999999}$
+\end{everbatim*}%
+and both are computed swiftly!\footnote{see however \autoref{fn:floatpow}.}
Within an \csbxint{iiexpr}|..\relax| the infix operator |^| is mapped to
\csa{xintiiPow}; within an \csbxint{expr}-ession it is mapped to \csbxint{Pow}
@@ -8254,18 +7959,31 @@ significance of the \textcolor[named]{PineGreen}{\Numf},
and \textcolor[named]{PineGreen}{$\star$} margin annotations and some
important background information.
-\subsection{\csbh{xintRev}} \label{xintRev}
+\subsection{\csbh{xintReverseDigits}} \label{xintReverseDigits}
-|\xintRev|\n\etype{f} will reverse the order of the digits of the number,
-keeping the optional sign. Leading zeroes
-resulting from the operation are not removed (see the
-\csa{xintNum} macro for this). This macro and all other
-macros dealing with numbers first expand `fully' their arguments.
-%
-\leftedline{|\xintRev{-123000}|\dtt{=\xintRev{-123000}}}
-%
-\leftedline{|\xintNum{\xintRev{-123000}}|%
- \dtt{=\xintNum{\xintRev{-123000}}}}
+|\xintReverseDigits|\n\etype{f} will reverse the order of the digits of the
+number, preserving an optional upfront minus sign. \csa{xintRev} is the former
+denomination and is kept as an alias to it. Leading zeroes resulting from the
+operation are not removed. Contrarily to \csbxint{ReverseOrder} this macro can
+only be used with digits and it first expands its argument (but beware that
+|-\x| will give an unexpected result as the minus sign immediately stops this
+expansion; one can use |\xintiiOpp{\x}| as argument.)
+
+This command has been rewritten for |1.2| and is faster for very long inputs.
+It is (almost) not used internally by the \xintcorename code, but the use
+of related routines explains to some extent the higher speed of release |1.2|.
+
+\begingroup
+\begin{everbatim*}
+\fdef\x{\xintReverseDigits
+ {-98765432109876543210987654321098765432109876543210}}\meaning\x\par
+\noindent\fdef\x{\xintReverseDigits {\xintReverseDigits
+ {-98765432109876543210987654321098765432109876543210}}}\meaning\x\par
+\end{everbatim*}
+\endgroup
+
+Notice that the output in this case with its leading zero is not in the strict
+integer format expected by the `|ii|' arithmetic macros.
\subsection{\csbh{xintLen}}\label{xintiLen}
@@ -8288,22 +8006,10 @@ have been returned by \csbxint{Raw}: |\xintRaw {-1e3/5.425}|\dtt{=\xintRaw
Let's point out that the whole thing should sum up to
less than circa $2^{31}$, but this is a bit theoretical.
-|\xintLen| is only for numbers or fractions. See \csbxint{Length} for counting
+|\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.
-\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
-
\subsection{\csbh{xintCmp}, \csbh{xintiiCmp}}
|\xintCmp|\n\m\etype{\Numf\Numf} returns \dtt{1} if |N>M|, \dtt{0} if |N=M|,
@@ -8441,9 +8147,7 @@ Important: the macro compares \emph{absolute values}.
|\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}}. The initial synonym \csbxint{Max}
-gets modified by \xintfracname which extends it to fractions. Its usage when
-only \xintname is loaded is discouraged.
+|\xintiMax {-5}{-6}|\dtt{=\xintiMax{-5}{-6}}.
The |\xintiiMax| macro skips the overhead of parsing the operands with
\csbxint{Num}.\etype{ff}
@@ -8453,9 +8157,7 @@ The |\xintiiMax| macro skips the overhead of parsing the operands with
|\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}}. The initial synonym \csbxint{Min}
-gets modified by \xintfracname which extends it to fractions. Its usage when
-only \xintname is loaded is discouraged.
+{-5}{-6}|\dtt{=\xintiMin{-5}{-6}}.
The |\xintiiMin| macro skips the overhead of parsing the operands with
\csbxint{Num}.\etype{ff}
@@ -8465,29 +8167,22 @@ The |\xintiiMin| macro skips the overhead of parsing the operands with
\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. \csbxint{Maxof} is the initial
-synonym which gets extended by \xintfracname to fractions. Do not use it when
-only \xintname is loaded.
+is submitted to |\xintNum| normalization.
\subsection{\csbh{xintiMinof}}\label{xintiMinof}
%{\small New with release |1.09a|.\par}
\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. \csbxint{Minof} is the initial
-synonym which gets extended by \xintfracname to fractions. Do not use it when
-only \xintname is loaded.
+is submitted to |\xintNum| normalization.
\subsection{\csbh{xintiiSum}}\label{xintiiSum}
\csa{xintiiSum}\marg{braced things}\etype{{\lowast f}} after expanding its
argument expects to find a sequence of tokens (or braced material). Each is
-expanded (with the usual meaning), and the sum of all these numbers is returned.
+\fexpan ded, and the sum of all these numbers is returned.
Note: the summands are \emph{not} parsed by \csbxint{Num}.
-\csbxint{Sum} is initially a synonym, it gets extended by \xintfracname to
-fractions.
-
%
\leftedline{%
\csa{xintiiSum}|{{123}{-98763450}{\xintFac{7}}{\xintiMul{3347}{591}}}|%
@@ -8533,7 +8228,6 @@ With \xintexprname, this would be easier:
%
\leftedline {|\xinttheiiexpr 2^200*3^100*7^100\relax |}
-The initial synonym \csbxint{Prd} is extended by \xintfracname to fractions.
% \subsection{\csbh{xintPrdExpr}}\label{xintiiPrdExpr}
@@ -8668,13 +8362,44 @@ odd integer and in that case executes the |YES| branch.
\subsection{\csbh{xintiFac}}\label{xintiFac}
-|\xintiFac|\x\etype{\numx} returns the factorial. It is an error if the
-argument is negative or at least $10^5$.% avant 1.09j c'était 1000000.
-
-|\xintFac| is a variant using |\xintNum| and thus, when \xintfracname is
-loaded, accepting a fraction on input (but it truncates it first).
+|\xintiFac|\x\etype{\numx} returns the factorial. It is an error on input if
+the argument is negative.
-% temps obsolètes, mettre à jour
+\begin{framed}
+ The macro will limits the acceptable inputs to a maximum of $9999$. However
+ the maximal computation depends on the values of some memory parameters of
+ the |tex| executable: with the 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}
+% \footnotetext{The computation with \xintname 1.2 of $5971!$ takes of the order
+% of 27 seconds on my laptop. And about half a second for the $2568$ digits of
+% $1000!$.}
+
+Package \xintfracname provides \csbxint{FloatFac} which allows to evaluate
+faster significant digits of big factorials and accepts (theoretically) inputs
+up to $99999999$. See \autoref{sec:examples} for the example of $2000!$ with
+$50$ significant digits.
+
+% avant 1.09j c'était 1000000.
+% avant 1.2 c'était 100000. (n'importe quoi!)
+
+|\xintFac| is the variant applying |\xintNum| on his input and thus, when
+\xintfracname is loaded, accepting a fraction on input (but it truncates it
+first).
+
+% avec xint1.2: 1000!, 2000!, 3000!
+% Mercredi 07 octobre 2015 à 14:34:20
+% (0.534s)
+% 402387260077093773543702, 2568, 4.023872600770938e2567.
+% (2.521s)
+% 331627509245063324117539, 5736, 3.316275092450633e5735.
+% (6.097s)
+% 414935960343785408555686, 9131, 4.149359603437854e9130.
+
+% ATTENTION TOTALEMENT MAIS TOTALEMENT OBSOLETE
+% JE CONSERVE UNIQUEMENT POUR ME SOUVENIR DU PASSÉ
+% ---- obsolète, remonte au premier xint
% On my laptop $1000!$ (2568 digits)
% is computed in a little less than ten seconds, $2000!$ (5736
% digits) is computed in a little less than one hundred seconds, and
@@ -8684,6 +8409,12 @@ loaded, accepting a fraction on input (but it truncates it first).
% transition from $N=9999$ to $10000$ and higher; $10000!$ has 35660
% digits). Not to mention $100000!$ which, from the Stirling formula,
% should have 456574 digits.
+% ---- (je rêvais à l'époque avec 100000! ...
+%
+% Je me souviens qu'au tout début je ne m'attendais pas du tout à rencontrer
+% de tels problèmes dès des nombres de quelques milliers de chiffres, car je
+% n'étais pas imprégné de la pénalité liée à parcourir par des macros
+% délimités de longues séquences de tokens
\subsection{\csbh{xintiiMON}, \csbh{xintiiMMON}}
\label{xintMON}\label{xintMMON}\label{xintiiMON}\label{xintiiMMON}
@@ -8884,6 +8615,7 @@ of \csa{xintDecSplit}.
\xintiiE {123}{89}
\end{everbatim*}
+\pagebreak
\section{Commands of the \xintfracname package}
\label{sec:frac}
@@ -9309,10 +9041,21 @@ xxx:_xint $
|
\endgroup
-Using |\xintTrunc| rather than |\xintXTrunc| would be hopeless on such long
-outputs (and even |\xintXTrunc| needed of the order of seconds to complete
-here). But it is not worth it to use |\xintXTrunc| for less than hundreds of
-digits.
+% \emph{Outdated note: Using |\xintTrunc| rather than |\xintXTrunc| would be
+% hopeless on such long outputs (and even |\xintXTrunc| needed of the order of
+% seconds to complete here). But it is not worth it to use |\xintXTrunc| for
+% less than hundreds of digits.}
+
+\begin{framed}
+ The |\xintiiMul {\ZA}{66049}| above can sadly \emph{not} be executed with
+ \xintname 1.2, due to the new limitation to at most about $19950$ digits for
+ multiplication. On the other hand |\edef\W {\xintXTrunc {131584}{1/66049}}|
+ produces the $131584$ digits four times faster. The macro \csbxint{XTrunc}
+ has not yet been adapted to the new integer model underlying the 1.2
+ \xintcorename macros, and perhaps some future improvements are possible. So
+ far it only benefits from a faster division routine, in that specific case
+ for a divisor having more than four but less than nine digits.
+\end{framed}
Fraction arguments to |\xintXTrunc| corresponding to a |A/B[N]| with a negative
|N| are treated somewhat less efficiently (additional memory impact) than for positive or zero |N|. This is because the algorithm tries to work with the
@@ -9600,6 +9343,17 @@ an integer format on output use \csbxint{iSqr}.
exactly and outputs in float format with precision |P| (which is optional), or
|\xintDigits| if |P| was absent, the result of this computation.
+\begin{framed}
+ It is obviously much needed that the author improves its algorithms to avoid
+ going through the exact |2P| or |2P-1| digits (plus safety digits) before
+ throwing to the waste-bin half of those digits !
+
+ \xintname initially was purely an \emph{exact} arbitrary precision
+ arithmetic machine, and the introduction of floating point numbers was an
+ after-thought. I got it working in release |1.07 (2013/05/25)| and never had
+ time to come back to it.
+\end{framed}
+
\subsection{\csbh{xintDiv}}\label{xintDiv}
Computes the algebraic quotient \etype{\Ff\Ff} of two fractions.
@@ -9621,13 +9375,34 @@ exactly and outputs in float format with precision |P| (which is optional), or
%{\small Modified in |1.08b| (to allow fractions on input).\par}
The original\etype{\Numf} is extended to allow a fraction |f| which will be
-truncated first to an integer |n| (non negative and at most |999999|, but
-already |100000!| is prohibitively time-costly). On output |n!| (with no
-trailing |/1[0]|).
+truncated first to an integer |n|. See \csbxint{iFac} for a discussion of the
+maximal allowed input.
+
+Output format is an integer without trailing |/1[0]|.
The original macro\etype{\numx} (which parses its input via |\numexpr|) is
still available as \csbxint{iFac}.
+\subsection{\csbh{xintFloatFac}}\label{xintFloatFac}
+
+\csa{xintFloatFac}|[P]{f}|\etype{{\upshape[\numx]}\Ff} returns the
+factorial.
+\begin{everbatim*}
+$1000!\approx{}$\xintFloatFac [30]{1000}
+\end{everbatim*}
+The computation\NewWith{1.2 !} proceeds via doing explicitely the product, as
+the Stirling formula cannot be used for lack so far of |exp/\log|.
+% \footnote{The computation of $100000!$ with $16$ digits of precision takes
+% about three or four seconds and for $1000000!$ it is about fifty seconds on
+% my laptop (2015/10/06).}
+%
+There is no a priori limit set on the |P| optional argument, thus the Stirling
+approach would become complicated if that freedom was to be obeyed.
+
+The macro |\xintFloatFac| chooses dynamically an appropriate number of
+digits for the intermediate computations, large enough to achieve the desired
+accuracy (hopefully).
+
\subsection{\csbh{xintPow}}\label{xintPow}
\csa{xintPow}{|{f}{g}|}:\etype{\Ff\Numf} computes |f^g| with |f| a fraction
@@ -9639,10 +9414,11 @@ vanishes: |\xintPow {2/3}{0}|\dtt{=\xintPow{2/3}{0}}).
The original
is available as \csbxint{iPow}.
-The exponent (after truncation to an integer) will be checked to not exceed
-|100000|. Indeed |2^50000| already has \dtt{\xintLen {\xintFloatPow
- [1]{2}{50000}}} digits, and squaring such a number would take hours (I
-think) with the expandable routine of \xintname.
+%%%%% OBSOLETE
+% The exponent (after truncation to an integer) will be checked to not exceed
+% |100000|. Indeed |2^50000| already has \dtt{\xintLen {\xintFloatPow
+% [1]{2}{50000}}} digits, and squaring such a number would take hours (I
+% think) with the expandable routine of \xintname.
\subsection{\csbh{xintFloatPow}}\label{xintFloatPow}
%{\small New with |1.07|.\par}
@@ -9688,7 +9464,16 @@ which is, in disguise, an integer.
The intermediate multiplications are done with a higher precision than
|\xintDigits| or the optional |P| argument, in order for the
-final result to hopefully have the desired accuracy.
+final result to hopefully have the desired accuracy.%
+%
+\footnote{\label{fn:floatpow}%
+ Release |1.2| did not change a single line of code to these macros because
+ they don't access low-level entry points. There is some sure important
+ efficiency gains to be obtained in maintaining internally the best inner
+ format for the successive squarings and multiplications, but I decided to
+ postpone that, as the more urgent issue is to improve \csbxint{FloatMul} to
+ not compute exactly with all digits the product before keeping only the
+ required digits.}
\subsection{\csbh{xintFloatSqrt}}\label{xintFloatSqrt}
%{\small New with |1.08|.\par}
@@ -9870,9 +9655,17 @@ be used when one is dealing exclusively with (big) integers.
\localtableofcontents
The \xintexprname package was first released with version |1.07|
-(|2013/05/25|) of the \xintname bundle. The package loads automatically
-\xintfracname and \xinttoolsname (it is now the only arithmetic package from the \xintname
-bundle which loads \xinttoolsname).
+(|2013/05/25|) of the \xintname bundle. It was substantially enhanced with
+release |1.1| from |2014/10/28|.
+
+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.
+
+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.
@@ -9886,30 +9679,32 @@ bundle which loads \xinttoolsname).
\end{everbatim*}
\end{itemize}
-Release |1.1| has brought many changes to \xintexprname.
-See \autoref{sec:expr11} if you are already familiar with the earlier versions.
+\begin{framed}
+ This documentation has repetitions, is a.t.t.of.w generally speaking not
+ well structured, and mixes old explanations dating back to the first release
+ and some more recent ones.
+\end{framed}
+
\subsection{The \csbh{xintexpr} expressions}\label{xintexpr}%
\label{xinttheexpr}\label{xintthe}
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.
-
-During this parsing, braced sub-content may be serving as usual as a macro
-parameter, or as a branch to the |?| two-way and |??| three-way operators.
-Prior to release |1.1|, there were also some other usage, but this has been
-removed. It was mainly needed because there was no other way to feed the
-number parser directtly with fractions in the |A/B[N]| notation which is the
-output format of the \xintfracname macros. There was no real need to use such
-macros anyhow. If one really wants to, one can now directly:
-\begin{everbatim*}
-\xinttheexpr \xintAdd{3/5[2]}{7/13[2]}+199/13[1]\relax
-\end{everbatim*}
-
-Notice in passing that the expressions benefit from the improved handling of
-denominators by \csbxint{Add} and \csbxint{Sub} from \xintfracname, which are
-the macros to which naturally |+| and |-| are mapped.
+\csbxint{expr}\meta{expandable\_expression}|\relax|\etype{x} where the
+expandable expression is read and completely expanded from left to right.
+
+% NOT THE GOOD LOCATION FOR THIS
+
+% During this parsing, braced sub-content may appear as usual as a macro
+% parameter, or as a branch to the |?| two-way and |??| three-way operators.
+% Prior to release |1.1|, there were also some other usage, but this has been
+% removed. It was mainly needed because there was no other way to feed the
+% number parser directtly with fractions in the |A/B[N]| notation which is the
+% output format of the \xintfracname macros. There was no real need to use such
+% macros anyhow. If one really wants to, one can now directly:
+% \begin{everbatim*}
+% \xinttheexpr \xintAdd{3/5[2]}{7/13[2]}+199/13[1]\relax
+% \end{everbatim*}
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
@@ -9928,7 +9723,7 @@ or |reduce|.%
number of digits of the fractional part; in |float| it is the total
number of digits of the mantissa.}
%
-Here are some examples\par
+Here are some examples\par % DO BETTER EXAMPLES !!!!!!!!!!!!!!!
\leftedline{|\xinttheexpr 1/5!-1/7!-1/9!\relax|%
\dtt{=\xinttheexpr 1/5!-1/7!-1/9!\relax}}
\leftedline{|\xinttheexpr round(1/5!-1/7!-1/9!,18)\relax|%
@@ -9974,7 +9769,438 @@ choice between parentheses or |\xintexpr...\relax|: |\def\x {(\a+\b)}|
or |\def\x {\xintexpr \a+\b\relax}|. The latter is the better choice as
it allows also to be prefixed with |\xintthe|. Furthemore, if |\a| and
|\b| are already defined |\edef\x {\xintexpr \a+\b\relax}| will do the
-computation on the spot. Rather than |\edef| one can use |\oodef|.
+computation on the spot.% Rather than |\edef| one can use |\oodef|.
+
+
+\subsection{Some features of the 1.1 release of \xintexprname}
+\label{sec:expr11}
+
+Release |1.1| brought many changes to \xintexprname. This chapter is for
+people already familiar with earlier versions. A more systematic item per item
+syntax description is provided in the next \autoref{sec:expr}. Both this
+section and the next are in need of being improved.
+
+First, there were some breaking changes:
+\begin{itemize}[parsep=0pt, labelwidth=\leftmarginii,
+ itemindent=0pt, leftmargin=\leftmarginii]
+ \item in |\xintiiexpr|, |/| does \emph{rounded} division, rather than as
+ in earlier releases the
+ Euclidean division (for positive arguments, this is truncated division).
+ The new |//| operator does truncated division,
+ \item the |:| operator for three-way branching is gone, replaced with |??|,
+ \item |1e(3+5)| is now illegal. The number parser identifies |e| and |E|
+ in the same way it does for the decimal mark, earlier versions treated
+ |e| as |E| rather as postfix operators,
+ \item the |add| and |mul| have a new syntax, old syntax is with |`+`| and
+ |`*`| (quotes mandatory), |sum| and |prd| are gone,
+ \item no more special treatment for encountered brace pairs |{..}| by the
+ number scanner, |a/b[N]| notation can be used without use of braces (the
+ |N| will end up space-stripped in a |\numexpr|, it is not parsed by the
+ |\xintexpr|-ession scanner).
+ \item although |&| and \verb+|+ are still available as Boolean operators the
+ use of |&&| and \verb+||+ is strongly recommended. The single
+ letter operators might be assigned some other meaning in later releases
+ (bitwise operations, perhaps). Do not use them.
+ \item place holders for |\xintNewExpr|
+ could be denoted |#1|, |#2|, ... or also, for special purposes |$1|, |$2|,
+ ... Only the first form is now accepted and the special cases previously
+ treated via the second form are now managed via a |protect(...)| function.
+\end{itemize}
+
+Let's now describle some of the numerous additional functionalities.
+
+\begin{itemize}[parsep=0pt, labelwidth=\leftmarginii,
+ itemindent=\leftmarginii, leftmargin=0em]
+ \item |\xintiexpr|, |\xinttheiexpr| admit an optional argument within
+ brackets |[d]|, it then presents the computation result (or results, if
+ comma separated) after rounding to |d| digits after decimal mark, (the
+ whole computation is done exactly, as in |xintexpr|),
+\begin{everbatim*}
+\xinttheiexpr [32] 1.23^50, 1.231^50\relax
+\end{everbatim*}
+ \item |\xintfloatexpr|, |\xintthefloatexpr| similarly admit an optional
+ argument which serves to keep only |d| digits of precision, getting rid
+ of cumulated uncertainties in the last digits (the whole computation is
+ done according to the precision set via |\xintDigits|),
+\begin{everbatim*}
+\xintDigits:=32;\xintthefloatexpr 1.010101^10-1.0101^10\relax
+
+\xintDigits:=16;\xintthefloatexpr 1.010101^10-1.0101^10\relax
+
+\xintthefloatexpr [12] 1.010101^10-1.0101^10\relax
+\end{everbatim*}
+
+ \item |\xinttheexpr| and |\xintthefloatexpr| ``pretty-print'' if possible,
+ the former removing unit denominator or |[0]| brackets, the latter
+ avoiding scientific notation if decimal notation is practical,
+ \item the |//| does truncated division and |/:| is the associated modulo,
+ \item multi-character operators |&&|, \verb+||+, |==|, |<=|, |>=|, |!=|,
+ |**|,
+ \item multi-letter infix binary words |'and'|, |'or'|, |'xor'|, |'mod'|
+ (quotes mandatory),
+ \item functions |even|, |odd|, |first|, |last|,
+ \item |\xintdefvar A3:=3.1415;| for variable definitions (non expandable,
+ naturally), usable in subsequent expressions; variable names may contain
+ letters, digits, underscores. They should not start with a digit, the
+ |@| is reserved, and single lowercase and uppercase Latin letters are
+ predefined to work as dummy variables (see next),
+ \item generation of comma separated lists |a..b|, |a..[d]..b|,
+ \item Python syntax-like list extractors |[list][n:]|, |[list][:n]|, |[list][a:b]|
+ and |[list][n]| (|n=0| for the number of list items), the step is always
+ |+1|,
+ \item function |reversed|, to reverse the order of list items,
+ \item itemwise sequence operations |a*[list]|, etc.., on both sides |a*[list]^b|,
+ \item dummy variables in |add| and |mul|: |add(x(x+1)(x-1), x=-10..10)|,
+ \item variable substitutions with |subs|: |subs(subs(add(x^2+y^2,x=1..y),y=t),t=20)|,
+ \item sequence generation using |seq| with a dummy variable: |seq(x^3, x=-10..10)|,
+ \item simple recursive sequences with |rseq|, with |@| given the last value,
+ |rseq(1;2@+1,i=1..10)|,
+ \item higher recursion with |rrseq|, |@1|, |@2|, |@3|, |@4|, and |@@(n)|
+ for earlier values, up to |n=K| where |K| is the number of terms of the
+ initial stretch |rrseq(0,1;@1+@2,i=2..100)|,
+ \item iteration with |iter| which is like |rrseq| but outputs only the
+ last |K| terms, where |K| was the number of initial terms,
+ \item inside |seq|, |rseq|, |rrseq|, |iter|, possibility to use |omit|,
+ |abort| and |break| to control termination,
+ \item |n++| potentially infinite index generation for |seq|, |rseq|,
+ |rrseq|, and |iter|, it is advised to use |abort| or |break(..)| at
+ some point,
+ \item the |add|, |mul|, |seq|, ... are nestable,%
+\footnote{but |add(seq(x,x=1..t),t=1..2)| fails for the reason that |add| will
+ receive not a list of numbers but a list of lists.}
+ \item |\xintthecoords| converts a comma separated list of an even number
+ of items to the format as expected by the |TikZ| |coordinates| syntax,
+ \item completely rewritten |\xintNewExpr|, new |protect| function to handle
+ external macros. However not all constructs are compatible with
+ |\xintNewExpr|.
+\end{itemize}
+
+% \subsection{Examples with the \texorpdfstring{\unexpanded{\unexpanded{|v1.1|}}}{v1.1} \csh{xintexpr}}
+
+And now some examples:
+
+\begin{itemize}[parsep=0pt, labelwidth=\leftmarginii,
+ itemindent=\leftmarginii, leftmargin=0em]
+\item One can define variables (the definition itself is a non expandable
+ step). The allowed names are composed of letters, digits, and underscores.
+ The variable should not start with a digit and single letters |a..z|, |A..Z|
+ are predefined for use as dummy variables --- see below. The |@| is
+ reserved.
+\begin{everbatim*}
+\begingroup
+ \xintdefvar a_1 := 3.14159;\xintdefvar a2 := 2.71828;\xinttheiexpr [5] a_1+a2\relax
+\endgroup
+\end{everbatim*}
+\item |add| and |mul| have a new syntax requiring a dummy variable:
+\begin{everbatim*}
+\xinttheexpr add(x, x=1,3,19), mul(x^2, x=1,3,19), add(x(x+1), x= 1,3,19)\relax
+\end{everbatim*}
+
+Use |`+`| and |`*`| (left ticks mandatory) for syntax without dummy variables:
+\begin{everbatim*}
+\xinttheexpr `+`(1,3,19), `*`(1^2,3^2,19^2), `+`(1*2,3*4,19*20)\relax
+\end{everbatim*}
+\item The |seq| function generates sequences according to a given formula:
+\begin{everbatim*}
+\xinttheexpr seq(x(x+1)(x+2), x=1,3,19), `+`(seq(x(x+1)(x+2), x=1,3,19)),
+ add(x(x+1)(x+2), x=1,3,19)\relax
+\end{everbatim*}
+\begin{everbatim*}
+And this is nestable!
+\xinttheexpr seq(seq(x^y, y=1..5),x=1..5), add(mul(x^y,y=1..5), x=1..5),
+ add(x^15, x=1..5)\relax % 15 = 1+2+3+4+5
+\end{everbatim*}
+
+One should use parentheses appropriately. The \csbxint{expr} parser in normal
+operation is not bad at identifying missing or extra opening or closing
+parentheses, but when it handles |seq|, |add|, |mul| or similar constructs it
+switches to another mode of operation (it starts using delimited macros,
+something which is almost non-existent in all its other operations) and ill-formed
+expressions are much more likely to let the parser fetch tokens from beyond the
+mandatory ending |\relax|. Thus, in case of a missing parenthesis in such
+circumstances the error message from \TeX{} might be very cryptic, even for
+the seasoned \xintname user.
+
+\item As seen in the last example |a..b| constructs the integers from |a| to
+ |b|. This is (small) integer only. A more general |a..[d]..b| works with big
+ integers, or fractions, from |a| to |b| with step |d|.
+\begin{everbatim*}
+\xinttheexpr seq(2x+1, x=1..10, 100..110, 3/5..[1/5]..7/5)\relax
+\end{everbatim*}
+\item itemwise operations on lists are possible, as well as item extractions:
+\begin{everbatim*}
+\xinttheiiexpr 2*[1,10,100]^3, 5+[2*[1,10,100]^3]*100 \relax
+\end{everbatim*}
+\begin{everbatim*}
+\xinttheiiexpr 1+[seq(3^j, j=1..10, 21..30)][17], 1+3^27\relax
+\end{everbatim*}
+
+We used the |[list][n]| construct which gives the nth item from the list. In
+this context there are also the functions |last| and |first|. There is no real
+concept of a list object, nor list operations, although itemwise manipulation
+are made possible as shown above via the |[..]| constructor. The list
+manipulation utilities are so far a bit limited. There is no notion of an
+``nuple'' object. The variable |nil| is reserved, it represents an empty list.
+
+\item |subs| is similar to |seq| in syntax but is for variable substitution:
+\begin{everbatim*}
+\xinttheexpr subs(100*subs(10*subs(3*x+5,x=y+50)+2,y=z^2),z=10)\relax % 100(10(3*150+5)+2)
+\end{everbatim*}
+\begin{everbatim*}
+\xinttheexpr subs(subs(add(x^2+y^2,x=1..y),y=t),t=20)\relax
+\end{everbatim*}
+
+The substituted variable may be a comma separated list (this is impossible
+with |seq| which will always pick one item after the other of a list).
+\begin{everbatim*}
+\xinttheexpr subs([x]^2,x=-123,17,32)\relax
+\end{everbatim*}
+
+\item last but not least, |seq| has variants |rseq| and |rrseq| which allow
+ recursive definitions. They start with at least one initial value, then a
+ semi-colon, then the formula, then the list of indices to iterate over. |@|
+ (or |@1|) evaluates to the last computed item, and |rrseq| keeps the memory
+ of the |K| last results, where |K| was the number of initial terms. One
+ accesses them via |@1, @2, @3, @4| and |@@(N)| for |N>4|. It is even
+ possible to nest them and use |@@@| to access the values of the master
+ recursion...
+\begin{everbatim*}
+\xinttheiiexpr rseq(1; 2*@, i=1..10), `+`(rseq(1; 2*@, i=1..10))\relax
+\end{everbatim*}
+\begin{everbatim*}
+\xinttheiiexpr rseq(2; @(@+1)/2, i=1..5)\relax
+\end{everbatim*}
+\begin{everbatim*}
+\xinttheiiexpr rseq(0,1; (@1,add(x,x=@1)), y=2..10)\relax
+\end{everbatim*}
+
+Some Fibonacci fun
+\begin{everbatim*}
+\xinttheiiexpr rrseq(0,1; @1+@2, x=2..10), last(rrseq(0,1; @1+@2, x=2..100))\relax
+\end{everbatim*}
+\begin{everbatim*}
+Sum of previous last three: \xinttheiiexpr rrseq(0,0,1; @1+@2+@3, i=1..20)\relax
+\end{everbatim*}
+\begin{everbatim*}
+Big numbers: \printnumber{\xinttheexpr rseq(1; @(@+1), j=1..10)\relax }
+\end{everbatim*}
+
+Nested recursion often quickly leads to gigantic outputs. This is an
+experimental feature, susceptible to be removed or altered in the future.
+\begin{everbatim*}
+\xinttheexpr rrseq(1; `+`(rrseq(0,1; @@@(1)+@1+@2, i=1..10)), j=1..5)\relax
+\end{everbatim*}
+
+\item The special keywords |omit|, |abort| and |break(..)| are available
+ inside |seq|, |rseq|, |rrseq|, as well as the |n++| for a potentially
+ infinite iteration. The |n++| construct in conjunction with an |abort| or
+ |break| is often more efficient, because in other cases the list to iterate
+ over is first completely constructed.
+\begin{everbatim*}
+First Fibonacci number at least |2^31| and its index
+\xinttheiiexpr iter(0,1; (@1>=2^31)?{break(i)}{@2+@1}, i=1++)\relax
+\end{everbatim*}
+
+\begin{everbatim*}
+Prime numbers are always cool
+\xinttheiiexpr seq((seq((subs((x/:m)?{(m*m>x)?{1}{0}}{-1},m=2n+1))
+ ??{break(0)}{omit}{break(1)},n=1++))?{x}{omit},
+ x=10001..[2]..10200)\relax
+\end{everbatim*}
+
+The syntax in this last example may look a bit involved. First |x/:m| computes
+|x modulo m| (this is the modulo with respect to truncated division, which
+here for positive arguments is like Euclidean division; in
+|\xintexpr...\relax|, |a/:b| is such that |a = b*(a//b)+a/:b|, with |a//b| the
+algebraic quotient |a/b| truncated to an integer.). The |(x)?{yes}{no}|
+construct checks if |x| (which \emph{must} be within parentheses) is true or
+false, i.e. non zero or zero. It then executes either the |yes| or the |no|
+branch, the non chosen branch is \emph{not} evaluated. Thus if |m| divides |x|
+we are in the second (``false'') branch. This gives a |-1|. This |-1| is the
+argument to a |??| branch which is of the type |(y)??{y<0}{y=0}{y>0}|, thus here
+the |y<0|, i.e., |break(0)| is chosen. This |0| is thus given to another |?|
+which consequently chooses |omit|, hence the number is not kept in the list.
+The numbers which survive are the prime numbers.
+
+% A006877 In the `3x+1' problem, these values for the starting value set new
+% records for number of steps to reach 1. (Formerly M0748) 14 1, 2, 3, 6, 7,
+% 9, 18, 25, 27, 54, 73, 97, 129, 171, 231, 313, 327, 649, 703, 871, 1161,
+% 2223, 2463, 2919, 3711, 6171, 10971, 13255, 17647, 23529, 26623, 34239,
+% 35655, 52527, 77031, 106239, 142587, 156159, 216367, 230631, 410011, 511935,
+% 626331, 837799
+
+\item The |iter| function is like |rrseq| but does not leave a trace of earlier items,
+ it starts with |K| initial values, then it iterates: either a fixed number of times,
+ or until aborting or breaking. And ultimately it prints |K| final values.
+\begin{everbatim*}
+The first Fibonacci number beyond the \TeX{} bound is
+\xinttheiiexpr subs(iter(0,1;(@1>N)?{break(i)}{@1+@2},i=1++),N=2^31)\relax{}
+and the previous number was its index.
+\end{everbatim*}But this was a bit too easy, what is the smallest Fibonacci number not representable on 64 bits?
+\begin{everbatim*}
+The first Fibonacci number beyond |2^64| bound is
+\xinttheiiexpr subs(iter(0,1;(@1>N)?{break(i)}{@1+@2},i=1++),N=2^64)\relax{}
+and the previous number was its index.
+\end{everbatim*}
+
+One more recursion:
+\begin{everbatim*}
+\def\syr #1{\xinttheiiexpr rseq(#1; (@<=1)?{break(i)}{odd(@)?{3@+1}{@//2}},i=0++)\relax}
+The 3x+1 problem: \syr{231}\par
+\end{everbatim*}
+
+Ok, a final one:
+\begin{everbatim*}
+\def\syrMax #1{\xinttheiiexpr iter(#1,#1;even(i)?
+ {(@2<=1)?{break(i/2)}{odd(@2)?{3@2+1}{@2//2}}}
+ {(@1>@2)?{@1}{@2}},i=0++)\relax }
+With initial value 1161, the maximal number attained is \syrMax{1161} and that latter
+number is the number of steps which was needed to reach 1.\par
+\end{everbatim*}
+
+Well, one more:
+
+\begin{everbatim*}
+\newcommand\GCD [2]{\xinttheiiexpr rrseq(#1,#2; (@1=0)?{abort}{@2/:@1}, i=1++)\relax }
+\GCD {13^10*17^5*29^5}{2^5*3^6*17^2}
+\end{everbatim*}
+
+and the ultimate:
+
+\begin{everbatim*}
+\newcommand\Factors [1]{\xinttheiiexpr
+ subs(seq((i/:3=2)?{omit}{[L][i]},i=1..([L][0])),
+ L=rseq(#1;(p^2>[@][1])?{([@][1]>1)?{break(1,[@][1],1)}{abort}}
+ {(([@][1])/:p)?{omit}
+ {iter(([@][1])//p; (@/:p)?{break(@,p,e)}{@//p},e=1++)}},p=2++))\relax }
+\Factors {41^4*59^2*29^3*13^5*17^8*29^2*59^4*37^6}
+\end{everbatim*}
+
+This might look a bit scary, I admit. \xintexprname has minimal tools and
+is obstinate about doing everything expandably! We are hampered by absence of a
+notion of ``nuple''. The algorithm divides |N| by |2| until no more possible,
+then by |3|, then by |4| (which is silly), then by |5|, then by |6| (silly
+again), \dots.
+
+The variable |L=rseq(#1;...)| expands, if one follows the steps, to a comma
+separated list starting with the initial (evaluated) |N=#1| and then
+pseudo-triplets where the first item is |N| trimmed of small primes, the
+second item is the last prime divisor found, and the third item is its
+exponent in original |N|.
+
+The algorithm needs to keep handy the last computed quotient by prime powers,
+hence all of them, but at the very end it will be cleaner to get rid of them
+(this corresponds to the first line in the code above). This is achieved in a
+cumbersome inefficient way; indeed each item extraction |[L][i]| is costly: it
+is not like accessing an array stored in memory, due to expandability, nothing
+can be stored in memory! Nevertheless, this step could be done here in a far
+less inefficient manner if there was a variant of |seq| which, in the spirit
+of \csbxint{iloopindex}, would know how many steps it had been through so far.
+This is a feature to be added to |\xintexpr|! (as well as a |++| construct
+allowing a non unit step).
+
+Notice that in |iter(([@][1])//p;| the |@| refers to the previous triplet (or
+in the first step to |N|), but the latter |@| showing up in |(@/:p)?| refers
+to the previous value computed by |iter|.
+
+\begin{snugframed}
+ Parentheses are essential in |..([y][0])| else the parser will see |..[| and
+ end up in ultimate confusion, and also in |([@][1])/:p| else the parser will
+ see the itemwise operator |]/| on lists and again be very confused (I could
+ implement a |]/:| on lists, but in this situation this would also be very
+ confusing to the parser.)
+\end{snugframed}
+
+For comparison, here is an \fexpan dable macro expanding to the same result,
+but coded directly with the \xintname macros. Here |#1| can not be itself an
+expression, naturally. But at least we let |\Factorize| \fexpan d its
+argument.
+\begin{everbatim}
+\makeatletter
+\newcommand\Factorize [1]
+ {\romannumeral0\expandafter\factorize\expandafter{\romannumeral-`0#1}}%
+\newcommand\factorize [1]{\xintiiifOne{#1}{ 1}{\factors@a #1.{#1};}}%
+\def\factors@a #1.{\xintiiifOdd{#1}
+ {\factors@c 3.#1.}%
+ {\expandafter\factors@b \expandafter1\expandafter.\romannumeral0\xinthalf{#1}.}}%
+\def\factors@b #1.#2.{\xintiiifOne{#2}
+ {\factors@end {2, #1}}%
+ {\xintiiifOdd{#2}{\factors@c 3.#2.{2, #1}}%
+ {\expandafter\factors@b \the\numexpr #1+\@ne\expandafter.%
+ \romannumeral0\xinthalf{#2}.}}%
+}%
+\def\factors@c #1.#2.{%
+ \expandafter\factors@d\romannumeral0\xintiidivision {#2}{#1}{#1}{#2}%
+}%
+\def\factors@d #1#2#3#4{\xintiiifNotZero{#2}
+ {\xintiiifGt{#3}{#1}
+ {\factors@end {#4, 1}}% ultimate quotient is a prime with power 1
+ {\expandafter\factors@c\the\numexpr #3+\tw@.#4.}}%
+ {\factors@e 1.#3.#1.}%
+}%
+\def\factors@e #1.#2.#3.{\xintiiifOne{#3}
+ {\factors@end {#2, #1}}%
+ {\expandafter\factors@f\romannumeral0\xintiidivision {#3}{#2}{#1}{#2}{#3}}%
+}%
+\def\factors@f #1#2#3#4#5{\xintiiifNotZero{#2}
+ {\expandafter\factors@c\the\numexpr #4+\tw@.#5.{#4, #3}}%
+ {\expandafter\factors@e\the\numexpr #3+\@ne.#4.#1.}%
+}%
+\def\factors@end #1;{\xintlistwithsep{, }{\xintRevWithBraces {#1}}}%
+\makeatother
+\end{everbatim}
+
+The macro |\Factorize| puts a little stress on the input save stack in order
+not be bothered with previously gathered things. I timed it to be about eight
+times faster than |\Factors| in test cases such as
+|16246355912554185673266068721806243461403654781833| and others. Among the
+various things explaining the speed-up, there is fact that we step by
+increments of two, not one, and also that we divide only once, obtaining
+quotient and remainder in one go. These two things already make for a speed-up
+factor of about four. Thus, our earlier |\Factors| was not completely
+inefficient, and was quite easier to come up with than |\Factorize|.
+
+If we only considered small integers, we could write pure |\numexpr| methods
+which would be very much faster (especially if we had a table of small primes
+prepared first) but still ridiculously slow compared to any non expandable
+implementation, not to mention use of programming languages directly accessing
+the CPU registers\dots
+\end{itemize}
+
+%\phantomsection
+\phantomsection\label{sec:expr11coords}
+
+To conclude with this overview of the new features in \xintexprname |1.1|, I
+will mention {\bfseries |\xintthecoords|} which converts a comma separated
+list as produced by |\xintfloatexpr| or |\xintiexpr [d]| to the format
+expected by the |TikZ| |coordinates| syntax.
+\begin{everbatim*}
+{\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 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}\par }
+\end{everbatim*}
+
+% Notice: if x goes no take exactly value 1 or -1, the origin appears slightly
+% off the curve, not MY fault!!!
+
+\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.
+
+\begin{everbatim*}
+\edef\x{\xintthecoords \xintexpr rrseq(1/2,1/3; @1+@2, x=1..20)\relax }
+\meaning\x +++
+\end{everbatim*}
\subsection{The syntax}\label{ssec:syntax}
@@ -10001,12 +10227,13 @@ two |t|'s.
|\xintexpr|-essions and |\xinttheexpr|-essions are completely expandable, in two steps.
\begin{itemize}[parsep=0pt, labelwidth=\leftmarginii,
- itemindent=\leftmarginii, leftmargin=0em]
+ itemindent=0pt, 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.
+ output each comma will be followed by a space. A decimal number must have
+ digits either before or after the decimal mark.\MyMarginNote{Changed!}
\item as everything gets expanded, the characters |.|, |+|, |-|, |*|, |/|, |^|,
|!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, |=|, |(|, |)|, |"|, |]|, |[|, |@|
@@ -10031,7 +10258,8 @@ two |t|'s.
\item The |!| is either a
function (the logical not) requiring an argument within parentheses, or a
- post-fix operator which does the factorial (so far, no float version).
+ post-fix operator which does the factorial. In \csbxint{floatexpr} it is
+ mapped to \csbxint{FloatFac}, else it computes the exact factorial.
\item The |?| may serve either as a function (the truth value) requiring an
argument within parentheses), or as two-way post-fix branching operator
@@ -10264,10 +10492,10 @@ operators and functions.
|?| and |!| (as prefix) require parentheses around their arguments.
\begin{snugframed}
- \ctexttt{num, reduce, abs, sgn, frac, floor, ceil, sqr, sqrt, sqrtr, float,
- round, trunc, mod, quo, rem, gcd, lcm, max, min, `+`, `*`, ?, !, not,
- all, any, xor, if, ifsgn, even, odd, first, last, reversed, bool,
- togl, add, mul, seq, subs, rseq, rrseq, iter}
+ \ctexttt{num, qint, qfrac, qfloat, reduce, abs, sgn, frac, floor, ceil,
+ sqr, sqrt, sqrtr, float, round, trunc, mod, quo, rem, gcd, lcm, max,
+ min, `+`, `*`, ?, !, not, all, any, xor, if, ifsgn, even, odd, first,
+ last, reversed, bool, togl, add, mul, seq, subs, rseq, rrseq, iter}
|quo|, |rem|, |even|, |odd|, |gcd| and |lcm| will first truncate their
arguments to integers; the latter two require package \xintgcdname;
@@ -10275,8 +10503,11 @@ operators and functions.
|`*`|, |max| and |min| are functions with arbitrarily many comma
separated arguments.
- |bool| and |togl| use delimited macros to fetch their argument whose
- closing parenthesis thus must be explicit, not arising from expansion.
+ |bool|, |togl| use delimited macros to fetch their argument and the
+ closing parenthesis which thus must be explicit, not arising from
+ expansion.
+
+ The same holds for |qint|, |qfrac|, |qfloat|.\NewWith{1.2}
Similarly |add|, |mul|, |subs|, |seq|, |rseq|, |rrseq|, |iter| use at
some stages delimited macros. They work with \emph{dummy variables},
@@ -10298,11 +10529,34 @@ operators and functions.
\item[functions with a single (numeric) argument]
\noindent\par
\begin{description}
- \item[num] truncates to the nearest integer (truncation towards zero)
+ \item[num] truncates to the nearest integer (truncation towards zero).
\begin{everbatim*}
\xinttheexpr num(3.1415^20)\relax
\end{everbatim*}
+ \item[qint] skips the token by token parsing of the input. The ending
+ parenthesis must be physically present rather than arising from
+ expansion.\NewWith{1.2} The |q| stands for ``quick''. This ``function''
+ handles the input exactly like do the |i| macros of \xintcorename, via
+ \csbxint{iNum}. Hence leading signs and the leading zeroes (coming next)
+ will be handled appropriately but spaces will not be systematically
+ stripped. They should cause no harm and will be removed as soon as the
+ number is used with one of the basic operators. This input form \emph{does
+ not accept decimal part or scientific part}.
+\begin{everbatim}
+\def\x{....many many many ... digits}\def\y{....also many many many digits...}
+\xinttheiiexpr qint(\x)*qint(\y)+qint(\y)^2\relax
+\end{everbatim}
+
+ \item[qfrac] does the same as \dtt{qint} excepts that it accepts fractions,
+ decimal numbers, scientific numbers as they are understood by the macros of
+ package\NewWith{1.2} \xintfracname. Not to be used within an
+ |\xintiiexpr|-ession, except if hidden inside functions such as
+ \dtt{round} or \dtt{trunc} which produce integers from fractions.
+
+ \item[qfloat] does the same as \dtt{qfrac} and converts to a float with the
+ precision given by the setting of |\xintDigits|.
+
\item[reduce] reduces a fraction to smallest terms
\begin{everbatim*}
\xinttheexpr reduce(50!/20!/20!/10!)\relax
@@ -10567,7 +10821,6 @@ Refer to \autoref{sec:expr11} for more examples.
\item The postfix operators \ctexttt{!} and the branching conditionals \ctexttt{?, ??}.
\begin{description}
\item[{\color[named]{DarkOrchid}!}] computes the factorial of an integer.
- This is the exact factorial even when used inside |\xintfloatexpr|.
\item[{\color[named]{DarkOrchid}?}] is used as |(cond)?{yes}{no}|. It
evaluates the (numerical) condition (any non-zero value counts as
@@ -10610,13 +10863,16 @@ Refer to \autoref{sec:expr11} for more examples.
optional and unique component of a being formed number. One can do
things such as
%
- \leftedline{\restoreMicroFont|\xinttheexpr .^2+2^.\relax|}
+ \leftedline{\restoreMicroFont|\xinttheexpr 0.^2+2^.0\relax|}
%
- which is |0^2+2^0| and produces \dtt{\xinttheexpr .^2+2^.\relax}.
+ which is |0^2+2^0| and produces \dtt{\xinttheexpr 0.^2+2^.0\relax}.
+
+ However a single dot |"."| as in |\xinttheexpr .^2\relax| is now illegal
+ input.\MyMarginNote{Changed!}
\item The |e| and |E| for scientific notation. They are parsed
- like the decimal mark is. Thus |1e(3+2)| is no legal syntax anymore, one
- must use |10^(3+2)| in such cases.
+ like the decimal mark is.% Thus |1e(3+2)| is no legal syntax anymore, one
+ % must use |10^(3+2)| in such cases.
\begingroup
\restoreMicroFont |1e3^2| is \dtt{\xinttheexpr 1e3^2\relax}
\endgroup
@@ -10726,22 +10982,39 @@ one obtains as output \xinttheexpr 2^3,3^4,5^6\relax{}.
dimexpr} expressions, count and dimension registers and variables}
\label{ssec:countinexpr}
-Count registers, count control sequences, dimen registers,
-dimen control sequences, skips and skip control sequences, |\numexpr|,
-|\dimexpr|, |\glueexpr| 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). 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|.
+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).
+
+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|.
+
+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 |\fontcharit| \eTeX{}
+primitives.
+
+In the case of numbered registers like |\count255| or |\dimen0| (or |\ht0|),
+the resulting digits will be re-parsed, so for example |\count255 0| is like
+|100| if |\the\count255| would give |10|. The same happens with inputs such
+as |\fontdimen6\font|. And |\numexpr 35+52\relax| will be exactly as if |87|
+as been encountered by the parser, thus more digits may follow: |\numexpr
+35+52\relax 000| is like |87000|. If a new |\numexpr| follows, it is treated
+as what would happen when |\xintexpr| scans a number and finds a non-digit: it
+does a tacit multiplication.
+\begin{everbatim*}
+\xinttheexpr \numexpr 351+877\relax\numexpr 1000-125\relax\relax{} is the same
+as \xinttheexpr 1228*875\relax.
+\end{everbatim*}
-In the case of numbered registers like |\count255| or |\dimen0|, the resulting
-digits will be re-parsed, so for example |\count255 0| is like |100| if
-|\the\count255| would give |10|. Control sequences define complete numbers, thus
-cannot be extended that way with more digits, on the other hand they are more
-efficient as they avoid the re-parsing of their unpacked contents.
+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.
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
@@ -10750,17 +11023,8 @@ 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|.
-% REVOIR
-% If one needs to optimize, |1.72\dimexpr 3.2pt\relax| is less efficient
-% than |1.72*{\number\dimexpr 3.2pt\relax}| as the latter avoids re-parsing the
-% digits of the representation of the dimension as scaled points.
-% \centeredline{|\xinttheexpr 1.72\dimexpr 3.2pt\relax/2.71828\relax=|}
-% \centeredline{|\xinttheexpr 1.72*{\number\dimexpr 3.2pt\relax}/2.71828\relax|}
-% \centeredline{\dtt{\xinttheexpr 1.72\dimexpr
-% 3.2pt\relax/2.71828\relax=\xinttheexpr 1.72*{\number\dimexpr
-% 3.2pt\relax}/2.71828\relax}}
Regarding how dimensional expressions are converted by \TeX{} into scaled points
-see \autoref{sec:Dimensions}.
+see also \autoref{sec:Dimensions}.
\subsection{Catcodes and spaces}
@@ -10801,10 +11065,15 @@ The characters |+|, |-|, |*|, |/|, |^|, |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|,
in the expression, as everything is expanded along the way. If one of them is
active, it should be prefixed with |\string|.
-The |!| as either logical negation or postfix factorial operator must be a
-standard (\emph{i.e.} catcode $12$) |!|, more precisely a catcode $11$
-exclamation point |!| must be avoided as it is used internally by |\xintexpr|
-for various special purposes.
+The exclamation mark should have its standard catcode, because it is used for
+internal purposes with a different one.
+
+% TOO TECHNICAL
+%
+% The |!| as either logical negation or postfix factorial operator must be a
+% standard (\emph{i.e.} catcode $12$) |!|, more precisely a catcode $11$
+% exclamation point |!| must be avoided as it is used internally by |\xintexpr|
+% for various special purposes.
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''.
@@ -11010,7 +11279,7 @@ And this works:
\item \FA{1}{3}{90}{-40}{-15}
\item \FA{1.234}{-0.123}{-10}{3}{7}
\end{itemize}
-\oodef\test {\FA {0}{10}{100}{3}{6}}\meaning\test +++
+\fdef\test {\FA {0}{10}{100}{3}{6}}\meaning\test +++
\end{everbatim*}
In the last example though, do not hope to use empty |#4| or |#5|: this is
@@ -11157,30 +11426,34 @@ 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 |/| can not be used!
-This dilemma is solved using |protect|. For understanding the
-next example, 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}.
+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}.
-\begin{everbatim*}
-\xinttheiiexpr 5/3, round(5/3,3), trunc(5/3,3), trunc(\xintDiv {5}{3},3),
-trunc(\xintRaw {5/3},3)\relax{},
-but \xinttheiiexpr 5/3, round(protect(5/3),3), trunc(protect(5/3),3), floor(protect(5/3)),
-ceil(protect(5/3))\relax{} works!
-\noindent And with negative numbers: \xinttheiiexpr -5/3, round(protect(-5/3),3),
-trunc(protect(-5/3),3), floor(protect(-5/3)), ceil(protect(-5/3))\relax.
+\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.
-Decimal numbers and numbers using scientific notations must be given as
-arguments to one of the |num|, or |round|, or etc\dots functions, which will truncate
-them to an integer.%
- Internally the number will be represented with as many zeros
-as is necessary, thus one does not want to do |num(1e100000)| for example!
+\begin{framed}
+ Scientific numbers are either rounded (in case of negative exponent) or
+ 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*}
@@ -11193,8 +11466,8 @@ 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| on
-their output,
+One can use the Float macros if one is careful to use |num|, or |round|
+etc\dots on their output.
\begin{everbatim*}
\xinttheiiexpr \xintFloatSqrt [20]{2}, \xintFloatSqrt [20]{3}\relax % no operations
@@ -11207,14 +11480,17 @@ their output,
decimal mark one should keep.)
\end{everbatim*}
-The whole point of \csbxint{iiexpr} is to gain some speed in \emph{integer-only}
-algorithms, and the above explanations related to how to nevertheless use
-fractions therein are a bit peripheral. We observed of the order of
-$30$\% speed gain when dealing with numbers with circa one hundred digits, but this
-gain decreases the longer the manipulated numbers become and becomes negligible
-for numbers with thousand digits: the overhead from parsing fraction format is
-little compared to other expensive aspects of the expandable shuffling of
-tokens.
+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 (v1.2: this info may be obsolete).
+
+% but this gain decreases the longer the manipulated
+% numbers become and becomes negligible for numbers with thousand digits: the
+% overhead from parsing fraction format is little compared to other expensive
+% aspects of the expandable shuffling of tokens
+
\subsection{\csbh{xintboolexpr},
\csbh{xinttheboolexpr}}\label{xintboolexpr}\label{xinttheboolexpr}
@@ -11239,10 +11515,6 @@ An optional parameter within brackets is allowed: the final float will have
that many digits of precision. This is provided to get rid of non-relevant
last digits.
-Currently, the factorial function hasn't yet a float version; so inside
-|\xintthefloatexpr . . . \relax|, |n!| will be computed exactly. Perhaps this
-will be improved in a future release.
-
\xintDigits:= 9;
Note that |1.000000001| and |(1+1e-9)| will not be equivalent for
@@ -11414,7 +11686,7 @@ 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*}
-\oodef\f {\xintexpr 1.23^10\relax }\meaning\f
+\fdef\f {\xintexpr 1.23^10\relax }\meaning\f
\end{everbatim*}
\begin{framed}
@@ -11443,11 +11715,6 @@ his/her expansion control.
possibility.
\end{framed}
-% \begin{framed}
-% This implementation and user interface are still to be considered
-% \emph{experimental}.
-% \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.
@@ -11748,8 +12015,8 @@ needed.%
\begin{everbatim*}
\def\coeff #1{\xintiiMON{#1}/#1.5} % (-1)^n/(n+1/2)
-\oodef\w {\xintSeries {0}{50}{\coeff}} % we want to re-use it
-\oodef\z {\xintJrr {\w}[0]} % the [0] for a microsecond gain.
+\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 \]
@@ -11773,7 +12040,7 @@ A more efficient way to code |\coeff| is illustrated next.
\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.
-\oodef\w {\xintSeries {0}{50}{\coeff}}
+\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
@@ -11882,7 +12149,7 @@ expressions built with such; they must obey the \TeX{} bound. The initial term
\def\ratio #1{2/#1[0]}% 2/n, to compute exp(2)
\cnta 0 % previously declared count
\begin{quote}
-\loop \oodef\z {\xintRationalSeries {0}{\cnta}{1}{\ratio }}%
+\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
@@ -11895,7 +12162,7 @@ expressions built with such; they must obey the \TeX{} bound. The initial term
\cnta 0 % previously declared count
\begin{quote}
\loop
-\oodef\z {\xintRationalSeries {0}{\cnta}{1}{\ratio }}%
+\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
@@ -11942,12 +12209,12 @@ Here is a slightly more complicated evaluation:
\begin{everbatim*}
\cnta 1
\begin{multicols}{2}
-\loop \oodef\z {\xintRationalSeries
+\loop \fdef\z {\xintRationalSeries
{\cnta}
{2*\cnta-1}
{\xintiPow {\the\cnta}{\cnta}/\xintFac{\cnta}}
{\ratioexp{\the\cnta}}}%
-\oodef\w {\xintRationalSeries {0}{2*\cnta-1}{1}{\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!} =
@@ -12012,19 +12279,19 @@ next section.
These completely exact operations rapidly create numbers with many digits. Let
us print in full the raw fractions created by the operation illustrated above:
-\oodef\z{\xintRationalSeriesX {0}{9}{\firstterm}
+\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm}
{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1[-1]}}}
|E(L(1[-1]))=|\dtt{\printnumber{\z}} (length of numerator:
\xintLen {\xintNumerator \z})
-\oodef\z{\xintRationalSeriesX {0}{9}{\firstterm}
+\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm}
{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{12[-2]}}}
|E(L(12[-2]))=|\dtt{\printnumber{\z}} (length of numerator:
\xintLen {\xintNumerator \z})
-\oodef\z{\xintRationalSeriesX {0}{9}{\firstterm}
+\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm}
{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{123[-3]}}}
|E(L(123[-3]))=|\dtt{\printnumber{\z}} (length of numerator:
@@ -12036,21 +12303,21 @@ 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:
-\oodef\z{\xintRationalSeriesX {0}{9}{\firstterm}
+\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm}
{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/7}}}
|E(L(1/7))=|\dtt{\printnumber{\z}} (length of numerator:
\xintLen {\xintNumerator \z}; length of denominator:
\xintLen {\xintDenominator \z})
-\oodef\z{\xintRationalSeriesX {0}{9}{\firstterm}
+\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm}
{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/71}}}
|E(L(1/71))=|\dtt{\printnumber{\z}} (length of numerator:
\xintLen {\xintNumerator \z}; length of denominator:
\xintLen {\xintDenominator \z})
-\oodef\z{\xintRationalSeriesX {0}{9}{\firstterm}
+\fdef\z{\xintRationalSeriesX {0}{9}{\firstterm}
{\ratioexp}{\xintPowerSeries{1}{10}{\coefflog}{1/712}}}
|E(L(1/712))=|\dtt{\printnumber{\z}} (length of numerator:
@@ -12245,7 +12512,7 @@ $\xintFxPtPowerSeries {0}{\cnta}{\coeffexp}{\f}{20}$\\
%
\leftedline{|\xintFxPtPowerSeries {0}{19}{\coeffexp}{\f}{25}=|
\dtt{\xintFxPtPowerSeries {0}{19}{\coeffexp}{\f}{25}}}
-\oodef\z{\xintIrr {\xintPowerSeries {0}{19}{\coeffexp}{\f}}}
+\fdef\z{\xintIrr {\xintPowerSeries {0}{19}{\coeffexp}{\f}}}
%
\texttt{\hyphenchar\font45 }%
@@ -12593,7 +12860,7 @@ You want more digits and have some time? compile this copy of the
{\xintMul {4/239}{\xintFxPtPowerSeries {0}{#2}{\coeffarctg}{\xb}{#3}}}%
}}%
\pdfresettimer
-\oodef\Z {\Machin {1000}}
+\fdef\Z {\Machin {1000}}
\odef\W {\the\pdfelapsedtime}
\message{\Z}
\message{computed in \xintRound {2}{\W/65536} seconds.}
@@ -12601,12 +12868,13 @@ You want more digits and have some time? compile this copy of the
|
This will log the first 1000 digits of $\pi$ after the decimal point. On my
-laptop (a 2012 model) this took about $16$ seconds last time I tried.%
+laptop (a 2012 model) this took about $5.6$ seconds last time I tried.%
%
-\footnote{With \texttt{1.09i} and earlier \xintname releases, this used
- to be \dtt{42} seconds; the \texttt{1.09j} division is much faster
- with small denominators as occurs here with \dtt{\char92xa=1/25}, and
- I believe this to be the main explanation for the speed gain.}
+\footnote{With \texttt{v1.09i} and earlier \xintname, this used to be \dtt{42}
+ seconds; starting with \texttt{v1.09j}, and prior to \texttt{v1.2}, it was
+ \dtt{16} seconds (this was probably due to a more efficient division with
+ denominators at most $9999$). The |v1.2| \xintcorename achieves a further
+ gain.}
%
As mentioned in the
introduction, the file \href{http://www.ctan.org/pkg/pi}{pi.tex} by \textsc{D.
@@ -12951,7 +13219,7 @@ $+$ or $-$.
\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|.\NewWith {1.09m}
+|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
@@ -12986,10 +13254,10 @@ $$\xintGCtoGCx {+\cfrac\xintFwOver}{\\\xintFwOver}{a+b/...}\endcfrac$$
\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.\NewWith {1.09m}
+(sequence) of braced items.
\begin{everbatim*}
-\oodef\test{\xintFtoC{-5262046/89233}}\texttt{\meaning\test}
+\fdef\test{\xintFtoC{-5262046/89233}}\texttt{\meaning\test}
\end{everbatim*}
\subsection{\csbh{xintFtoCs}}\label{xintFtoCs}
@@ -13049,20 +13317,20 @@ format'.
\csa{xintFGtoC}|{f}{g}|\etype{\Ff\Ff} computes the common initial coefficients
to
-two given fractions |f| and |g|. Notice\NewWith {1.09m} that any real number |f<x<g| or |f>x>g|
+two given fractions |f| and |g|. Notice that any real number |f<x<g| or |f>x>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*}
-\oodef\test{\xintFGtoC{-5262046/89233}{-5314647/90125}}\texttt{\meaning\test}
+\fdef\test{\xintFGtoC{-5262046/89233}{-5314647/90125}}\texttt{\meaning\test}
\end{everbatim*}
\begin{everbatim*}
-\oodef\test{\xintFGtoC{3.141592653}{3.141592654}}\texttt{\meaning\test}
+\fdef\test{\xintFGtoC{3.141592653}{3.141592654}}\texttt{\meaning\test}
\end{everbatim*}
\begin{everbatim*}
-\oodef\test{\xintFGtoC{3.1415926535897932384}{3.1415926535897932385}}\meaning\test
+\fdef\test{\xintFGtoC{3.1415926535897932384}{3.1415926535897932385}}\meaning\test
\end{everbatim*}
\begin{everbatim*}
\xintRound {30}{\xintCstoF{\xintListWithSep{,}{\test}}}
@@ -13071,7 +13339,7 @@ braced numbers. This list can then be manipulated via macros from
\xintRound {30}{\xintCtoF{\test}}
\end{everbatim*}
\begin{everbatim*}
-\oodef\test{\xintFGtoC{1.41421356237309}{1.4142135623731}}\meaning\test
+\fdef\test{\xintFGtoC{1.41421356237309}{1.4142135623731}}\meaning\test
\end{everbatim*}
\subsection{\csbh{xintFtoCC}}\label{xintFtoCC}
@@ -13109,7 +13377,7 @@ simplification by 3 in the result above).
\subsection{\csbh{xintCtoF}}\label{xintCtoF}
\csa{xintCtoF}|{{a}{b}{c}...{z}}|\etype{f} computes the fraction corresponding
-to the coefficients, which may be fractions or even macros.\NewWith {1.09m}
+to the coefficients, which may be fractions or even macros.
\begin{everbatim*}
\xintCtoF {\xintApply {\xintiiPow 3}{\xintSeq {1}{5}}}
\end{everbatim*}
@@ -13166,9 +13434,9 @@ fractions, but otherwise it is not necessarily the case.
\subsection{\csbh{xintCtoCv}}\label{xintCtoCv}
\csa{xintCtoCv}|{{a}{b}{c}...{z}}|\etype{f} returns the sequence of the
-corresponding convergents, each one within braces.\NewWith {1.09m}
+corresponding convergents, each one within braces.
\begin{everbatim*}
-\oodef\test{\xintCtoCv {11111111111}}\texttt{\meaning\test}
+\fdef\test{\xintCtoCv {11111111111}}\texttt{\meaning\test}
\end{everbatim*}
\subsection{\csbh{xintGCtoCv}}\label{xintGCtoCv}
@@ -13263,7 +13531,7 @@ 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}
-\oodef\x{\xintCntoGC {5}{\macro}}\meaning\x
+\fdef\x{\xintCntoGC {5}{\macro}}\meaning\x
\[\xintGCFrac{\xintCntoGC {5}{\macro}}\]
\end{everbatim*}
@@ -13309,7 +13577,7 @@ fraction of the same type, each expanded coefficient being enclosed within
braces.
%
\begin{everbatim*}
-\oodef\x {\xintGCtoGC {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/%
+\fdef\x {\xintGCtoGC {1+\xintPow{1.5}{3}/{1/7}+{-3/5}/%
\xintFac {6}+\xintCstoF {2,-7,-5}/16}} \meaning\x
\end{everbatim*}
@@ -13374,7 +13642,7 @@ 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*}
-\oodef\z {\xintCntoF {199}{\cn}}%
+\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
@@ -13463,15 +13731,29 @@ $1$ or $-1$.
% \bigskip
% This is \expandafter|\xintbndlversion| of \expandafter|\xintbndldate|.
%
-% Extensive changes in release |1.1| of |2014/10/28| were located in
-% \xintexprnameimp. Also with that release,
-% packages \xintkernelnameimp and \xintcorenameimp were extracted from
-% \xinttoolsnameimp and \xintnameimp, and |\xintAdd| was modified to not
-% multiply denominators blindly.
-%
-% \smallskip
-% \noindent\fbox{\xinttoolsnameimp is not loaded anymore by
-% \xintnameimp, nor by \xintfracnameimp. It is loaded by \xintexprnameimp.}
+% \begin{itemize}
+% \item Release |1.2| of |2015/10/10| has entirely rewritten the core
+% arithmetic routines in \xintcorenameimp. Many macros benefit indirectly
+% from the faster core routines. The new model is yet to be extended to
+% other portions of the code: for example the routines of \xintbinhexnameimp
+% could be made faster for very big inputs if they adopted some of the style
+% used now for the basic arithmetic routines.
+%
+% The parser of \xintexprnameimp is also faster at gathering digits and does
+% not have a limit at |5000| digits per number anymore.
+%
+% \item Extensive changes in release |1.1| of |2014/10/28| were located in
+% \xintexprnameimp. Also with that release, packages \xintkernelnameimp and
+% \xintcorenameimp were extracted from \xinttoolsnameimp and \xintnameimp,
+% and |\xintAdd| was modified to not multiply denominators blindly.
+%
+% \xinttoolsnameimp is not loaded anymore by \xintnameimp, nor by
+% \xintfracnameimp. It is loaded by \xintexprnameimp.
+% \end{itemize}
+%
+% Large portions of the code date back to the initial release, and at that
+% time I was learning my trade in expandable TeX macro programming. At some
+% point in the future, I will have to re-examine the older parts of the code.
%
% \section {Package \xintkernelnameimp implementation}
% \label{sec:kernelimp}
@@ -13479,8 +13761,10 @@ $1$ or $-1$.
% \localtableofcontents
%
% This package provides the common minimal code base for loading management
-% and catcode control and also a few programming utilities. It is loaded by both
-% |xintcore.sty| and |xinttools.sty| hence by all other packages.
+% and catcode control and also a few programming utilities. With |1.2| a few
+% more helper macros and all |\chardef|'s have been moved here. The package is
+% loaded by both |xintcore.sty| and |xinttools.sty| hence by all other
+% packages.
%
% First appeared as a separate package with release |1.1|.
%
@@ -13524,19 +13808,36 @@ $1$ or $-1$.
\else
\def\y#1#2{\PackageInfo{#1}{#2}}%
\fi
+ \let\z\relax
\expandafter
\ifx\csname numexpr\endcsname\relax
\y{xintkernel}{\numexpr not available, aborting input}%
- \aftergroup\endinput
+ \def\z{\endgroup\endinput}%
\else
\expandafter
\ifx\csname XINTsetupcatcodes\endcsname\relax
\else
\y{xintkernel}{I was already loaded, aborting input}%
- \aftergroup\endinput
+ \def\z{\endgroup\endinput}%
\fi
\fi
- \def\SetCatcodesIfInputNotAborted
+ \ifx\z\relax\else\expandafter\z\fi%
+% \end{macrocode}
+% |1.2| corrects a long-standing somewhat subtle bug, of which the author
+% became aware only on |15/09/13|: earlier releases had |\aftergroup\endinput|
+% above, rather than |\def\z{\endgroup\endinput}| and the |\ifx| test. The
+% |\endinput| token was indeed inserted after the |\endgroup| from
+% |\PrepareCatcodes|, but all material and in particular |\XINT_setupcatcodes|
+% from the macro now called |\PrepareCatcodes| was expanded before the
+% |\endinput| had come into effect ! as a result the catcodes would be
+% modified in unwanted ways, in Plain \TeX, if the source had for example
+% |\input xint.sty| followed by |\input xintkernel.sty|: the catcode changes
+% would be done before the second input of |xintkernel.sty| had been aborted.
+% One didn't see the situation under \LaTeX{} (in normal circumstances),
+% because a second |\usepackage{xintkernel}| would not do any input of
+% |xintkernel.sty| to start with.
+% \begin{macrocode}
+ \def\PrepareCatcodes
{%
\endgroup
\def\XINT_restorecatcodes
@@ -13605,19 +13906,19 @@ $1$ or $-1$.
\catcode36=3 % $
\catcode91=12 % [
\catcode93=12 % ]
- \catcode33=11 % ! LETTER
+ \catcode33=12 % !
\catcode64=11 % @ LETTER
\catcode38=12 % &
\catcode124=12 % |
\catcode63=11 % ? LETTER
\catcode34=12 % "
\catcode39=12 % '
- \catcode126=3 % ~
+ \catcode126=3 % ~ MATH
\catcode59=12 % ;
}%
\XINT_setcatcodes
}%
-\SetCatcodesIfInputNotAborted
+\PrepareCatcodes
% \end{macrocode}
% Other modules could possibly be loaded under a different catcode regime.
% \begin{macrocode}
@@ -13648,10 +13949,55 @@ $1$ or $-1$.
\fi
\XINT_providespackage
\ProvidesPackage {xintkernel}%
- [2015/09/12 v1.1c Paraphernalia for the xint packages (jfB)]%
+ [2015/10/10 v1.2 Paraphernalia for the xint packages (jfB)]%
+% \end{macrocode}
+% \subsection{Constants}
+% |v1.2| decides to move them to \xintkernelnameimp from \xintcorenameimp and
+% \xintnameimp. The |\count|'s are left in their respective packages.
+% \begin{macrocode}
+\chardef\xint_c_ 0
+\chardef\xint_c_i 1
+\chardef\xint_c_ii 2
+\chardef\xint_c_iii 3
+\chardef\xint_c_iv 4
+\chardef\xint_c_v 5
+\chardef\xint_c_vi 6
+\chardef\xint_c_vii 7
+\chardef\xint_c_viii 8
+\chardef\xint_c_ix 9
+\chardef\xint_c_x 10
+\chardef\xint_c_xiv 14
+\chardef\xint_c_xvi 16
+\chardef\xint_c_xviii 18
+\chardef\xint_c_xxii 22
+\chardef\xint_c_ii^v 32
+\chardef\xint_c_ii^vi 64
+\chardef\xint_c_ii^vii 128
+\mathchardef\xint_c_ii^viii 256
+\mathchardef\xint_c_ii^xii 4096
+\mathchardef\xint_c_x^iv 10000
% \end{macrocode}
% \subsection{Token management utilities}
% \begin{macrocode}
+\def\XINT_tmpa { }%
+\ifx\XINT_tmpa\space\else
+ \immediate\write-1{Package xintkernel Warning: ATTENTION!}%
+ \immediate\write-1{\string\space\XINT_tmpa macro does not have its normal
+ meaning.}%
+ \immediate\write-1{\XINT_tmpa\XINT_tmpa\XINT_tmpa\XINT_tmpa
+ All kinds of catastrophes will ensue!!!!}%
+\fi
+\def\XINT_tmpb {}%
+\ifx\XINT_tmpb\empty\else
+ \immediate\write-1{Package xintkernel Warning: ATTENTION!}%
+ \immediate\write-1{\string\empty\XINT_tmpa macro does not have its normal
+ meaning.}%
+ \immediate\write-1{\XINT_tmpa\XINT_tmpa\XINT_tmpa\XINT_tmpa
+ All kinds of catastrophes will ensue!!!!}%
+\fi
+\let\XINT_tmpa\relax \let\XINT_tmpb\relax
+\ifdefined\space\else\def\space { }\fi
+\ifdefined\empty\else\def\empty {}\fi
\long\def\xint_gobble_ {}%
\long\def\xint_gobble_i #1{}%
\long\def\xint_gobble_ii #1#2{}%
@@ -13667,14 +14013,33 @@ $1$ or $-1$.
\long\def\xint_firstofone_thenstop #1{ #1}%
\long\def\xint_firstoftwo_thenstop #1#2{ #1}%
\long\def\xint_secondoftwo_thenstop #1#2{ #2}%
+\def\xint_minus_thenstop { -}%
+\def\xint_exchangetwo_keepbraces #1#2{{#2}{#1}}%
% \end{macrocode}
-% \subsection{gob til macros and UD style fork}
+% \subsection{``gob til'' macros and UD style fork}
+% Some moved here from \xintcorenameimp by release |1.2|.
% \begin{macrocode}
-\def\xint_gob_til_zero #10{}%
-\def\xint_UDzerominusfork #10-#2#3\krof {#2}%
\long\def\xint_gob_til_R #1\R {}%
\long\def\xint_gob_til_W #1\W {}%
\long\def\xint_gob_til_Z #1\Z {}%
+\def\xint_gob_til_zero #10{}%
+\def\xint_gob_til_one #11{}%
+\def\xint_gob_til_zeros_iii #1000{}%
+\def\xint_gob_til_zeros_iv #10000{}%
+\def\xint_gob_til_eightzeroes #100000000{}%
+\def\xint_gob_til_exclam #1!{}% catcode 12 exclam
+\def\xint_gob_til_dot #1.{}%
+\def\xint_gob_til_G #1G{}%
+\def\xint_gob_til_minus #1-{}%
+\def\xint_gob_til_relax #1\relax {}%
+\def\xint_UDzerominusfork #10-#2#3\krof {#2}%
+\def\xint_UDzerofork #10#2#3\krof {#2}%
+\def\xint_UDsignfork #1-#2#3\krof {#2}%
+\def\xint_UDwfork #1\W#2#3\krof {#2}%
+\def\xint_UDXINTWfork #1\XINT_W#2#3\krof {#2}%
+\def\xint_UDzerosfork #100#2#3\krof {#2}%
+\def\xint_UDonezerofork #110#2#3\krof {#2}%
+\def\xint_UDsignsfork #1--#2#3\krof {#2}%
\let\xint_relax\relax
\def\xint_brelax {\xint_relax }%
\long\def\xint_gob_til_xint_relax #1\xint_relax {}%
@@ -13687,19 +14052,20 @@ $1$ or $-1$.
% \begin{macrocode}
\long\def\xint_bye #1\xint_bye {}%
% \end{macrocode}
-% \subsection{\csh{xint_dothis}, \csh{xint_orthat}}
-% \lverb|New with 1.1. Used as \if..\xint_dothis{..}\fi <multiple times>
-% followed by \xint_orthat{...}. To be used with less probable things first.|
+% \subsection{\csh{xintdothis}, \csh{xintorthat}}
+% \lverb|New with 1.1. Public names without underscores with 1.2. Used as
+% \if..\xint_dothis{..}\fi <multiple times> followed by \xint_orthat{...}. To
+% be used with less probable things first.|
% \begin{macrocode}
\long\def\xint_dothis #1#2\xint_orthat #3{\fi #1}% v1.1
\let\xint_orthat \xint_firstofone
+\long\def\xintdothis #1#2\xintorthat #3{\fi #1}%
+\let\xintorthat \xint_firstofone
% \end{macrocode}
% \subsection{\csh{xint_zapspaces}}
-% \lverb|&
-% 1.1. Zaps leading, intermediate, trailing, spaces in completely
-% expanding context
-% (\edef, \csname . . . \endcsname). To be used as:$\
-% $null$ $ $ $ \xint_zapspaces foo \xint_gobble_i $% notice the mandatory space after foo
+% \lverb|1.1. This little utility zaps leading, intermediate, trailing,
+% spaces in completely expanding context (\edef, \csname . . . \endcsname).
+% $centeredline$bgroup\xint_zapspaces foo<space>\xint_gobble_i$egroup
%
% Will remove some brace pairs (but not spaces inside them). By the way the
% \zap@spaces of LaTeX2e handles unexpectedly things such as \zap@spaces 1
@@ -13712,28 +14078,25 @@ $1$ or $-1$.
% brace-stripping may occur. And this iterates: each time a #2 is removed,
% either we then have spaces and next #1 will be empty, or we have no spaces
% and #1 will end at the first space. Ultimately #2 will be \xint_gobble_i.
-%
-% Code comment from 1.1 release said to do:
%
-% \xint_zapspaces foo \xint_bye\xint_bye
-%
-% perhaps because it was pretty. It works also, but \xint_gobble_i is one
-% token less. Compatible with an empty foo.|
+% This is not really robust as it may switch the expansion order of macros,
+% and the \xint_zapspaces token might end up being fetched up by a macro. But
+% it is enough for our purposes, for example:
+% $centeredline
+% $bgroup\the\numexpr \xint_zapspaces 1 2 \xint_gobble_i\relax$egroup
+% expands to 12, and not 12\relax. Imagine also:
+% $centeredline
+% $bgroup\the\numexpr 1 2\expandafter.\the\numexpr ...$egroup
+%
+% The space will delay the \expandafter. Thus we have to get rid of spaces in
+% contexts where arguments are fetched by delimited macros and fed to
+% \numexpr (or for any reason can contain spaces). I apply this corrective
+% treatment so far only in $xintexprnameimp but perhaps I should in
+% $xintfracnameimp too. As said above, perhaps the zapspaces should force
+% expansion too, but I leave it standing.|
% \begin{macrocode}
\def\xint_zapspaces #1 #2{#1#2\xint_zapspaces }% v1.1
% \end{macrocode}
-% \subsection{Constants}
-% \begin{macrocode}
-\chardef\xint_c_ 0
-\chardef\xint_c_i 1
-\chardef\xint_c_ii 2
-\chardef\xint_c_iii 3
-\chardef\xint_c_iv 4
-\chardef\xint_c_v 5
-\chardef\xint_c_vi 6
-\chardef\xint_c_vii 7
-\chardef\xint_c_viii 8
-% \end{macrocode}
% \subsection{\csh{odef}, \csh{oodef}, \csh{fdef}}
% \lverb|May be prefixed with \global. No parameter text.|
% \begin{macrocode}
@@ -13748,7 +14111,10 @@ $1$ or $-1$.
\ifdefined\fdef\else\let\fdef\xintfdef\fi
% \end{macrocode}
% \subsection{\csh{xintReverseOrder}}
-% \lverb|\xintReverseOrder: does NOT expand its argument.|
+% \lverb|\xintReverseOrder: does NOT expand its argument. Thus one must use
+% some \expandafter if argument is a macro. A faster reverse, but only
+% applicable to (many) digit tokens has been provided with
+% \csh{xintReverseDigits} from 1.2 xintcore.|
% \begin{macrocode}
\def\xintReverseOrder {\romannumeral0\xintreverseorder }%
\long\def\xintreverseorder #1%
@@ -13879,7 +14245,7 @@ $1$ or $-1$.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xinttools}%
- [2015/09/12 v1.1c Expandable and non-expandable utilities (jfB)]%
+ [2015/10/10 v1.2 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.|
@@ -15160,17 +15526,24 @@ $1$ or $-1$.
%
% \localtableofcontents
%
-% Got split off from \xintnameimp with release |1.1| (macros |\XINT_SQ|,
-% |\xintLDg|, |\xintHalf| which are dependencies of |\XINT_div_prepare| were
-% forgotten and they were added to the package only later with |1.1b|).
-% Release |1.1| also added the new macro |\xintiiDivRound|. The package does
-% not load \xinttoolsnameimp.
+% Got split off from \xintnameimp with release |1.1|. Release |1.1| also added
+% the new macro |\xintiiDivRound|. The package does not load
+% \xinttoolsnameimp.
+%
+% \begin{framed}
+% The core arithmetic routines have been entirely rewritten for release
+% |1.2|.
+%
+% The commenting continues (\xintdocdate) to be very sparse: actually it got
+% worse than ever with release |1.2|. I will possibly add comments at a
+% later date, but for the time being the new routines are not commented at
+% all.
+% \end{framed}
%
-% Since release |xint 1.09a| the macros doing arithmetic operations
-% apply systematically |\xintnum| to their arguments; this adds a little
-% overhead but this is more convenient for using count registers even
-% with infix notation; also this is what |xintfrac.sty| did all along.
-% It simplifies the discussion in the documentation too.
+% Also, with |1.2|, |\xintAdd| etc... have been left undefined control
+% sequences: only |\xintiAdd| and |\xintiiAdd| (etc...) are provided via
+% \xintcorenameimp. It was announced a long time ago that |\xintAdd| etc...
+% were to be removed from \xintnameimp and only defined by \xintfracnameimp.
%
% \subsection{Catcodes, \protect\eTeX{} and reload detection}
%
@@ -15229,246 +15602,278 @@ $1$ or $-1$.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintcore}%
- [2015/09/12 v1.1c Expandable arithmetic on big integers (jfB)]%
+ [2015/10/10 v1.2 Expandable arithmetic on big integers (jfB)]%
% \end{macrocode}
-% \subsection{More token management, constants}
+% \subsection{Counts for holding needed constants}
% \begin{macrocode}
-\def\xint_minus_thenstop { -}%
-\def\xint_gob_til_zeros_iii #1000{}%
-\def\xint_gob_til_zeros_iv #10000{}%
-\def\xint_gob_til_one #11{}%
-\def\xint_gob_til_G #1G{}%
-\def\xint_gob_til_minus #1-{}%
-\def\xint_gob_til_relax #1\relax {}%
-\def\xint_exchangetwo_keepbraces #1#2{{#2}{#1}}%
-\def\xint_exchangetwo_keepbraces_thenstop #1#2{ {#2}{#1}}%
-\def\xint_UDzerofork #10#2#3\krof {#2}%
-\def\xint_UDsignfork #1-#2#3\krof {#2}%
-\def\xint_UDwfork #1\W#2#3\krof {#2}%
-\def\xint_UDzerosfork #100#2#3\krof {#2}%
-\def\xint_UDonezerofork #110#2#3\krof {#2}%
-\def\xint_UDsignsfork #1--#2#3\krof {#2}%
-\chardef\xint_c_ix 9
-\chardef\xint_c_x 10
-\chardef\xint_c_ii^v 32 % not used in xint, common to xintfrac and xintbinhex
-\chardef\xint_c_ii^vi 64
-\mathchardef\xint_c_ixixixix 9999
-\mathchardef\xint_c_x^iv 10000
-\newcount\xint_c_x^viii \xint_c_x^viii 100000000
+\ifdefined\m@ne\let\xint_c_mone\m@ne
+ \else\csname newcount\endcsname\xint_c_mone \xint_c_mone -1 \fi
+\newcount\xint_c_x^viii \xint_c_x^viii 100000000
+\newcount\xint_c_x^ix \xint_c_x^ix 1000000000
+\newcount\xint_c_x^viii_mone \xint_c_x^viii_mone 99999999
+\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
+\newcount\xint_c_xii_e_viii_mone\xint_c_xii_e_viii_mone 1199999999
% \end{macrocode}
-% \subsection{\csh{XINT_RQ}}
-% \lverb|Cette macro renverse et ajoute le nombre minimal de zéros à
-% la fin pour que la longueur soit alors multiple de 4$\
-% \romannumeral0\XINT_RQ {}<le truc à renverser>\R\R\R\R\R\R\R\R\Z$\
-% Attention, ceci n'est utilisé que pour des chaînes de chiffres, et donc le
-% comportement avec des {..} ou autres espaces n'a fait l'objet d'aucune
-% attention.|
+% \subsection{\csh{xintNum}}
+% \lverb|&
+% For example \xintNum {----+-+++---+----000000000000003}$\
+% 1.05 defines \xintiNum, which allows redefinition of \xintNum by xintfrac.sty
+% Slightly modified in 1.06b (\R->\xint_relax) to avoid initial re-scan of
+% input stack (while still allowing empty #1). In versions earlier than 1.09a
+% it was entirely up to the user to apply \xintnum; starting with 1.09a
+% arithmetic
+% macros of xint.sty (like earlier already xintfrac.sty with its own \xintnum)
+% make use of \xintnum. This allows arguments to
+% be count registers, or even \numexpr arbitrary long expressions (with the
+% trick of braces, see the user documentation).
+%
+% Note (10/2015): I should take time to revisit this.|
% \begin{macrocode}
-\def\XINT_RQ #1#2#3#4#5#6#7#8#9%
+\def\xintiNum {\romannumeral0\xintinum }%
+\def\xintinum #1%
+{%
+ \expandafter\XINT_num_loop
+ \romannumeral-`0#1\xint_relax\xint_relax\xint_relax\xint_relax
+ \xint_relax\xint_relax\xint_relax\xint_relax\Z
+}%
+\let\xintNum\xintiNum \let\xintnum\xintinum
+\def\XINT_num #1%
{%
- \xint_gob_til_R #9\XINT_RQ_end_a\R\XINT_RQ {#9#8#7#6#5#4#3#2#1}%
+ \XINT_num_loop #1\xint_relax\xint_relax\xint_relax\xint_relax
+ \xint_relax\xint_relax\xint_relax\xint_relax\Z
}%
-\def\XINT_RQ_end_a\R\XINT_RQ #1#2\Z
+\def\XINT_num_loop #1#2#3#4#5#6#7#8%
{%
- \XINT_RQ_end_b #1\Z
+ \xint_gob_til_xint_relax #8\XINT_num_end\xint_relax
+ \XINT_num_NumEight #1#2#3#4#5#6#7#8%
}%
-\def\XINT_RQ_end_b #1#2#3#4#5#6#7#8%
+\edef\XINT_num_end\xint_relax\XINT_num_NumEight #1\xint_relax #2\Z
{%
- \xint_gob_til_R
- #8\XINT_RQ_end_viii
- #7\XINT_RQ_end_vii
- #6\XINT_RQ_end_vi
- #5\XINT_RQ_end_v
- #4\XINT_RQ_end_iv
- #3\XINT_RQ_end_iii
- #2\XINT_RQ_end_ii
- \R\XINT_RQ_end_i
- \Z #2#3#4#5#6#7#8%
+ \noexpand\expandafter\space\noexpand\the\numexpr #1+\xint_c_\relax
}%
-\def\XINT_RQ_end_viii #1\Z #2#3#4#5#6#7#8#9\Z { #9}%
-\def\XINT_RQ_end_vii #1\Z #2#3#4#5#6#7#8#9\Z { #8#9000}%
-\def\XINT_RQ_end_vi #1\Z #2#3#4#5#6#7#8#9\Z { #7#8#900}%
-\def\XINT_RQ_end_v #1\Z #2#3#4#5#6#7#8#9\Z { #6#7#8#90}%
-\def\XINT_RQ_end_iv #1\Z #2#3#4#5#6#7#8#9\Z { #5#6#7#8#9}%
-\def\XINT_RQ_end_iii #1\Z #2#3#4#5#6#7#8#9\Z { #4#5#6#7#8#9000}%
-\def\XINT_RQ_end_ii #1\Z #2#3#4#5#6#7#8#9\Z { #3#4#5#6#7#8#900}%
-\def\XINT_RQ_end_i \Z #1#2#3#4#5#6#7#8\Z { #1#2#3#4#5#6#7#80}%
+\def\XINT_num_NumEight #1#2#3#4#5#6#7#8%
+{%
+ \ifnum \numexpr #1#2#3#4#5#6#7#8+\xint_c_= \xint_c_
+ \xint_afterfi {\expandafter\XINT_num_keepsign_a
+ \the\numexpr #1#2#3#4#5#6#7#81\relax}%
+ \else
+ \xint_afterfi {\expandafter\XINT_num_finish
+ \the\numexpr #1#2#3#4#5#6#7#8\relax}%
+ \fi
+}%
+\def\XINT_num_keepsign_a #1%
+{%
+ \xint_gob_til_one#1\XINT_num_gobacktoloop 1\XINT_num_keepsign_b
+}%
+\def\XINT_num_gobacktoloop 1\XINT_num_keepsign_b {\XINT_num_loop }%
+\def\XINT_num_keepsign_b #1{\XINT_num_loop -}%
+\def\XINT_num_finish #1\xint_relax #2\Z { #1}%
% \end{macrocode}
-% \subsection{\csh{XINT_OQ}}
+% \subsection{Zeroes}
+% \lverb|Changed for 1.2 which has a base model of eight digits rather than
+% four for the basic operations.|
% \begin{macrocode}
-\def\XINT_OQ #1#2#3#4#5#6#7#8#9%
+\edef\XINT_cuz_small #1#2#3#4#5#6#7#8%
{%
- \xint_gob_til_R #9\XINT_OQ_end_a\R\XINT_OQ {#9#8#7#6#5#4#3#2#1}%
+ \noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4#5#6#7#8\relax
}%
-\def\XINT_OQ_end_a\R\XINT_OQ #1#2\Z
+%%%%%%%%%%%%
+\def\XINT_cuz #1#2#3#4#5#6#7#8#9%
{%
- \XINT_OQ_end_b #1\Z
+ \xint_gob_til_R #9\XINT_cuz_e \R
+ \xint_gob_til_eightzeroes #1#2#3#4#5#6#7#8\XINT_cuz_z 00000000%
+ \XINT_cuz_clean #1#2#3#4#5#6#7#8#9%
}%
-\def\XINT_OQ_end_b #1#2#3#4#5#6#7#8%
+\edef\XINT_cuz_clean #1#2#3#4#5#6#7#8#9\R
+ {\noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4#5#6#7#8\relax #9}%
+\edef\XINT_cuz_e\R #1\XINT_cuz_clean #2\R
+ {\noexpand\expandafter\space\noexpand\the\numexpr #2\relax }%
+\def\XINT_cuz_z 00000000\XINT_cuz_clean 00000000{\XINT_cuz }%
+%%%%%%%%%%%%
+\def\XINT_cuz_byviii #1#2#3#4#5#6#7#8#9%
{%
- \xint_gob_til_R
- #8\XINT_OQ_end_viii
- #7\XINT_OQ_end_vii
- #6\XINT_OQ_end_vi
- #5\XINT_OQ_end_v
- #4\XINT_OQ_end_iv
- #3\XINT_OQ_end_iii
- #2\XINT_OQ_end_ii
- \R\XINT_OQ_end_i
- \Z #2#3#4#5#6#7#8%
+ \xint_gob_til_R #9\XINT_cuz_byviii_e \R
+ \xint_gob_til_eightzeroes #1#2#3#4#5#6#7#8\XINT_cuz_byviii_z 00000000%
+ \XINT_cuz_byviii_clean #1#2#3#4#5#6#7#8#9%
}%
-\def\XINT_OQ_end_viii #1\Z #2#3#4#5#6#7#8#9\Z { #9}%
-\def\XINT_OQ_end_vii #1\Z #2#3#4#5#6#7#8#9\Z { #8#90000000}%
-\def\XINT_OQ_end_vi #1\Z #2#3#4#5#6#7#8#9\Z { #7#8#9000000}%
-\def\XINT_OQ_end_v #1\Z #2#3#4#5#6#7#8#9\Z { #6#7#8#900000}%
-\def\XINT_OQ_end_iv #1\Z #2#3#4#5#6#7#8#9\Z { #5#6#7#8#90000}%
-\def\XINT_OQ_end_iii #1\Z #2#3#4#5#6#7#8#9\Z { #4#5#6#7#8#9000}%
-\def\XINT_OQ_end_ii #1\Z #2#3#4#5#6#7#8#9\Z { #3#4#5#6#7#8#900}%
-\def\XINT_OQ_end_i \Z #1#2#3#4#5#6#7#8\Z { #1#2#3#4#5#6#7#80}%
+\def\XINT_cuz_byviii_clean #1\R { #1}%
+\def\XINT_cuz_byviii_e\R #1\XINT_cuz_byviii_clean #2\R{ #2}%
+\def\XINT_cuz_byviii_z 00000000\XINT_cuz_byviii_clean 00000000{\XINT_cuz_byviii}%
% \end{macrocode}
-% \subsection{\csh{XINT_SQ}}
+% \subsection{Blocks of eight digits}
+% \lverb|Lingua of release 1.2.|
% \begin{macrocode}
-\def\XINT_SQ #1#2#3#4#5#6#7#8%
+\def\XINT_zeroes_forviii #1#2#3#4#5#6#7#8%
{%
- \xint_gob_til_R #8\XINT_SQ_end_a\R\XINT_SQ {#8#7#6#5#4#3#2#1}%
+ \xint_gob_til_R #8\XINT_zeroes_forviii_end\R\XINT_zeroes_forviii
}%
-\def\XINT_SQ_end_a\R\XINT_SQ #1#2\Z
+\edef\XINT_zeroes_forviii_end\R\XINT_zeroes_forviii #1#2#3#4#5#6#7#8#9\W
{%
- \XINT_SQ_end_b #1\Z
+ \noexpand\expandafter\space\noexpand\xint_gob_til_one #2#3#4#5#6#7#8%
}%
-\def\XINT_SQ_end_b #1#2#3#4#5#6#7%
+%%%%%%%%%%%%
+\def\XINT_rsepbyviii #1#2#3#4#5#6#7#8%
{%
- \xint_gob_til_R
- #7\XINT_SQ_end_vii
- #6\XINT_SQ_end_vi
- #5\XINT_SQ_end_v
- #4\XINT_SQ_end_iv
- #3\XINT_SQ_end_iii
- #2\XINT_SQ_end_ii
- \R\XINT_SQ_end_i
- \Z #2#3#4#5#6#7%
-}%
-\def\XINT_SQ_end_vii #1\Z #2#3#4#5#6#7#8\Z { #8}%
-\def\XINT_SQ_end_vi #1\Z #2#3#4#5#6#7#8\Z { #7#8000000}%
-\def\XINT_SQ_end_v #1\Z #2#3#4#5#6#7#8\Z { #6#7#800000}%
-\def\XINT_SQ_end_iv #1\Z #2#3#4#5#6#7#8\Z { #5#6#7#80000}%
-\def\XINT_SQ_end_iii #1\Z #2#3#4#5#6#7#8\Z { #4#5#6#7#8000}%
-\def\XINT_SQ_end_ii #1\Z #2#3#4#5#6#7#8\Z { #3#4#5#6#7#800}%
-\def\XINT_SQ_end_i \Z #1#2#3#4#5#6#7\Z { #1#2#3#4#5#6#70}%
-% \end{macrocode}
-% \subsection{\csh{XINT_cuz}}
-% \begin{macrocode}
-\edef\xint_cleanupzeros_andstop #1#2#3#4%
+ \XINT_rsepbyviii_b {#1#2#3#4#5#6#7#8}%
+}%
+\def\XINT_rsepbyviii_b #1#2#3#4#5#6#7#8#9%
{%
- \noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4\relax
+ #2#3#4#5#6#7#8#9\expandafter!\the\numexpr
+ 1#1\expandafter.\the\numexpr 1\XINT_rsepbyviii
}%
-\def\xint_cleanupzeros_nostop #1#2#3#4%
+\def\XINT_rsepbyviii_end_B #1\relax #2#3{#2.}%
+\def\XINT_rsepbyviii_end_A #11#2\expandafter #3\relax #4#5{#2.1#5.}%
+%%%%%%%%%%%%
+\def\XINT_sepandrev
{%
- \the\numexpr #1#2#3#4\relax
+ \expandafter\XINT_sepandrev_a\the\numexpr 1\XINT_rsepbyviii
}%
-\def\XINT_rev_andcuz #1%
+\def\XINT_sepandrev_a {\XINT_sepandrev_b {}}%
+\def\XINT_sepandrev_b #1#2.#3.#4.#5.#6.#7.#8.#9.%
{%
- \expandafter\xint_cleanupzeros_andstop
- \romannumeral0\XINT_rord_main {}#1%
- \xint_relax
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_relax
+ \xint_gob_til_R #9\XINT_sepandrev_end\R
+ \XINT_sepandrev_b {#9!#8!#7!#6!#5!#4!#3!#2!#1}%
+}%
+\def\XINT_sepandrev_end\R\XINT_sepandrev_b #1#2\W {\XINT_sepandrev_done #1}%
+\def\XINT_sepandrev_done #11#2!{ }%
+%%%%%%%%%%%%
+\def\XINT_sepandrev_andcount
+{%
+ \expandafter\XINT_sepandrev_andcount_a\the\numexpr 1\XINT_rsepbyviii
+}%
+\def\XINT_sepandrev_andcount_a {\XINT_sepandrev_andcount_b 0.{}}%
+\def\XINT_sepandrev_andcount_b #1.#2#3.#4.#5.#6.#7.#8.#9.%
+{%
+ \xint_gob_til_R #9\XINT_sepandrev_andcount_end\R
+ \expandafter\XINT_sepandrev_andcount_b \the\numexpr #1+\xint_c_xiv.%
+ {#9!#8!#7!#6!#5!#4!#3!#2}%
}%
+\def\XINT_sepandrev_andcount_end\R
+ \expandafter\XINT_sepandrev_andcount_b\the\numexpr #1+\xint_c_xiv.#2#3#4\W
+{\expandafter\XINT_sepandrev_andcount_done\the\numexpr \xint_c_ii*#3+#1.#2}%
+\edef\XINT_sepandrev_andcount_done #1.#21#3!%
+ {\noexpand\expandafter\space\noexpand\the\numexpr #1-#3.}%
% \end{macrocode}
-% \lverb|&
-% routine CleanUpZeros. Utilisée en particulier par la
-% soustraction.$\
-% INPUT: longueur **multiple de 4** (<-- ATTENTION)$\
-% OUTPUT: on a retiré tous les leading zéros, on n'est **plus*
-% nécessairement de longueur 4n$\
-% Délimiteur pour _main: \W\W\W\W\W\W\W\Z avec SEPT \W|
+% \subsection{Blocks of eight, for needs of v1.2 \csh{xintiiDivision}.}
% \begin{macrocode}
-\def\XINT_cuz #1%
+\def\XINT_sepbyviii_andcount
{%
- \XINT_cuz_loop #1\W\W\W\W\W\W\W\Z%
+ \expandafter\XINT_sepbyviii_andcount_a\the\numexpr\XINT_sepbyviii
}%
-\def\XINT_cuz_loop #1#2#3#4#5#6#7#8%
+\def\XINT_sepbyviii #1#2#3#4#5#6#7#8%
{%
- \xint_gob_til_W #8\xint_cuz_end_a\W
- \xint_gob_til_Z #8\xint_cuz_end_A\Z
- \XINT_cuz_check_a {#1#2#3#4#5#6#7#8}%
+ 1#1#2#3#4#5#6#7#8\expandafter!\the\numexpr\XINT_sepbyviii
}%
-\def\xint_cuz_end_a #1\XINT_cuz_check_a #2%
+\def\XINT_sepbyviii_end #1\relax {\relax\XINT_sepbyviii_andcount_end!}%
+\def\XINT_sepbyviii_andcount_a {\XINT_sepbyviii_andcount_b \xint_c_.}%
+\def\XINT_sepbyviii_andcount_b #1.#2!#3!#4!#5!#6!#7!#8!#9!%
{%
- \xint_cuz_end_b #2%
+ #2\expandafter!\the\numexpr#3\expandafter!\the\numexpr#4\expandafter
+ !\the\numexpr#5\expandafter!\the\numexpr#6\expandafter!\the\numexpr
+ #7\expandafter
+ !\the\numexpr#8\expandafter!\the\numexpr#9\expandafter!\the\numexpr
+ \expandafter\XINT_sepbyviii_andcount_b\the\numexpr #1+\xint_c_viii.%
}%
-\edef\xint_cuz_end_b #1#2#3#4#5\Z
+\def\XINT_sepbyviii_andcount_end #1\XINT_sepbyviii_andcount_b\the\numexpr
+ #2+\xint_c_viii.#3#4\W {\expandafter.\the\numexpr #2+#3.}%
+%%%%%%%%%%%%
+\def\XINT_rev_nounsep #1#2!#3!#4!#5!#6!#7!#8!#9!%
{%
- \noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4\relax
+ \xint_gob_til_R #9\XINT_rev_nounsep_end\R
+ \XINT_rev_nounsep {#9!#8!#7!#6!#5!#4!#3!#2!#1}%
}%
-\def\xint_cuz_end_A \Z\XINT_cuz_check_a #1{ 0}%
-\def\XINT_cuz_check_a #1%
+\def\XINT_rev_nounsep_end\R\XINT_rev_nounsep #1#2\W {\XINT_rev_nounsep_done #1}%
+\def\XINT_rev_nounsep_done #11{ 1}%
+%%%%%%%%%%%%
+\def\XINT_sepbyviii_Z #1#2#3#4#5#6#7#8%
{%
- \expandafter\XINT_cuz_check_b\the\numexpr #1\relax
+ 1#1#2#3#4#5#6#7#8\expandafter!\the\numexpr\XINT_sepbyviii_Z
}%
-\def\XINT_cuz_check_b #1%
+\def\XINT_sepbyviii_Z_end #1\relax {\relax\Z!}%
+%%%%%%%%%%%%
+\def\XINT_unsep_cuzsmall #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!%
{%
- \xint_gob_til_zero #1\xint_cuz_backtoloop 0\XINT_cuz_stop #1%
+ \xint_gob_til_R #9\XINT_unsep_cuzsmall_end\R
+ \XINT_unsep_cuzsmall {#1#2#3#4#5#6#7#8#9}%
}%
-\def\XINT_cuz_stop #1\W #2\Z{ #1}%
-\def\xint_cuz_backtoloop 0\XINT_cuz_stop 0{\XINT_cuz_loop }%
-% \end{macrocode}
-% \subsection{\csh{xintNum}}
-% \lverb|&
-% For example \xintNum {----+-+++---+----000000000000003}$\
-% 1.05 defines \xintiNum, which allows redefinition of \xintNum by xintfrac.sty
-% Slightly modified in 1.06b (\R->\xint_relax) to avoid initial re-scan of
-% input stack (while still allowing empty #1). In versions earlier than 1.09a
-% it was entirely up to the user to apply \xintnum; starting with 1.09a
-% arithmetic
-% macros of xint.sty (like earlier already xintfrac.sty with its own \xintnum)
-% make use of \xintnum. This allows arguments to
-% be count registers, or even \numexpr arbitrary long expressions (with the
-% trick of braces, see the user documentation).
-%
-% Note (22/06/14): \xintiNum jamais utilisé sous ce nom, le supprimer?
-% \XINT_num maintenant utilisé par le parseur de xintexpr.|
-% \begin{macrocode}
-\def\xintiNum {\romannumeral0\xintinum }%
-\def\xintinum #1%
+\def\XINT_unsep_cuzsmall_end\R
+ \XINT_unsep_cuzsmall #1{\XINT_unsep_cuzsmall_done #1}%
+\def\XINT_unsep_cuzsmall_done #1\R #2\W{\XINT_cuz_small #1}%
+\def\XINT_unsep_delim {1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W}%
+%%%%%%%%%%%%
+\def\XINT_div_unsepQ #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!%
{%
- \expandafter\XINT_num_loop
- \romannumeral-`0#1\xint_relax\xint_relax\xint_relax\xint_relax
- \xint_relax\xint_relax\xint_relax\xint_relax\Z
+ \xint_gob_til_R #9\XINT_div_unsepQ_end\R
+ \XINT_div_unsepQ {#1#2#3#4#5#6#7#8#9}%
}%
-\let\xintNum\xintiNum \let\xintnum\xintinum
-\def\XINT_num #1%
+\def\XINT_div_unsepQ_end\R\XINT_div_unsepQ #1{\XINT_div_unsepQ_x #1}%
+\def\XINT_div_unsepQ_x #1#2#3#4#5#6#7#8#9%
{%
- \XINT_num_loop #1\xint_relax\xint_relax\xint_relax\xint_relax
- \xint_relax\xint_relax\xint_relax\xint_relax\Z
+ \xint_gob_til_R #9\XINT_div_unsepQ_e \R
+ \xint_gob_til_eightzeroes #1#2#3#4#5#6#7#8\XINT_div_unsepQ_y 00000000%
+ \expandafter\XINT_div_unsepQ_done \the\numexpr #1#2#3#4#5#6#7#8.#9%
}%
-\def\XINT_num_loop #1#2#3#4#5#6#7#8%
+\def\XINT_div_unsepQ_e\R\xint_gob_til_eightzeroes #1\XINT_div_unsepQ_y #2\W
+ {\the\numexpr #1\relax \Z}%
+\def\XINT_div_unsepQ_y #1.#2\R #3\W{\XINT_cuz_small #2\Z}%
+\def\XINT_div_unsepQ_done #1.#2\R #3\W { #1#2\Z}%
+%%%%%%%%%%%%
+\def\XINT_div_unsepR #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!%
{%
- \xint_gob_til_xint_relax #8\XINT_num_end\xint_relax
- \XINT_num_NumEight #1#2#3#4#5#6#7#8%
+ \xint_gob_til_R #9\XINT_div_unsepR_end\R
+ \XINT_div_unsepR {#1#2#3#4#5#6#7#8#9}%
}%
-\edef\XINT_num_end\xint_relax\XINT_num_NumEight #1\xint_relax #2\Z
+\def\XINT_div_unsepR_end\R\XINT_div_unsepR #1{\XINT_div_unsepR_done #1}%
+\def\XINT_div_unsepR_done #1\R #2\W {\XINT_cuz #1\R}%
+%%%%%%%%%%%%
+\def\XINT_unrevbyviii #11#2!1#3!1#4!1#5!1#6!1#7!1#8!1#9!%
{%
- \noexpand\expandafter\space\noexpand\the\numexpr #1+\xint_c_\relax
+ \xint_gob_til_R #9\XINT_unrevbyviii_a\R
+ \XINT_unrevbyviii {#9#8#7#6#5#4#3#2#1}%
}%
-\def\XINT_num_NumEight #1#2#3#4#5#6#7#8%
+\edef\XINT_unrevbyviii_a\R\XINT_unrevbyviii #1#2\W
+ {\noexpand\expandafter\space
+ \noexpand\romannumeral-`0\noexpand\xint_gob_til_Z #1}%
+\def\XINT_smallunrevbyviii 1#1!1#2!1#3!1#4!1#5!1#6!1#7!1#8!#9\W%
{%
- \ifnum \numexpr #1#2#3#4#5#6#7#8+\xint_c_= \xint_c_
- \xint_afterfi {\expandafter\XINT_num_keepsign_a
- \the\numexpr #1#2#3#4#5#6#7#81\relax}%
- \else
- \xint_afterfi {\expandafter\XINT_num_finish
- \the\numexpr #1#2#3#4#5#6#7#8\relax}%
- \fi
+ \expandafter\XINT_cuz_small\xint_gob_til_Z #8#7#6#5#4#3#2#1%
}%
-\def\XINT_num_keepsign_a #1%
+% \end{macrocode}
+% \subsection{\csh{xintReverseDigits}}
+% \lverb|v1.2. Needed now by \xintLDg.|
+% \begin{macrocode}
+\def\XINT_microrevsep #1#2#3#4#5#6#7#8%
{%
- \xint_gob_til_one#1\XINT_num_gobacktoloop 1\XINT_num_keepsign_b
+ 1#8#7#6#5#4#3#2#1\expandafter!\the\numexpr\XINT_microrevsep
}%
-\def\XINT_num_gobacktoloop 1\XINT_num_keepsign_b {\XINT_num_loop }%
-\def\XINT_num_keepsign_b #1{\XINT_num_loop -}%
-\def\XINT_num_finish #1\xint_relax #2\Z { #1}%
+\def\XINT_microrevsep_end #1\W #2\expandafter #3\Z{#2!}%
+\def\xintReverseDigits {\romannumeral0\xintreversedigits }%
+\def\xintreversedigits #1{\expandafter\XINT_reversedigits\romannumeral-`0#1\Z}%
+\def\XINT_reversedigits #1%
+{%
+ \xint_UDsignfork
+ #1{\expandafter\xint_minus_thenstop\romannumeral0\XINT_reversedigits_a}%
+ -{\XINT_reversedigits_a #1}%
+ \krof
+}%
+\def\XINT_reversedigits_a #1\Z
+{%
+ \expandafter\XINT_revdigits_a\the\numexpr\expandafter\XINT_microrevsep
+ \romannumeral-`0#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\Z
+ 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+}%
+\def\XINT_revdigits_a {\XINT_revdigits_b {}}%
+\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}%
+}%
+\edef\XINT_revdigits_end\R\XINT_revdigits_b #1#2\W
+ {\noexpand\expandafter\space\noexpand\xint_gob_til_Z #1}%
% \end{macrocode}
% \subsection{\csh{xintSgn}, \csh{xintiiSgn}, \csh{XINT_Sgn}, \csh{XINT_cntSgn}}
% \lverb|&
@@ -15510,13 +15915,12 @@ $1$ or $-1$.
{%
\xint_UDzerominusfork
#1-\xint_c_
- 0#1\m@ne % I will not allocate a count only for -1?
+ 0#1\xint_c_mone
0-\xint_c_i
\krof
}%
% \end{macrocode}
-% \subsection{\csh{xintiOpp}}
-% \lverb|\xintnum added in 1.09a|
+% \subsection{\csh{xintiOpp}, \csh{xintiiOpp}}
% \begin{macrocode}
\def\xintiiOpp {\romannumeral0\xintiiopp }%
\def\xintiiopp #1%
@@ -15528,7 +15932,6 @@ $1$ or $-1$.
{%
\expandafter\XINT_opp \romannumeral0\xintnum{#1}%
}%
-\let\xintOpp\xintiOpp \let\xintopp\xintiopp
\def\XINT_Opp #1{\romannumeral0\XINT_opp #1}%
\def\XINT_opp #1%
{%
@@ -15556,7 +15959,6 @@ $1$ or $-1$.
{%
\expandafter\XINT_abs \romannumeral0\xintnum{#1}%
}%
-\let\xintAbs\xintiAbs \let\xintabs\xintiabs
\def\XINT_Abs #1{\romannumeral0\XINT_abs #1}%
\def\XINT_abs #1%
{%
@@ -15600,33 +16002,34 @@ $1$ or $-1$.
% defining \xintiiOdd which is used once (currently) elsewhere .
%
% bug fix (1.1b): \xintiiLDg is needed by the division macros next, thus
-% it needs to be in the xintcore.sty|
+% it needs to be in the xintcore.sty.
+%
+% Rewritten for 1.2.|
% \begin{macrocode}
+\def\xintLDg {\romannumeral0\xintldg }%
+\def\xintldg #1{\xintiildg {\xintNum{#1}}}%
\def\xintiiLDg {\romannumeral0\xintiildg }%
\def\xintiildg #1%
{%
- \expandafter\XINT_ldg\expandafter {\romannumeral-`0#1}%
-}%
-\def\xintLDg {\romannumeral0\xintldg }%
-\def\xintldg #1%
-{%
- \expandafter\XINT_ldg\expandafter {\romannumeral0\xintnum{#1}}%
-}%
-\def\XINT_LDg #1{\romannumeral0\XINT_ldg {#1}}%
-\def\XINT_ldg #1%
-{%
- \expandafter\XINT_ldg_\romannumeral0\xintreverseorder {#1}\Z
+ \expandafter\XINT_ldg_done\romannumeral0%
+ \expandafter\XINT_revdigits_a\the\numexpr\expandafter\XINT_microrevsep
+ \romannumeral0\expandafter\XINT_abs
+ \romannumeral-`0#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\Z
+ 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+ \Z
}%
-\def\XINT_ldg_ #1#2\Z{ #1}%
+\def\XINT_ldg_done #1#2\Z { #1}%
% \end{macrocode}
% \subsection{\csh{xintDouble}}
-% \lverb|v1.08|
+% \lverb|v1.08. Rewritten for v1.2.|
% \begin{macrocode}
\def\xintDouble {\romannumeral0\xintdouble }%
\def\xintdouble #1%
{%
- \expandafter\XINT_dbl\romannumeral-`0#1%
- \R\R\R\R\R\R\R\Z \W\W\W\W\W\W\W
+ \expandafter\XINT_dbl\romannumeral-`0#1\Z
}%
\def\XINT_dbl #1%
{%
@@ -15636,44 +16039,31 @@ $1$ or $-1$.
0-{\XINT_dbl_pos #1}%
\krof
}%
-\def\XINT_dbl_zero #1\Z \W\W\W\W\W\W\W { 0}%
+\def\XINT_dbl_zero #1\Z { 0}%
\def\XINT_dbl_neg
{\expandafter\xint_minus_thenstop\romannumeral0\XINT_dbl_pos }%
-\def\XINT_dbl_pos
-{%
- \expandafter\XINT_dbl_a \expandafter{\expandafter}\expandafter 0%
- \romannumeral0\XINT_SQ {}%
-}%
-\def\XINT_dbl_a #1#2#3#4#5#6#7#8#9%
-{%
- \xint_gob_til_W #9\XINT_dbl_end_a\W
- \expandafter\XINT_dbl_b
- \the\numexpr \xint_c_x^viii+#2+\xint_c_ii*#9#8#7#6#5#4#3\relax {#1}%
-}%
-\def\XINT_dbl_b 1#1#2#3#4#5#6#7#8#9%
+\def\XINT_dbl_pos #1\Z
{%
- \XINT_dbl_a {#2#3#4#5#6#7#8#9}{#1}%
+ \expandafter\XINT_dbl_pos_aa
+ \romannumeral0\expandafter\XINT_sepandrev
+ \romannumeral0\XINT_zeroes_forviii #1\R\R\R\R\R\R\R\R{10}0000001\W
+ #1\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax XX%
+ \R.\R.\R.\R.\R.\R.\R.\R.\W 1\Z!%
+ 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
}%
-\def\XINT_dbl_end_a #1+#2+#3\relax #4%
+\def\XINT_dbl_pos_aa
{%
- \expandafter\XINT_dbl_end_b #2#4%
-}%
-\edef\XINT_dbl_end_b #1#2#3#4#5#6#7#8%
-{%
- \noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4#5#6#7#8\relax
+ \expandafter\XINT_mul_out\the\numexpr\XINT_verysmallmul 0.2!%
}%
% \end{macrocode}
% \subsection{\csh{xintHalf}}
-% \lverb|v1.08. Relase 1.1 left it in xint.sty, but it is needed by the
-% division routines included in xintcore.sty. Thus moved here for bugfix
-% release 1.1c.
-% Also \XINT_SQ which it uses. Moved here \xintDouble as well by sympathy.|
+% \lverb|v1.08. Rewritten for v1.2.|
% \begin{macrocode}
\def\xintHalf {\romannumeral0\xinthalf }%
\def\xinthalf #1%
{%
- \expandafter\XINT_half\romannumeral-`0#1%
- \R\R\R\R\R\R\R\Z \W\W\W\W\W\W\W
+ \expandafter\XINT_half\romannumeral-`0#1\Z
}%
\def\XINT_half #1%
{%
@@ -15683,52 +16073,38 @@ $1$ or $-1$.
0-{\XINT_half_pos #1}%
\krof
}%
-\def\XINT_half_zero #1\Z \W\W\W\W\W\W\W { 0}%
+\def\XINT_half_zero #1\Z { 0}%
\def\XINT_half_neg {\expandafter\XINT_opp\romannumeral0\XINT_half_pos }%
-\def\XINT_half_pos {\expandafter\XINT_half_a\romannumeral0\XINT_SQ {}}%
-\def\XINT_half_a #1#2#3#4#5#6#7#8%
-{%
- \xint_gob_til_W #8\XINT_half_dont\W
- \expandafter\XINT_half_b
- \the\numexpr \xint_c_x^viii+\xint_c_v*#7#6#5#4#3#2#1\relax #8%
-}%
-\edef\XINT_half_dont\W\expandafter\XINT_half_b
- \the\numexpr \xint_c_x^viii+\xint_c_v*#1#2#3#4#5#6#7\relax \W\W\W\W\W\W\W
-{%
- \noexpand\expandafter\space
- \noexpand\the\numexpr (#1#2#3#4#5#6#7+\xint_c_i)/\xint_c_ii-\xint_c_i \relax
-}%
-\def\XINT_half_b 1#1#2#3#4#5#6#7#8%
-{%
- \XINT_half_c {#2#3#4#5#6#7}{#1}%
-}%
-\def\XINT_half_c #1#2#3#4#5#6#7#8#9%
-{%
- \xint_gob_til_W #3\XINT_half_end_a #2\W
- \expandafter\XINT_half_d
- \the\numexpr \xint_c_x^viii+\xint_c_v*#9#8#7#6#5#4#3+#2\relax {#1}%
-}%
-\def\XINT_half_d 1#1#2#3#4#5#6#7#8#9%
+\def\XINT_half_pos #1\Z
{%
- \XINT_half_c {#2#3#4#5#6#7#8#9}{#1}%
+ \expandafter\XINT_half_pos_a
+ \romannumeral0\expandafter\XINT_sepandrev
+ \romannumeral0\XINT_zeroes_forviii #1\R\R\R\R\R\R\R\R{10}0000001\W
+ #1\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax XX%
+ \R.\R.\R.\R.\R.\R.\R.\R.\W
+ 1\Z!%
+ 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
}%
-\def\XINT_half_end_a #1\W #2\relax #3%
+\def\XINT_half_pos_a
+ {\expandafter\XINT_half_pos_b\the\numexpr\XINT_verysmallmul 0.5!}%
+\def\XINT_half_pos_b 1#1#2#3#4#5#6#7#8!1#9%
{%
- \xint_gob_til_zero #1\XINT_half_end_b 0\space #1#3%
+ \xint_gob_til_Z #9\XINT_half_small \Z
+ \XINT_mul_out 1#1#2#3#4#5#6#7!1#9%
}%
-\edef\XINT_half_end_b 0\space 0#1#2#3#4#5#6#7%
+\edef\XINT_half_small \Z\XINT_mul_out 1#1!#2\W
{%
- \noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4#5#6#7\relax
+ \noexpand\expandafter\space\noexpand\the\numexpr #1\relax
}%
% \end{macrocode}
% \subsection{\csh{xintDec}}
-% \lverb!v1.08!
+% \lverb|v1.08. Rewritten for v1.2.|
% \begin{macrocode}
\def\xintDec {\romannumeral0\xintdec }%
\def\xintdec #1%
{%
- \expandafter\XINT_dec\romannumeral-`0#1%
- \R\R\R\R\R\R\R\R\Z \W\W\W\W\W\W\W\W
+ \expandafter\XINT_dec\romannumeral-`0#1\Z
}%
\def\XINT_dec #1%
{%
@@ -15738,47 +16114,28 @@ $1$ or $-1$.
0-{\XINT_dec_pos #1}%
\krof
}%
-\def\XINT_dec_zero #1\W\W\W\W\W\W\W\W { -1}%
+\def\XINT_dec_zero #1\Z { -1}%
\def\XINT_dec_neg
{\expandafter\xint_minus_thenstop\romannumeral0\XINT_inc_pos }%
-\def\XINT_dec_pos
-{%
- \expandafter\XINT_dec_a \expandafter{\expandafter}%
- \romannumeral0\XINT_OQ {}%
-}%
-\def\XINT_dec_a #1#2#3#4#5#6#7#8#9%
+\def\XINT_dec_pos #1\Z
{%
- \expandafter\XINT_dec_b
- \the\numexpr 11#9#8#7#6#5#4#3#2-\xint_c_i\relax {#1}%
-}%
-\def\XINT_dec_b 1#1%
-{%
- \xint_gob_til_one #1\XINT_dec_A 1\XINT_dec_c
-}%
-\def\XINT_dec_c #1#2#3#4#5#6#7#8#9{\XINT_dec_a {#1#2#3#4#5#6#7#8#9}}%
-\def\XINT_dec_A 1\XINT_dec_c #1#2#3#4#5#6#7#8#9%
- {\XINT_dec_B {#1#2#3#4#5#6#7#8#9}}%
-\def\XINT_dec_B #1#2\W\W\W\W\W\W\W\W
-{%
- \expandafter\XINT_dec_cleanup
- \romannumeral0\XINT_rord_main {}#2%
- \xint_relax
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_relax
- #1%
+ \expandafter\XINT_dec_pos_aa
+ \romannumeral0\expandafter\XINT_sepandrev
+ \romannumeral0\XINT_zeroes_forviii #1\R\R\R\R\R\R\R\R{10}0000001\W
+ #1\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax XX%
+ \R.\R.\R.\R.\R.\R.\R.\R.\W
+ \Z!\Z!\Z!\Z!\Z!\W
}%
-\edef\XINT_dec_cleanup #1#2#3#4#5#6#7#8%
- {\noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4#5#6#7#8\relax }%
+\def\XINT_dec_pos_aa {\XINT_sub_aa 100000001!\Z!\Z!\Z!\Z!\Z!\W }%
% \end{macrocode}
% \subsection{\csh{xintInc}}
-% \lverb!v1.08!
+% \lverb!v1.08. Rewritten for v1.2.!
% \begin{macrocode}
\def\xintInc {\romannumeral0\xintinc }%
\def\xintinc #1%
{%
- \expandafter\XINT_inc\romannumeral-`0#1%
- \R\R\R\R\R\R\R\R\Z \W\W\W\W\W\W\W\W
+ \expandafter\XINT_inc\romannumeral-`0#1\Z
}%
\def\XINT_inc #1%
{%
@@ -15788,520 +16145,231 @@ $1$ or $-1$.
0-{\XINT_inc_pos #1}%
\krof
}%
-\def\XINT_inc_zero #1\W\W\W\W\W\W\W\W { 1}%
+\def\XINT_inc_zero #1\Z { 1}%
\def\XINT_inc_neg {\expandafter\XINT_opp\romannumeral0\XINT_dec_pos }%
-\def\XINT_inc_pos
-{%
- \expandafter\XINT_inc_a \expandafter{\expandafter}%
- \romannumeral0\XINT_OQ {}%
-}%
-\def\XINT_inc_a #1#2#3#4#5#6#7#8#9%
-{%
- \xint_gob_til_W #9\XINT_inc_end\W
- \expandafter\XINT_inc_b
- \the\numexpr 10#9#8#7#6#5#4#3#2+\xint_c_i\relax {#1}%
-}%
-\def\XINT_inc_b 1#1%
-{%
- \xint_gob_til_zero #1\XINT_inc_A 0\XINT_inc_c
-}%
-\def\XINT_inc_c #1#2#3#4#5#6#7#8#9{\XINT_inc_a {#1#2#3#4#5#6#7#8#9}}%
-\def\XINT_inc_A 0\XINT_inc_c #1#2#3#4#5#6#7#8#9%
- {\XINT_dec_B {#1#2#3#4#5#6#7#8#9}}%
-\def\XINT_inc_end\W #1\relax #2{ 1#2}%
-% \end{macrocode}
-% \subsection{Variants for addition sub-routines}
-% \lverb|&
-% Release 1.03 re-organizes sub-routines to facilitate future developments: the
-% diverse variants of addition, with diverse conditions on inputs and output are
-% first listed; they will be used in multiplication, or in the summation, or in
-% the power routines. I am aware that the commenting is close to non-existent,
-% sorry about that.
-%
-% Addition and multiplication each have multiple implementations corresponding
-% to slightly differing formats on input and on output.|
-%
-% \subsubsection{Addition vI: \csh{XINT_add_A}}
-% \lverb|&
-% INPUT:$\
-% \romannumeral0\XINT_add_A 0{}<N1>\W\X\Y\Z <N2>\W\X\Y\Z$\
-% 1. <N1> et <N2> renversés $\
-% 2. de longueur 4n (avec des leading zéros éventuels)$\
-% 3. l'un des deux ne doit pas se terminer par 0000$\$relax
-% [Donc on peut avoir 0000 comme input si l'autre est >0 et ne se termine pas en
-% 0000 bien sûr]. On peut avoir l'un des deux vides. Mais alors l'autre ne doit
-% être ni vide ni 0000.
-%
-% OUTPUT: la somme <N1>+<N2>, ordre normal, plus sur 4n, pas de leading zeros
-% La procédure est plus rapide lorsque <N1> est le plus court des deux.$\
-% Nota bene: (30 avril 2013). J'ai une version qui est deux fois plus rapide sur
-% des nombres d'environ 1000 chiffres chacun, et qui commence à être avantageuse
-% pour des nombres d'au moins 200 chiffres. Cependant il serait vraiment
-% compliqué d'en étendre l'utilisation aux emplois de l'addition dans les
-% autres routines, comme celle de multiplication ou celle de division; et son
-% implémentation ajouterait au minimum la mesure de la longueur des summands.|
-% \begin{macrocode}
-\def\XINT_add_A #1#2#3#4#5#6%
-{%
- \xint_gob_til_W #3\xint_add_az\W
- \XINT_add_AB #1{#3#4#5#6}{#2}%
-}%
-\def\xint_add_az\W\XINT_add_AB #1#2%
-{%
- \XINT_add_AC_checkcarry #1%
-}%
-% \end{macrocode}
-% \lverb|&
-% ici #2 est prévu pour l'addition, mais attention il devra être renversé
-% pour \numexpr. #3 = résultat partiel. #4 = chiffres qui restent. On vérifie si
-% le deuxième nombre s'arrête.|
-% \begin{macrocode}
-\def\XINT_add_AB #1#2#3#4\W\X\Y\Z #5#6#7#8%
-{%
- \xint_gob_til_W #5\xint_add_bz\W
- \XINT_add_ABE #1#2{#8#7#6#5}{#3}#4\W\X\Y\Z
-}%
-\def\XINT_add_ABE #1#2#3#4#5#6%
-{%
- \expandafter\XINT_add_ABEA\the\numexpr #1+10#5#4#3#2+#6.%
-}%
-\def\XINT_add_ABEA #1#2#3.#4%
-{%
- \XINT_add_A #2{#3#4}%
-}%
-% \end{macrocode}
-% \lverb|&
-% ici le deuxième nombre est fini
-% #6 part à la poubelle, #2#3#4#5 est le #2 dans \XINT_add_AB
-% on ne vérifie pas la retenue cette fois, mais les fois suivantes|
-% \begin{macrocode}
-\def\xint_add_bz\W\XINT_add_ABE #1#2#3#4#5#6%
-{%
- \expandafter\XINT_add_CC\the\numexpr #1+10#5#4#3#2.%
-}%
-\def\XINT_add_CC #1#2#3.#4%
-{%
- \XINT_add_AC_checkcarry #2{#3#4}% on va examiner et \'eliminer #2
-}%
-% \end{macrocode}
-% \lverb|&
-% retenue plus chiffres qui restent de l'un des deux nombres.
-% #2 = résultat partiel
-% #3#4#5#6 = summand, avec plus significatif à droite|
-% \begin{macrocode}
-\def\XINT_add_AC_checkcarry #1%
-{%
- \xint_gob_til_zero #1\xint_add_AC_nocarry 0\XINT_add_C
-}%
-\def\xint_add_AC_nocarry 0\XINT_add_C #1#2\W\X\Y\Z
-{%
- \expandafter
- \xint_cleanupzeros_andstop
- \romannumeral0%
- \XINT_rord_main {}#2%
- \xint_relax
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_relax
- #1%
-}%
-\def\XINT_add_C #1#2#3#4#5%
-{%
- \xint_gob_til_W #2\xint_add_cz\W
- \XINT_add_CD {#5#4#3#2}{#1}%
-}%
-\def\XINT_add_CD #1%
-{%
- \expandafter\XINT_add_CC\the\numexpr 1+10#1.%
-}%
-\def\xint_add_cz\W\XINT_add_CD #1#2{ 1#2}%
-% \end{macrocode}
-% \subsubsection{Addition vII: \csh{XINT_addr_A}}
-% \lverb|&
-% INPUT: \romannumeral0\XINT_addr_A 0{}<N1>\W\X\Y\Z <N2>\W\X\Y\Z
-%
-% Comme \XINT_add_A, la différence principale c'est qu'elle donne son résultat
-% aussi *sur 4n*, renversé. De plus cette variante accepte que l'un ou même les
-% deux inputs soient vides. Utilisé par la sommation et par la division (pour
-% les quotients). Et aussi par la multiplication d'ailleurs.$\
-% INPUT: comme pour \XINT_add_A$\
-% 1. <N1> et <N2> renversés $\
-% 2. de longueur 4n (avec des leading zéros éventuels)$\
-% 3. l'un des deux ne doit pas se terminer par 0000$\
-% OUTPUT: la somme <N1>+<N2>, *aussi renversée* et *sur 4n*|
-% \begin{macrocode}
-\def\XINT_addr_A #1#2#3#4#5#6%
-{%
- \xint_gob_til_W #3\xint_addr_az\W
- \XINT_addr_B #1{#3#4#5#6}{#2}%
-}%
-\def\xint_addr_az\W\XINT_addr_B #1#2%
-{%
- \XINT_addr_AC_checkcarry #1%
-}%
-\def\XINT_addr_B #1#2#3#4\W\X\Y\Z #5#6#7#8%
-{%
- \xint_gob_til_W #5\xint_addr_bz\W
- \XINT_addr_E #1#2{#8#7#6#5}{#3}#4\W\X\Y\Z
-}%
-\def\XINT_addr_E #1#2#3#4#5#6%
-{%
- \expandafter\XINT_addr_ABEA\the\numexpr #1+10#5#4#3#2+#6\relax
-}%
-\def\XINT_addr_ABEA #1#2#3#4#5#6#7%
-{%
- \XINT_addr_A #2{#7#6#5#4#3}%
-}%
-\def\xint_addr_bz\W\XINT_addr_E #1#2#3#4#5#6%
-{%
- \expandafter\XINT_addr_CC\the\numexpr #1+10#5#4#3#2\relax
-}%
-\def\XINT_addr_CC #1#2#3#4#5#6#7%
-{%
- \XINT_addr_AC_checkcarry #2{#7#6#5#4#3}%
-}%
-\def\XINT_addr_AC_checkcarry #1%
-{%
- \xint_gob_til_zero #1\xint_addr_AC_nocarry 0\XINT_addr_C
-}%
-\def\xint_addr_AC_nocarry 0\XINT_addr_C #1#2\W\X\Y\Z { #1#2}%
-\def\XINT_addr_C #1#2#3#4#5%
-{%
- \xint_gob_til_W #2\xint_addr_cz\W
- \XINT_addr_D {#5#4#3#2}{#1}%
-}%
-\def\XINT_addr_D #1%
-{%
- \expandafter\XINT_addr_CC\the\numexpr 1+10#1\relax
-}%
-\def\xint_addr_cz\W\XINT_addr_D #1#2{ #21000}%
-% \end{macrocode}
-% \subsubsection{Addition vIII: \csh{XINT_addm_A}}
-% \lverb|&
-% INPUT:\romannumeral0\XINT_addm_A 0{}<N1>\W\X\Y\Z <N2>\W\X\Y\Z$\
-% 1. <N1> et <N2> renversés$\
-% 2. <N1> de longueur 4n ; <N2> non$\
-% 3. <N2> est *garanti au moins aussi long* que <N1>$\
-% OUTPUT: la somme <N1>+<N2>, ordre normal, pas sur 4n, leading zeros retirés.
-% Utilisé par la multiplication.|
-% \begin{macrocode}
-\def\XINT_addm_A #1#2#3#4#5#6%
-{%
- \xint_gob_til_W #3\xint_addm_az\W
- \XINT_addm_AB #1{#3#4#5#6}{#2}%
-}%
-\def\xint_addm_az\W\XINT_addm_AB #1#2%
-{%
- \XINT_addm_AC_checkcarry #1%
-}%
-\def\XINT_addm_AB #1#2#3#4\W\X\Y\Z #5#6#7#8%
-{%
- \XINT_addm_ABE #1#2{#8#7#6#5}{#3}#4\W\X\Y\Z
-}%
-\def\XINT_addm_ABE #1#2#3#4#5#6%
-{%
- \expandafter\XINT_addm_ABEA\the\numexpr #1+10#5#4#3#2+#6.%
-}%
-\def\XINT_addm_ABEA #1#2#3.#4%
-{%
- \XINT_addm_A #2{#3#4}%
-}%
-\def\XINT_addm_AC_checkcarry #1%
-{%
- \xint_gob_til_zero #1\xint_addm_AC_nocarry 0\XINT_addm_C
-}%
-\def\xint_addm_AC_nocarry 0\XINT_addm_C #1#2\W\X\Y\Z
-{%
- \expandafter
- \xint_cleanupzeros_andstop
- \romannumeral0%
- \XINT_rord_main {}#2%
- \xint_relax
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_relax
- #1%
-}%
-\def\XINT_addm_C #1#2#3#4#5%
-{%
- \xint_gob_til_W
- #5\xint_addm_cw
- #4\xint_addm_cx
- #3\xint_addm_cy
- #2\xint_addm_cz
- \W\XINT_addm_CD {#5#4#3#2}{#1}%
-}%
-\def\XINT_addm_CD #1%
-{%
- \expandafter\XINT_addm_CC\the\numexpr 1+10#1.%
-}%
-\def\XINT_addm_CC #1#2#3.#4%
-{%
- \XINT_addm_AC_checkcarry #2{#3#4}%
-}%
-\def\xint_addm_cw
- #1\xint_addm_cx
- #2\xint_addm_cy
- #3\xint_addm_cz
- \W\XINT_addm_CD
-{%
- \expandafter\XINT_addm_CDw\the\numexpr 1+#1#2#3.%
-}%
-\def\XINT_addm_CDw #1.#2#3\X\Y\Z
-{%
- \XINT_addm_end #1#3%
-}%
-\def\xint_addm_cx
- #1\xint_addm_cy
- #2\xint_addm_cz
- \W\XINT_addm_CD
-{%
- \expandafter\XINT_addm_CDx\the\numexpr 1+#1#2.%
-}%
-\def\XINT_addm_CDx #1.#2#3\Y\Z
-{%
- \XINT_addm_end #1#3%
-}%
-\def\xint_addm_cy
- #1\xint_addm_cz
- \W\XINT_addm_CD
-{%
- \expandafter\XINT_addm_CDy\the\numexpr 1+#1.%
-}%
-\def\XINT_addm_CDy #1.#2#3\Z
-{%
- \XINT_addm_end #1#3%
-}%
-\def\xint_addm_cz\W\XINT_addm_CD #1#2#3{\XINT_addm_end #1#3}%
-\edef\XINT_addm_end #1#2#3#4#5%
- {\noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4#5\relax}%
-% \end{macrocode}
-% \subsubsection{Addition vIV: \csh{XINT_addp_A}}
-% \lverb|&
-% INPUT:
-% \romannumeral0\XINT_addp_A 0{}<N1>\W\X\Y\Z <N2>\W\X\Y\Z$\
-% 1. <N1> et <N2> renversés$\
-% 2. <N1> de longueur 4n ; <N2> non$\
-% 3. <N2> est *garanti au moins aussi long* que <N1>$\
-% OUTPUT: la somme <N1>+<N2>, dans l'ordre renversé, sur 4n, et en faisant
-% attention de ne pas terminer en 0000.
-% Utilisé par la multiplication servant pour le calcul des puissances.|
+\def\XINT_inc_pos #1\Z
+{%
+ \expandafter\XINT_inc_pos_aa
+ \romannumeral0\expandafter\XINT_sepandrev
+ \romannumeral0\XINT_zeroes_forviii #1\R\R\R\R\R\R\R\R{10}0000001\W
+ #1\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax XX%
+ \R.\R.\R.\R.\R.\R.\R.\R.\W
+ \Z!\Z!\Z!\Z!\Z!\W
+}%
+\def\XINT_inc_pos_aa {\XINT_add_aa 100000001!\Z!\Z!\Z!\Z!\Z!\W }%
+% \end{macrocode}
+% \subsection{Core arithmetic}
+% \lverb|The four operations have been rewritten entirely for release v1.2.
+% The new routines works with separated blocks of eight digits. They all measure
+% first the lengths of the arguments, even addition and subtraction (this was
+% not the case with xintcore.sty 1.1 or earlier.)
+%
+% The technique of chaining \the\numexpr induces a limitation on the
+% maximal size depending on the size of the input save stack and the maximum
+% expansion depth. For the current (TL2015) settings (5000, resp. 10000), the
+% induced limit for addition of numbers is at 19968 and for multiplication
+% it is observed to be 19959 (valid as of 2015/10/07).
+%
+% Side remark: I tested that \the\numexpr was more efficient than \number. But
+% it reduced the allowable numbers for addition from 19976 digits to 19968
+% digits.|
+%
+% \subsection{\csbh{xintiAdd}, \csbh{xintiiAdd}}
% \begin{macrocode}
-\def\XINT_addp_A #1#2#3#4#5#6%
-{%
- \xint_gob_til_W #3\xint_addp_az\W
- \XINT_addp_AB #1{#3#4#5#6}{#2}%
-}%
-\def\xint_addp_az\W\XINT_addp_AB #1#2%
+\def\xintiAdd {\romannumeral0\xintiadd }%
+\def\xintiadd #1{\expandafter\XINT_iadd\romannumeral0\xintnum{#1}\Z }%
+\def\xintiiAdd {\romannumeral0\xintiiadd }%
+\def\xintiiadd #1{\expandafter\XINT_iiadd\romannumeral-`0#1\Z }%
+\def\XINT_iiadd #1#2\Z #3%
{%
- \XINT_addp_AC_checkcarry #1%
+ \expandafter\XINT_add_nfork\expandafter #1\romannumeral-`0#3\Z #2\Z
}%
-\def\XINT_addp_AC_checkcarry #1%
+\def\XINT_iadd #1#2\Z #3%
{%
- \xint_gob_til_zero #1\xint_addp_AC_nocarry 0\XINT_addp_C
+ \expandafter\XINT_add_nfork\expandafter #1\romannumeral0\xintnum{#3}\Z #2\Z
}%
-\def\xint_addp_AC_nocarry 0\XINT_addp_C
+\def\XINT_add_fork #1#2\Z #3\Z {\XINT_add_nfork #1#3\Z #2\Z}%
+\def\XINT_add_nfork #1#2%
{%
- \XINT_addp_F
-}%
-\def\XINT_addp_AB #1#2#3#4\W\X\Y\Z #5#6#7#8%
-{%
- \XINT_addp_ABE #1#2{#8#7#6#5}{#3}#4\W\X\Y\Z
+ \xint_UDzerofork
+ #1\XINT_add_firstiszero
+ #2\XINT_add_secondiszero
+ 0{}%
+ \krof
+ \xint_UDsignsfork
+ #1#2\XINT_add_minusminus
+ #1-\XINT_add_minusplus
+ #2-\XINT_add_plusminus
+ --\XINT_add_plusplus
+ \krof #1#2%
}%
-\def\XINT_addp_ABE #1#2#3#4#5#6%
-{%
- \expandafter\XINT_addp_ABEA\the\numexpr #1+10#5#4#3#2+#6\relax
+\def\XINT_add_firstiszero #1\krof 0#2#3\Z #4\Z { #2#3}%
+\def\XINT_add_secondiszero #1\krof #20#3\Z #4\Z { #2#4}%
+\def\XINT_add_minusminus #1#2%
+ {\expandafter\xint_minus_thenstop\romannumeral0\XINT_add_pp_a {}{}}%
+\def\XINT_add_minusplus #1#2{\XINT_sub_mm_a {}#2}%
+\def\XINT_add_plusminus #1#2%
+ {\expandafter\XINT_opp\romannumeral0\XINT_sub_mm_a #1{}}%
+\def\XINT_add_pp_a #1#2#3\Z
+{%
+ \expandafter\XINT_add_pp_b
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #2#3\R\R\R\R\R\R\R\R{10}0000001\W
+ #2#3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_iii
+ \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii
+ \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W
+ \X #1%
+}%
+\let\XINT_add_plusplus \XINT_add_pp_a
+\def\XINT_add_pp_b #1.#2\X #3\Z
+{%
+ \expandafter\XINT_add_checklengths
+ \the\numexpr #1\expandafter.%
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #3\R\R\R\R\R\R\R\R{10}0000001\W
+ #3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_iii
+ \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii
+ \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W
+ \Z!\Z!\Z!\Z!\Z!\W #2\Z!\Z!\Z!\Z!\Z!\W
+}%
+\def\XINT_add_checklengths #1.#2.%
+{%
+ \ifnum #2>#1
+ \expandafter\XINT_add_exchange
+ \else
+ \expandafter\XINT_add_A
+ \fi
+ #1.#2.%
}%
-\def\XINT_addp_ABEA #1#2#3#4#5#6#7%
+\def\XINT_add_exchange #1.#2.#3\Z!\Z!\Z!\Z!\Z!\W #4\Z
{%
- \XINT_addp_A #2{#7#6#5#4#3}%<-- attention on met donc \`a droite
+ \XINT_add_A #2.#1.#4\Z!\Z!\Z!\Z!\Z!\W #3\Z
}%
-\def\XINT_addp_C #1#2#3#4#5%
+\def\XINT_add_A #1.#2.%
{%
- \xint_gob_til_W
- #5\xint_addp_cw
- #4\xint_addp_cx
- #3\xint_addp_cy
- #2\xint_addp_cz
- \W\XINT_addp_CD {#5#4#3#2}{#1}%
+ \ifnum #1>\xint_c_vi %
+ \expandafter\XINT_add_aa
+ \else \expandafter\XINT_add_aa_small
+ \fi
}%
-\def\XINT_addp_CD #1%
+%%%%%%%%%%%%
+\def\XINT_add_out #1\Z #2\W%
{%
- \expandafter\XINT_addp_CC\the\numexpr 1+10#1\relax
+ \expandafter\XINT_cuz_small\romannumeral0\XINT_unrevbyviii {}%
+ #11\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
}%
-\def\XINT_addp_CC #1#2#3#4#5#6#7%
+\def\XINT_add_out_small #1\Z #2\W%
{%
- \XINT_addp_AC_checkcarry #2{#7#6#5#4#3}%
+ \XINT_smallunrevbyviii #11\Z!1\R!1\R!1\R!1\R!1\R!1\R!\W
}%
-\def\xint_addp_cw
- #1\xint_addp_cx
- #2\xint_addp_cy
- #3\xint_addp_cz
- \W\XINT_addp_CD
+%%%%%%%%%%%%
+\def\XINT_add_aa {\expandafter\XINT_add_out\the\numexpr\XINT_add_a \xint_c_ii}%
+\def\XINT_add_aa_small
+ {\expandafter\XINT_add_out_small\the\numexpr\XINT_add_a \xint_c_ii}%
+\def\XINT_add_a #1!#2!#3!#4!#5\W #6!#7!#8!#9!%
{%
- \expandafter\XINT_addp_CDw\the\numexpr \xint_c_i+10#1#2#3\relax
+ \XINT_add_b #1!#6!#2!#7!#3!#8!#4!#9!#5\W
}%
-\def\XINT_addp_CDw #1#2#3#4#5#6%
+\def\XINT_add_b #1#2!#3!%
{%
- \xint_gob_til_zeros_iv #2#3#4#5\XINT_addp_endDw_zeros
- 0000\XINT_addp_endDw #2#3#4#5%
+ \xint_gob_til_Z #2\XINT_add_bi \Z
+ \expandafter\XINT_add_c\the\numexpr#1+#2+#3-\xint_c_ii.%
}%
-\def\XINT_addp_endDw_zeros 0000\XINT_addp_endDw 0000#1\X\Y\Z{ #1}%
-\def\XINT_addp_endDw #1#2#3#4#5\X\Y\Z{ #5#4#3#2#1}%
-\def\xint_addp_cx
- #1\xint_addp_cy
- #2\xint_addp_cz
- \W\XINT_addp_CD
+\def\XINT_add_bi\Z
+ \expandafter\XINT_add_c
+ \the\numexpr#1+#2+#3-\xint_c_ii.#4!#5!#6!#7!#8!#9!\Z !\W
{%
- \expandafter\XINT_addp_CDx\the\numexpr \xint_c_i+100#1#2\relax
+ \XINT_add_k #1#3!#5!#7!#9!%
}%
-\def\XINT_addp_CDx #1#2#3#4#5#6%
+\def\XINT_add_c #1#2.%
{%
- \xint_gob_til_zeros_iv #2#3#4#5\XINT_addp_endDx_zeros
- 0000\XINT_addp_endDx #2#3#4#5%
+ 1#2\expandafter!\the\numexpr\XINT_add_d #1%
}%
-\def\XINT_addp_endDx_zeros 0000\XINT_addp_endDx 0000#1\Y\Z{ #1}%
-\def\XINT_addp_endDx #1#2#3#4#5\Y\Z{ #5#4#3#2#1}%
-\def\xint_addp_cy #1\xint_addp_cz\W\XINT_addp_CD
+\def\XINT_add_d #1#2!#3!%
{%
- \expandafter\XINT_addp_CDy\the\numexpr \xint_c_i+1000#1\relax
+ \xint_gob_til_Z #2\XINT_add_di \Z
+ \expandafter\XINT_add_e\the\numexpr#1+#2+#3-\xint_c_ii.%
}%
-\def\XINT_addp_CDy #1#2#3#4#5#6%
+\def\XINT_add_di\Z\expandafter\XINT_add_e
+ \the\numexpr#1+#2+#3-\xint_c_ii.#4!#5!#6!#7!#8\W
{%
- \xint_gob_til_zeros_iv #2#3#4#5\XINT_addp_endDy_zeros
- 0000\XINT_addp_endDy #2#3#4#5%
+ \XINT_add_k #1#3!#5!#7!%
}%
-\def\XINT_addp_endDy_zeros 0000\XINT_addp_endDy 0000#1\Z{ #1}%
-\def\XINT_addp_endDy #1#2#3#4#5\Z{ #5#4#3#2#1}%
-\def\xint_addp_cz\W\XINT_addp_CD #1#2{ #21000}%
-\def\XINT_addp_F #1#2#3#4#5%
+\def\XINT_add_e #1#2.%
{%
- \xint_gob_til_W
- #5\xint_addp_Gw
- #4\xint_addp_Gx
- #3\xint_addp_Gy
- #2\xint_addp_Gz
- \W\XINT_addp_G {#2#3#4#5}{#1}%
+ 1#2\expandafter!\the\numexpr\XINT_add_f #1%
}%
-\def\XINT_addp_G #1#2%
+\def\XINT_add_f #1#2!#3!%
{%
- \XINT_addp_F {#2#1}%
+ \xint_gob_til_Z #2\XINT_add_fi \Z
+ \expandafter\XINT_add_g\the\numexpr#1+#2+#3-\xint_c_ii.%
}%
-\def\xint_addp_Gw
- #1\xint_addp_Gx
- #2\xint_addp_Gy
- #3\xint_addp_Gz
- \W\XINT_addp_G #4%
+\def\XINT_add_fi\Z\expandafter\XINT_add_g
+ \the\numexpr#1+#2+#3-\xint_c_ii.#4!#5!#6\W
{%
- \xint_gob_til_zeros_iv #3#2#10\XINT_addp_endGw_zeros
- 0000\XINT_addp_endGw #3#2#10%
+ \XINT_add_k #1#3!#5!%
}%
-\def\XINT_addp_endGw_zeros 0000\XINT_addp_endGw 0000#1\X\Y\Z{ #1}%
-\def\XINT_addp_endGw #1#2#3#4#5\X\Y\Z{ #5#1#2#3#4}%
-\def\xint_addp_Gx
- #1\xint_addp_Gy
- #2\xint_addp_Gz
- \W\XINT_addp_G #3%
+\def\XINT_add_g #1#2.%
{%
- \xint_gob_til_zeros_iv #2#100\XINT_addp_endGx_zeros
- 0000\XINT_addp_endGx #2#100%
+ 1#2\expandafter!\the\numexpr\XINT_add_h #1%
}%
-\def\XINT_addp_endGx_zeros 0000\XINT_addp_endGx 0000#1\Y\Z{ #1}%
-\def\XINT_addp_endGx #1#2#3#4#5\Y\Z{ #5#1#2#3#4}%
-\def\xint_addp_Gy
- #1\xint_addp_Gz
- \W\XINT_addp_G #2%
+\def\XINT_add_h #1#2!#3!%
{%
- \xint_gob_til_zeros_iv #1000\XINT_addp_endGy_zeros
- 0000\XINT_addp_endGy #1000%
+ \xint_gob_til_Z #2\XINT_add_hi \Z
+ \expandafter\XINT_add_i\the\numexpr#1+#2+#3-\xint_c_ii.%
}%
-\def\XINT_addp_endGy_zeros 0000\XINT_addp_endGy 0000#1\Z{ #1}%
-\def\XINT_addp_endGy #1#2#3#4#5\Z{ #5#1#2#3#4}%
-\def\xint_addp_Gz\W\XINT_addp_G #1#2{ #2}%
-% \end{macrocode}
-% \subsection{\csh{xintiAdd}, \csh{xintiiAdd}}
-% \lverb|ADDITION
-% [algo plus efficace lorsque le premier argument plus long que le second]
-%
-% Note (octobre 2014, pendant la préparation de la sortie de 1.1)
-%
-% Je n'aurais pas dû l'appeler \xintAdd, mais seulement \xintiAdd. Le format
-% de sortie de \xintAdd est modifié par xintfrac.sty, celui de \xintiAdd ne
-% bouge pas, et \xintiiAdd reste la version stricte.|
-% \begin{macrocode}
-\def\xintiiAdd {\romannumeral0\xintiiadd }%
-\def\xintiiadd #1{\expandafter\xint_iiadd\romannumeral-`0#1\Z }%
-\def\xint_iiadd #1#2\Z #3%
+\def\XINT_add_hi\Z
+ \expandafter\XINT_add_i\the\numexpr#1+#2+#3-\xint_c_ii.#4\W
{%
- \expandafter\XINT_add_fork\expandafter #1\romannumeral-`0#3\Z #2\Z
+ \XINT_add_k #1#3!%
}%
-\def\xintiAdd {\romannumeral0\xintiadd }%
-\def\xintiadd #1%
+\def\XINT_add_i #1#2.%
{%
- \expandafter\xint_add\romannumeral0\xintnum{#1}\Z
+ 1#2\expandafter!\the\numexpr\XINT_add_a #1%
}%
-\def\xint_add #1#2\Z #3%
+%%%%%%%%%%%%
+\def\XINT_add_k #1%
+ {\if #12\expandafter\XINT_add_ke\else\expandafter\XINT_add_l \fi}%
+\def\XINT_add_ke #1%
{%
- \expandafter\XINT_add_fork\expandafter #1\romannumeral0\xintnum{#3}\Z #2\Z
+ \xint_gob_til_Z #1\XINT_add_kf\Z 1%
}%
-\let\xintAdd\xintiAdd \let\xintadd\xintiadd
-\def\XINT_add_fork #1#2%
+\def\XINT_add_kf\Z 1{1}%
+\def\XINT_add_l #1%
{%
- \xint_UDzerofork
- #1\XINT_add_firstiszero
- #2\XINT_add_secondiszero
- 0{}%
- \krof
- \xint_UDsignsfork
- #1#2\XINT_add_minusminus
- #1-\XINT_add_minusplus
- #2-\XINT_add_plusminus
- --\XINT_add_plusplus
- \krof #1#2%
+ \xint_gob_til_Z #1\XINT_add_lf\Z \XINT_add_m 1%
}%
-\def\XINT_add_firstiszero #1\krof #2#3\Z #4\Z { #3}%
-\def\XINT_add_secondiszero #1\krof #2#3\Z #4\Z { #2#4}%
-\def\XINT_add_plusplus #1#2#3\Z #4\Z {\XINT_add_pre {#1#4}{#2#3}}%
-\def\XINT_add_minusminus #1#2#3\Z #4\Z
- {\expandafter\xint_minus_thenstop\romannumeral0\XINT_add_pre {#4}{#3}}%
-\def\XINT_add_minusplus #1#2#3\Z #4\Z {\XINT_sub_pre {#2#3}{#4}}%
-\def\XINT_add_plusminus #1#2#3\Z #4\Z {\XINT_sub_pre {#1#4}{#3}}%
-% \end{macrocode}
-% \lverb|positive summands|
-% \begin{macrocode}
-\def\XINT_add_pre #1%
+\def\XINT_add_lf\Z\XINT_add_m 1{100000001}%
+\def\XINT_add_m #1!%
{%
- \expandafter\XINT_add_pre_b\expandafter
- {\romannumeral0\XINT_RQ {}#1\R\R\R\R\R\R\R\R\Z }%
+ \expandafter\XINT_add_n\the\numexpr\xint_c_i+#1.%
}%
-\def\XINT_add_pre_b #1#2%
+\def\XINT_add_n #1#2.%
{%
- \expandafter\XINT_add_A
- \expandafter0\expandafter{\expandafter}%
- \romannumeral0\XINT_RQ {}#2\R\R\R\R\R\R\R\R\Z
- \W\X\Y\Z #1\W\X\Y\Z
+ 1#2\expandafter!\the\numexpr\XINT_add_o #1%
}%
+\def\XINT_add_o #1%
+ {\if #12\expandafter\XINT_add_l\else\expandafter\XINT_add_ke \fi}%
% \end{macrocode}
% \subsection{\csh{xintiSub}, \csh{xintiiSub}}
-% \lverb|Release 1.09a has \xintnum added into \xintiSub.|
+% \lverb|Entirely rewritten for v1.2.|
% \begin{macrocode}
\def\xintiiSub {\romannumeral0\xintiisub }%
-\def\xintiisub #1{\expandafter\xint_iisub\romannumeral-`0#1\Z }%
-\def\xint_iisub #1#2\Z #3%
+\def\xintiisub #1{\expandafter\XINT_iisub\romannumeral-`0#1\Z }%
+\def\XINT_iisub #1#2\Z #3%
{%
- \expandafter\XINT_sub_fork\expandafter #1\romannumeral-`0#3\Z #2\Z
+ \expandafter\XINT_sub_nfork\expandafter #1\romannumeral-`0#3\Z #2\Z
}%
-\def\xintiSub {\romannumeral0\xintisub }%
-\def\xintisub #1%
+\def\xintiSub {\romannumeral0\xintisub }%
+\def\xintisub #1{\expandafter\XINT_isub\romannumeral0\xintnum{#1}\Z }%
+\def\XINT_isub #1#2\Z #3%
{%
- \expandafter\xint_sub\romannumeral0\xintnum{#1}\Z
+ \expandafter\XINT_sub_nfork\expandafter #1\romannumeral0\xintnum{#3}\Z #2\Z
}%
-\def\xint_sub #1#2\Z #3%
-{%
- \expandafter\XINT_sub_fork\expandafter #1\romannumeral0\xintnum{#3}\Z #2\Z
-}%
-\let\xintSub\xintiSub \let\xintsub\xintisub
-\def\XINT_sub_fork #1#2%
+\def\XINT_sub_nfork #1#2%
{%
\xint_UDzerofork
#1\XINT_sub_firstiszero
@@ -16315,756 +16383,437 @@ $1$ or $-1$.
--\XINT_sub_plusplus
\krof #1#2%
}%
-\def\XINT_sub_firstiszero #1\krof #2#3\Z #4\Z {\XINT_opp #3}%
-\def\XINT_sub_secondiszero #1\krof #2#3\Z #4\Z { #2#4}%
-\def\XINT_sub_plusplus #1#2#3\Z #4\Z {\XINT_sub_pre {#1#4}{#2#3}}%
-\def\XINT_sub_minusminus #1#2#3\Z #4\Z {\XINT_sub_pre {#3}{#4}}%
-\def\XINT_sub_minusplus #1#2#3\Z #4\Z
- {\expandafter\xint_minus_thenstop\romannumeral0\XINT_add_pre {#4}{#2#3}}%
-\def\XINT_sub_plusminus #1#2#3\Z #4\Z {\XINT_add_pre {#1#4}{#3}}%
-% \end{macrocode}
-% \lverb|SOUSTRACTION A-B avec A premier argument, B second argument de
-% \xintSub et ensuite \XINT_sub_pre ici|
-% \begin{macrocode}
-\def\XINT_sub_pre #1%
-{%
- \expandafter\XINT_sub_pre_b\expandafter
- {\romannumeral0\XINT_RQ {}#1\R\R\R\R\R\R\R\R\Z }%
-}%
-\def\XINT_sub_pre_b #1#2%
-{%
- \expandafter\XINT_sub_A
- \expandafter1\expandafter{\expandafter}%
- \romannumeral0\XINT_RQ {}#2\R\R\R\R\R\R\R\R\Z
- \W\X\Y\Z #1 \W\X\Y\Z
-}%
-% \end{macrocode}
-% \lverb|&
-% \romannumeral0\XINT_sub_A 1{}<N1>\W\X\Y\Z<N2>\W\X\Y\Z$\
-% N1 et N2 sont présentés à l'envers ET ON A RAJOUTÉ DES ZÉROS
-% POUR QUE LEURS LONGUEURS À CHACUN SOIENT MULTIPLES DE 4, MAIS
-% AUCUN NE SE TERMINE EN 0000.$\ output: N2 - N1$\
-% Elle donne le résultat dans le **bon ordre**, avec le bon signe,
-% et sans zéros superflus.|
-% \begin{macrocode}
-\def\XINT_sub_A #1#2#3\W\X\Y\Z #4#5#6#7%
-{%
- \xint_gob_til_W
- #4\xint_sub_az
- \W\XINT_sub_B #1{#4#5#6#7}{#2}#3\W\X\Y\Z
-}%
-\def\XINT_sub_B #1#2#3#4#5#6#7%
+\def\XINT_sub_firstiszero #1\krof 0#2#3\Z #4\Z {\XINT_opp #2#3}%
+\def\XINT_sub_secondiszero #1\krof #20#3\Z #4\Z { #2#4}%
+\def\XINT_sub_plusminus #1#2{\XINT_add_pp_a #1{}}%
+\def\XINT_sub_plusplus #1#2%
+ {\expandafter\XINT_opp\romannumeral0\XINT_sub_mm_a #1#2}%
+\def\XINT_sub_minusplus #1#2%
+ {\expandafter\xint_minus_thenstop\romannumeral0\XINT_add_pp_a {}#2}%
+\def\XINT_sub_minusminus #1#2{\XINT_sub_mm_a {}{}}%
+\def\XINT_sub_mm_a #1#2#3\Z
+{%
+ \expandafter\XINT_sub_mm_b
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #2#3\R\R\R\R\R\R\R\R{10}0000001\W
+ #2#3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_iii
+ \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii
+ \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W
+ \X #1%
+}%
+\def\XINT_sub_mm_b #1.#2\X #3\Z
+{%
+ \expandafter\XINT_sub_checklengths
+ \the\numexpr #1\expandafter.%
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #3\R\R\R\R\R\R\R\R{10}0000001\W
+ #3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax \xint_c_ii\xint_c_iii
+ \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii
+ \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W
+ \Z!\Z!\Z!\Z!\Z!\W #2\Z!\Z!\Z!\Z!\Z!\W
+}%
+\def\XINT_sub_checklengths #1.#2.%
{%
- \xint_gob_til_W
- #4\xint_sub_bz
- \W\XINT_sub_onestep #1#2{#7#6#5#4}{#3}%
-}%
-% \end{macrocode}
-% \lverb|&
-% d'abord la branche principale
-% #6 = 4 chiffres de N1, plus significatif en *premier*,
-% #2#3#4#5 chiffres de N2, plus significatif en *dernier*
-% On veut N2 - N1.|
-% \begin{macrocode}
-\def\XINT_sub_onestep #1#2#3#4#5#6%
-{%
- \expandafter\XINT_sub_backtoA\the\numexpr 11#5#4#3#2-#6+#1-\xint_c_i.%
+ \ifnum #2>#1
+ \expandafter\XINT_sub_exchange
+ \else
+ \expandafter\XINT_sub_aa
+ \fi
}%
-% \end{macrocode}
-% \lverb|ON PRODUIT LE RÉSULTAT DANS LE BON ORDRE|
-% \begin{macrocode}
-\def\XINT_sub_backtoA #1#2#3.#4%
+\def\XINT_sub_exchange #1\Z!\Z!\Z!\Z!\Z!\W #2\Z
{%
- \XINT_sub_A #2{#3#4}%
+ \expandafter\XINT_opp\romannumeral0\XINT_sub_aa
+ #2\Z!\Z!\Z!\Z!\Z!\W #1\Z
}%
-\def\xint_sub_bz
- \W\XINT_sub_onestep #1#2#3#4#5#6#7%
+%%%%%%%%%%%%
+\def\XINT_sub_prepare_rescue #1\W {\relax\Z-\W}%
+\def\XINT_sub_prepare_cuz #1\W {\relax\XINT_cuz_byviii!\Z 0\W\R}%
+%%%%%%%%%%%%
+\def\XINT_sub_aa {\expandafter\XINT_sub_out\the\numexpr\XINT_sub_a \xint_c_i }%
+\def\XINT_sub_out #1\Z #2#3\W
{%
- \xint_UDzerofork
- #1\XINT_sub_C % une retenue
- 0\XINT_sub_D % pas de retenue
- \krof
- {#7}#2#3#4#5%
+ \if-#2\expandafter\XINT_sub_startrescue\fi
+ \expandafter\XINT_cuz_small
+ \romannumeral0\XINT_unrevbyviii {}#11\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
}%
-\def\XINT_sub_D #1#2\W\X\Y\Z
+\def\XINT_sub_startrescue\expandafter\XINT_cuz_small
+ \romannumeral0\XINT_unrevbyviii #1#2\Z!#3\W
{%
- \expandafter
- \xint_cleanupzeros_andstop
- \romannumeral0%
- \XINT_rord_main {}#2%
- \xint_relax
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_relax
- #1%
+ \expandafter\XINT_sub_rescue_finish
+ \the\numexpr\XINT_sub_rescue_a #2!%
+ 1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W \R
}%
-\def\XINT_sub_C #1#2#3#4#5%
+\def\XINT_sub_rescue_finish
+ {\expandafter-\romannumeral0\expandafter\XINT_cuz
+ \romannumeral0\XINT_unrevbyviii {}}%
+\def\XINT_sub_rescue_a #1!%
{%
- \xint_gob_til_W
- #2\xint_sub_cz
- \W\XINT_sub_AC_onestep {#5#4#3#2}{#1}%
+ \expandafter\XINT_sub_rescue_c\the\numexpr \xint_c_xii_e_viii-#1.%
}%
-\def\XINT_sub_AC_onestep #1%
+\def\XINT_sub_rescue_c 1#1#2.%
{%
- \expandafter\XINT_sub_backtoC\the\numexpr 11#1-\xint_c_i.%
+ 1#2\expandafter!\the\numexpr\XINT_sub_rescue_d #1%
}%
-\def\XINT_sub_backtoC #1#2#3.#4%
+\def\XINT_sub_rescue_d #1#2#3!%
{%
- \XINT_sub_AC_checkcarry #2{#3#4}% la retenue va \^etre examin\'ee
+ \xint_gob_til_minus #2\XINT_sub_rescue_z -%
+ \expandafter\XINT_sub_rescue_c\the\numexpr \xint_c_xii_e_viii_mone-#2#3+#1.%
}%
-\def\XINT_sub_AC_checkcarry #1%
+\def\XINT_sub_rescue_z #1.{1!}%
+%%%%%%%%%%%%
+\def\XINT_sub_a #1!#2!#3!#4!#5\W #6!#7!#8!#9!%
{%
- \xint_gob_til_one #1\xint_sub_AC_nocarry 1\XINT_sub_C
+ \XINT_sub_b #1!#6!#2!#7!#3!#8!#4!#9!#5\W
}%
-\def\xint_sub_AC_nocarry 1\XINT_sub_C #1#2\W\X\Y\Z
+\def\XINT_sub_b #1#2#3!#4!%
{%
- \expandafter
- \XINT_cuz_loop
- \romannumeral0%
- \XINT_rord_main {}#2%
- \xint_relax
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_relax
- #1\W\W\W\W\W\W\W\Z
+ \xint_gob_til_Z #2\XINT_sub_bi \Z
+ \expandafter\XINT_sub_c\the\numexpr#1+1#4-#3-\xint_c_i.%
}%
-\def\xint_sub_cz\W\XINT_sub_AC_onestep #1%
+\def\XINT_sub_c 1#1#2.%
{%
- \XINT_cuz
+ 1#2\expandafter!\the\numexpr\XINT_sub_d #1%
}%
-\def\xint_sub_az\W\XINT_sub_B #1#2#3#4#5#6#7%
+\def\XINT_sub_d #1#2#3!#4!%
{%
- \xint_gob_til_W
- #4\xint_sub_ez
- \W\XINT_sub_Eenter #1{#3}#4#5#6#7%
+ \xint_gob_til_Z #2\XINT_sub_di \Z
+ \expandafter\XINT_sub_e\the\numexpr#1+1#4-#3-\xint_c_i.%
}%
-% \end{macrocode}
-% \lverb|le premier nombre continue, le résultat sera < 0.|
-% \begin{macrocode}
-\def\XINT_sub_Eenter #1#2%
+\def\XINT_sub_e 1#1#2.%
{%
- \expandafter
- \XINT_sub_E\expandafter1\expandafter{\expandafter}%
- \romannumeral0%
- \XINT_rord_main {}#2%
- \xint_relax
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_relax
- \W\X\Y\Z #1%
+ 1#2\expandafter!\the\numexpr\XINT_sub_f #1%
}%
-\def\XINT_sub_E #1#2#3#4#5#6%
+\def\XINT_sub_f #1#2#3!#4!%
{%
- \xint_gob_til_W #3\xint_sub_F\W
- \XINT_sub_Eonestep #1{#6#5#4#3}{#2}%
+ \xint_gob_til_Z #2\XINT_sub_fi \Z
+ \expandafter\XINT_sub_g\the\numexpr#1+1#4-#3-\xint_c_i.%
}%
-\def\XINT_sub_Eonestep #1#2%
+\def\XINT_sub_g 1#1#2.%
{%
- \expandafter\XINT_sub_backtoE\the\numexpr 109999-#2+#1.%
+ 1#2\expandafter!\the\numexpr\XINT_sub_h #1%
}%
-\def\XINT_sub_backtoE #1#2#3.#4%
+\def\XINT_sub_h #1#2#3!#4!%
{%
- \XINT_sub_E #2{#3#4}%
+ \xint_gob_til_Z #2\XINT_sub_hi \Z
+ \expandafter\XINT_sub_i\the\numexpr#1+1#4-#3-\xint_c_i.%
}%
-\def\xint_sub_F\W\XINT_sub_Eonestep #1#2#3#4%
+\def\XINT_sub_i 1#1#2.%
{%
- \xint_UDonezerofork
- #4#1{\XINT_sub_Fdec 0}% soustraire 1. Et faire signe -
- #1#4{\XINT_sub_Finc 1}% additionner 1. Et faire signe -
- 10\XINT_sub_DD % terminer. Mais avec signe -
- \krof
- {#3}%
+ 1#2\expandafter!\the\numexpr\XINT_sub_a #1%
}%
-\def\XINT_sub_DD {\expandafter\xint_minus_thenstop\romannumeral0\XINT_sub_D }%
-\def\XINT_sub_Fdec #1#2#3#4#5#6%
+\def\XINT_sub_bi\Z
+ \expandafter\XINT_sub_c\the\numexpr#1+1#2-#3.#4!#5!#6!#7!#8!#9!\Z !\W
{%
- \xint_gob_til_W #3\xint_sub_Fdec_finish\W
- \XINT_sub_Fdec_onestep #1{#6#5#4#3}{#2}%
+ \XINT_sub_k #1#2!#5!#7!#9!%
}%
-\def\XINT_sub_Fdec_onestep #1#2%
+\def\XINT_sub_di\Z
+ \expandafter\XINT_sub_e\the\numexpr#1+1#2-#3.#4!#5!#6!#7!#8\W
{%
- \expandafter\XINT_sub_backtoFdec\the\numexpr 11#2+#1-\xint_c_i.%
+ \XINT_sub_k #1#2!#5!#7!%
}%
-\def\XINT_sub_backtoFdec #1#2#3.#4%
+\def\XINT_sub_fi\Z
+ \expandafter\XINT_sub_g\the\numexpr#1+1#2-#3.#4!#5!#6\W
{%
- \XINT_sub_Fdec #2{#3#4}%
+ \XINT_sub_k #1#2!#5!%
}%
-\def\xint_sub_Fdec_finish\W\XINT_sub_Fdec_onestep #1#2%
+\def\XINT_sub_hi\Z
+ \expandafter\XINT_sub_i\the\numexpr#1+1#2-#3.#4\W
{%
- \expandafter\xint_minus_thenstop\romannumeral0\XINT_cuz
+ \XINT_sub_k #1#2!%
}%
-\def\XINT_sub_Finc #1#2#3#4#5#6%
+%%%%%%%%%%%%
+\def\XINT_sub_k #1#2%
{%
- \xint_gob_til_W #3\xint_sub_Finc_finish\W
- \XINT_sub_Finc_onestep #1{#6#5#4#3}{#2}%
+ \xint_gob_til_Z #2\XINT_sub_p\Z \XINT_sub_l #1#2%
}%
-\def\XINT_sub_Finc_onestep #1#2%
+\def\XINT_sub_l #1%
{%
- \expandafter\XINT_sub_backtoFinc\the\numexpr 10#2+#1.%
+ \xint_UDzerofork
+ #1\XINT_sub_m
+ 0{}%
+ \krof
}%
-\def\XINT_sub_backtoFinc #1#2#3.#4%
+\def\XINT_sub_m #1!%
{%
- \XINT_sub_Finc #2{#3#4}%
+ \expandafter\XINT_sub_n\the\numexpr 1#1-\xint_c_i!%
}%
-\def\xint_sub_Finc_finish\W\XINT_sub_Finc_onestep #1#2#3%
+\def\XINT_sub_n 1#1%
{%
\xint_UDzerofork
- #1{\expandafter\expandafter\expandafter
- \xint_minus_thenstop\xint_cleanupzeros_nostop}%
- 0{ -1}%
+ #1{\XINT_sub_o}%
+ 0{\XINT_sub_n_checkzero}%
\krof
- #3%
}%
-\def\xint_sub_ez\W\XINT_sub_Eenter #1%
+\def\XINT_sub_o #1!{1#1\expandafter!\the\numexpr\XINT_sub_m }%
+\def\XINT_sub_n_checkzero #1!%
{%
- \xint_UDzerofork
- #1\XINT_sub_K % il y a une retenue
- 0\XINT_sub_L % pas de retenue
- \krof
+ \xint_gob_til_eightzeroes #1\XINT_sub_n_prepare_cuz 00000000%
+ 1#1!%
}%
-\def\XINT_sub_L #1\W\X\Y\Z {\XINT_cuz_loop #1\W\W\W\W\W\W\W\Z }%
-\def\XINT_sub_K #1%
+\def\XINT_sub_n_prepare_cuz 00000000100000000{1\XINT_sub_prepare_cuz}%
+\def\XINT_sub_p\Z\XINT_sub_l #1\Z!%
{%
- \expandafter
- \XINT_sub_KK\expandafter1\expandafter{\expandafter}%
- \romannumeral0%
- \XINT_rord_main {}#1%
- \xint_relax
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_relax
-}%
-\def\XINT_sub_KK #1#2#3#4#5#6%
-{%
- \xint_gob_til_W #3\xint_sub_KK_finish\W
- \XINT_sub_KK_onestep #1{#6#5#4#3}{#2}%
-}%
-\def\XINT_sub_KK_onestep #1#2%
-{%
- \expandafter\XINT_sub_backtoKK\the\numexpr 109999-#2+#1.%
-}%
-\def\XINT_sub_backtoKK #1#2#3.#4%
-{%
- \XINT_sub_KK #2{#3#4}%
-}%
-\def\xint_sub_KK_finish\W\XINT_sub_KK_onestep #1#2#3%
-{%
- \expandafter\xint_minus_thenstop
- \romannumeral0\XINT_cuz_loop #3\W\W\W\W\W\W\W\Z
+ \xint_UDzerofork
+ #1{-1\XINT_sub_prepare_rescue}%
+ 0{1\XINT_sub_prepare_cuz }%
+ \krof
}%
% \end{macrocode}
% \subsection{\csh{xintiMul}, \csh{xintiiMul}}
-% \lverb|1.09a adds \xintnum|
+% \lverb|Completely rewritten for v1.2.|
% \begin{macrocode}
-\def\xintiiMul {\romannumeral0\xintiimul }%
-\def\xintiimul #1%
+\def\xintiMul {\romannumeral0\xintimul }%
+\def\xintimul #1%
{%
- \expandafter\xint_iimul\expandafter {\romannumeral-`0#1}%
+ \expandafter\XINT_imul\romannumeral0\xintnum{#1}\Z
}%
-\def\xint_iimul #1#2%
+\def\XINT_imul #1#2\Z #3%
{%
- \expandafter\XINT_mul_fork \romannumeral-`0#2\Z #1\Z
+ \expandafter\XINT_mul_nfork\expandafter #1\romannumeral0\xintnum{#3}\Z #2\Z
}%
-\def\xintiMul {\romannumeral0\xintimul }%
-\def\xintimul #1%
+\def\xintiiMul {\romannumeral0\xintiimul }%
+\def\xintiimul #1%
{%
- \expandafter\xint_mul\expandafter {\romannumeral0\xintnum{#1}}%
+ \expandafter\XINT_iimul\romannumeral-`0#1\Z
}%
-\def\xint_mul #1#2%
+\def\XINT_iimul #1#2\Z #3%
{%
- \expandafter\XINT_mul_fork \romannumeral0\xintnum{#2}\Z #1\Z
+ \expandafter\XINT_mul_nfork\expandafter #1\romannumeral-`0#3\Z #2\Z
}%
-\let\xintMul\xintiMul \let\xintmul\xintimul
-\def\XINT_Mul #1#2{\romannumeral0\XINT_mul_fork #2\Z #1\Z }%
% \end{macrocode}
-% \lverb|&
-% MULTIPLICATION$\
-% Ici #1#2 = 2e input et #3#4 = 1er input $\
-% Release 1.03 adds some overhead to first compute and compare the
-% lengths of the two inputs. The algorithm is asymmetrical and whether
-% the first input is the longest or the shortest sometimes has a strong
-% impact. 50 digits times 1000 digits used to be 5 times faster
-% than 1000 digits times 50 digits. With the new code, the user input
-% order does not matter as it is decided by the routine what is best.
-% This is important for the extension to fractions, as there is no way
-% then to generally control or guess the most frequent sizes of the
-% inputs besides actually computing their lengths. |
-% \begin{macrocode}
-\def\XINT_mul_fork #1#2\Z #3#4\Z
+% \lverb|I have changed the fork, and it complicates matters elsewhere.|
+% \begin{macrocode}
+\def\XINT_mul_fork #1#2\Z #3\Z{\XINT_mul_nfork #1#3\Z #2\Z}%
+\def\XINT_mul_nfork #1#2%
{%
\xint_UDzerofork
#1\XINT_mul_zero
- #3\XINT_mul_zero
+ #2\XINT_mul_zero
0{}%
\krof
\xint_UDsignsfork
- #1#3\XINT_mul_minusminus % #1 = #3 = -
- #1-{\XINT_mul_minusplus #3}% % #1 = -
- #3-{\XINT_mul_plusminus #1}% % #3 = -
- --{\XINT_mul_plusplus #1#3}%
- \krof
- {#2}{#4}%
-}%
-\def\XINT_mul_zero #1\krof #2#3{ 0}%
-\def\XINT_mul_minusminus #1#2%
-{%
- \expandafter\XINT_mul_choice_a
- \expandafter{\romannumeral0\xintlength {#2}}%
- {\romannumeral0\xintlength {#1}}{#1}{#2}%
-}%
-\def\XINT_mul_minusplus #1#2#3%
-{%
- \expandafter\xint_minus_thenstop\romannumeral0\expandafter
- \XINT_mul_choice_a
- \expandafter{\romannumeral0\xintlength {#1#3}}%
- {\romannumeral0\xintlength {#2}}{#2}{#1#3}%
-}%
-\def\XINT_mul_plusminus #1#2#3%
-{%
- \expandafter\xint_minus_thenstop\romannumeral0\expandafter
- \XINT_mul_choice_a
- \expandafter{\romannumeral0\xintlength {#3}}%
- {\romannumeral0\xintlength {#1#2}}{#1#2}{#3}%
-}%
-\def\XINT_mul_plusplus #1#2#3#4%
-{%
- \expandafter\XINT_mul_choice_a
- \expandafter{\romannumeral0\xintlength {#2#4}}%
- {\romannumeral0\xintlength {#1#3}}{#1#3}{#2#4}%
-}%
-\def\XINT_mul_choice_a #1#2%
-{%
- \expandafter\XINT_mul_choice_b\expandafter{#2}{#1}%
-}%
-\def\XINT_mul_choice_b #1#2%
-{%
- \ifnum #1<\xint_c_v
- \expandafter\XINT_mul_choice_littlebyfirst
- \else
- \ifnum #2<\xint_c_v
- \expandafter\expandafter\expandafter\XINT_mul_choice_littlebysecond
- \else
- \expandafter\expandafter\expandafter\XINT_mul_choice_compare
- \fi
- \fi
- {#1}{#2}%
-}%
-\def\XINT_mul_choice_littlebyfirst #1#2#3#4%
-{%
- \expandafter\XINT_mul_M
- \expandafter{\the\numexpr #3\expandafter}%
- \romannumeral0\XINT_RQ {}#4\R\R\R\R\R\R\R\R\Z \Z\Z\Z\Z
-}%
-\def\XINT_mul_choice_littlebysecond #1#2#3#4%
-{%
- \expandafter\XINT_mul_M
- \expandafter{\the\numexpr #4\expandafter}%
- \romannumeral0\XINT_RQ {}#3\R\R\R\R\R\R\R\R\Z \Z\Z\Z\Z
+ #1#2\XINT_mul_minusminus
+ #1-\XINT_mul_minusplus
+ #2-\XINT_mul_plusminus
+ --\XINT_mul_plusplus
+ \krof #1#2%
}%
-\def\XINT_mul_choice_compare #1#2%
-{%
- \ifnum #1>#2
- \expandafter \XINT_mul_choice_i
+\def\XINT_mul_zero #1\krof #2#3\Z #4\Z { 0}%
+\def\XINT_mul_minusminus #1#2{\XINT_mul_plusplus {}{}}%
+\def\XINT_mul_minusplus #1#2%
+ {\expandafter\xint_minus_thenstop\romannumeral0\XINT_mul_plusplus {}#2}%
+\def\XINT_mul_plusminus #1#2%
+ {\expandafter\xint_minus_thenstop\romannumeral0\XINT_mul_plusplus #1{}}%
+\def\XINT_mul_plusplus #1#2#3\Z
+{%
+ \expandafter\XINT_mul_pre_b
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #2#3\R\R\R\R\R\R\R\R{10}0000001\W
+ #2#3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_iii
+ \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii
+ \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W
+ \W #1%
+}%
+\def\XINT_mul_pre_b #1.#2\W #3\Z
+{%
+ \expandafter\XINT_mul_checklengths
+ \the\numexpr #1\expandafter.%
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #3\R\R\R\R\R\R\R\R{10}0000001\W
+ #3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_iii
+ \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii
+ \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W
+ 1\Z!\W #21\Z!%
+ 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+}%
+% \end{macrocode}
+% \lverb|Cooking recipee, 2015/10/05.|
+% \begin{macrocode}
+\def\XINT_mul_checklengths #1.#2.%
+{%
+ \ifnum #2=\xint_c_i\expandafter\XINT_mul_smallbyfirst\fi
+ \ifnum #1=\xint_c_i\expandafter\XINT_mul_smallbysecond\fi
+ \ifnum #2<#1
+ \ifnum \numexpr (#2-\xint_c_i)*(#1-#2)<383
+ \XINT_mul_exchange
+ \fi
\else
- \expandafter \XINT_mul_choice_ii
+ \ifnum \numexpr (#1-\xint_c_i)*(#2-#1)>383
+ \XINT_mul_exchange
+ \fi
\fi
- {#1}{#2}%
-}%
-\def\XINT_mul_choice_i #1#2%
-{%
- \ifnum #1<\numexpr\ifcase \numexpr (#2-\xint_c_iii)/\xint_c_iv\relax
- \or 330\or 168\or 109\or 80\or 66\or 52\else 0\fi\relax
- \expandafter\XINT_mul_choice_same
- \else
- \expandafter\XINT_mul_choice_permute
- \fi
-}%
-\def\XINT_mul_choice_ii #1#2%
-{%
- \ifnum #2<\numexpr\ifcase \numexpr (#1-\xint_c_iii)/\xint_c_iv\relax
- \or 330\or 168\or 109\or 80\or 66\or 52\else 0\fi\relax
- \expandafter\XINT_mul_choice_permute
- \else
- \expandafter\XINT_mul_choice_same
- \fi
-}%
-\def\XINT_mul_choice_same #1#2%
-{%
- \expandafter\XINT_mul_enter
- \romannumeral0\XINT_RQ {}#1\R\R\R\R\R\R\R\R\Z
- \Z\Z\Z\Z #2\W\W\W\W
-}%
-\def\XINT_mul_choice_permute #1#2%
-{%
- \expandafter\XINT_mul_enter
- \romannumeral0\XINT_RQ {}#2\R\R\R\R\R\R\R\R\Z
- \Z\Z\Z\Z #1\W\W\W\W
-}%
-% \end{macrocode}
-% \lverb|&
-% Cette portion de routine d'addition se branche directement sur _addr_
-% lorsque
-% le premier nombre est épuisé, ce qui est garanti arriver avant le second
-% nombre. Elle produit son résultat toujours sur 4n, renversé. Ses deux inputs
-% sont garantis sur 4n.|
-% \begin{macrocode}
-\def\XINT_mul_Ar #1#2#3#4#5#6%
-{%
- \xint_gob_til_Z #6\xint_mul_br\Z\XINT_mul_Br #1{#6#5#4#3}{#2}%
-}%
-\def\xint_mul_br\Z\XINT_mul_Br #1#2%
-{%
- \XINT_addr_AC_checkcarry #1%
-}%
-\def\XINT_mul_Br #1#2#3#4\W\X\Y\Z #5#6#7#8%
-{%
- \expandafter\XINT_mul_ABEAr
- \the\numexpr #1+10#2+#8#7#6#5.{#3}#4\W\X\Y\Z
-}%
-\def\XINT_mul_ABEAr #1#2#3#4#5#6.#7%
-{%
- \XINT_mul_Ar #2{#7#6#5#4#3}%
-}%
-% \end{macrocode}
-% \subsubsection{``Small'' multiplication: \csh{XINT_mul_Mr}}
-% \lverb|&
-% << Petite >> multiplication.
-% mul_Mr renvoie le résultat *à l'envers*, sur *4n*$\
-% \romannumeral0\XINT_mul_Mr {<n>}<N>\Z\Z\Z\Z$\
-% Fait la multiplication de <N> par <n>, qui est < 10000.
-% <N> est présenté *à l'envers*, sur *4n*. Lorsque <n> vaut 0, donne 0000.|
+ \XINT_mul_start
+}%
+\def\XINT_mul_smallbyfirst #1\XINT_mul_start 1#2!1\Z!\W
+{%
+ \ifnum#2=\xint_c_i\expandafter\XINT_mul_oneisone\fi
+ \ifnum#2<\xint_c_xxii\expandafter\XINT_mul_verysmall\fi
+ \expandafter\XINT_mul_out\the\numexpr\XINT_smallmul 1#2!%
+}%
+\def\XINT_mul_smallbysecond #1\XINT_mul_start #2\W 1#3!1\Z!%
+{%
+ \ifnum#3=\xint_c_i\expandafter\XINT_mul_oneisone\fi
+ \ifnum#3<\xint_c_xxii\expandafter\XINT_mul_verysmall\fi
+ \expandafter\XINT_mul_out\the\numexpr\XINT_smallmul 1#3!#2%
+}%
+\def\XINT_mul_oneisone #1!{\XINT_mul_out }%
+\def\XINT_mul_verysmall\expandafter\XINT_mul_out
+ \the\numexpr\XINT_smallmul 1#1!%
+ {\expandafter\XINT_mul_out\the\numexpr\XINT_verysmallmul 0.#1!}%
+\def\XINT_mul_exchange #1\XINT_mul_start #2\W #31\Z!%
+ {\fi\fi\XINT_mul_start #31\Z!\W #2}%
+\def\XINT_mul_start
+ {\expandafter\XINT_mul_out\the\numexpr\XINT_mul_loop 100000000!\Z\W}%
+\def\XINT_mul_out
+ {\expandafter\XINT_cuz_small\romannumeral0\XINT_unrevbyviii {}}%
+\def\XINT_mul_loop #1\Z #2\W #3\W 1#4!%
+{%
+ \xint_gob_til_Z #4\XINT_mul_e \Z
+ \expandafter\XINT_mul_a\the\numexpr \XINT_smallmul 1#4!#3\W
+ #11!\W #3\W
+}%
+\def\XINT_mul_a #11\Z!\W #2!1!#3\W
+{%
+ \expandafter\XINT_mul_b\the\numexpr
+ \XINT_add_a \xint_c_ii #2!\Z!\Z!\Z!\Z!\Z!\W #1\Z!\Z!\Z!\Z!\Z!\W
+}%
+\def\XINT_mul_b 1#1!{1#1\expandafter!\the\numexpr\XINT_mul_loop }%
+\def\XINT_mul_e\Z #1\W #2!1!#3\W #4\W {#2!1\Z!}%
+% \end{macrocode}
+% \lverb|1.2 small and mini multiplication in base 10^8 with carry. On output
+% the small multiplication suppresses ending zeroes. The situation is
+% different with addition which may end up inserting a final 1!, thus
+% multiplication is « cleaner » in that aspect. Used by the main
+% multiplication routines. But division, float factorial, etc.. have their
+% own variants as they need output with specific constraints.
+% |
% \begin{macrocode}
-\def\XINT_mul_Mr #1%
+\def\XINT_minimulwc_a 1#1.#2.#3!#4#5#6#7#8.%
{%
- \expandafter\XINT_mul_Mr_checkifzeroorone\expandafter{\the\numexpr #1}%
+ \expandafter\XINT_minimulwc_b
+ \the\numexpr \xint_c_x^ix+#1+#3*#8.#3*#4#5#6#7+#2*#8.#2*#4#5#6#7.%
}%
-\def\XINT_mul_Mr_checkifzeroorone #1%
+\def\XINT_minimulwc_b 1#1#2#3#4#5#6.#7.%
{%
- \ifcase #1
- \expandafter\XINT_mul_Mr_zero
- \or
- \expandafter\XINT_mul_Mr_one
- \else
- \expandafter\XINT_mul_Nr
- \fi
- {0000}{}{#1}%
+ \expandafter\XINT_minimulwc_c
+ \the\numexpr \xint_c_x^ix+#1#2#3#4#5+#7.#6.%
}%
-\def\XINT_mul_Mr_zero #1\Z\Z\Z\Z { 0000}%
-\def\XINT_mul_Mr_one #1#2#3#4\Z\Z\Z\Z { #4}%
-\def\XINT_mul_Nr #1#2#3#4#5#6#7%
+\def\XINT_minimulwc_c 1#1#2#3#4#5#6.#7.#8.%
{%
- \xint_gob_til_Z #4\xint_mul_pr\Z\XINT_mul_Pr {#1}{#3}{#7#6#5#4}{#2}{#3}%
+ 1#6#7\expandafter!%
+ \the\numexpr\expandafter\XINT_smallmul_a
+ \the\numexpr \xint_c_x^viii+#1#2#3#4#5+#8.%
}%
-\def\XINT_mul_Pr #1#2#3%
+\def\XINT_smallmul 1#1#2#3#4#5!{\XINT_smallmul_a 100000000.#1#2#3#4.#5!}%
+\def\XINT_smallmul_a #1.#2.#3!1#4!%
{%
- \expandafter\XINT_mul_Lr\the\numexpr \xint_c_x^viii+#1+#2*#3\relax
+ \xint_gob_til_Z #4\XINT_smallmul_e\Z
+ \XINT_minimulwc_a #1.#2.#3!#4.#2.#3!%
}%
-\def\XINT_mul_Lr 1#1#2#3#4#5#6#7#8#9%
-{%
- \XINT_mul_Nr {#1#2#3#4}{#9#8#7#6#5}%
-}%
-\def\xint_mul_pr\Z\XINT_mul_Pr #1#2#3#4#5%
-{%
- \xint_gob_til_zeros_iv #1\XINT_mul_Mr_end_nocarry 0000%
- \XINT_mul_Mr_end_carry #1{#4}%
-}%
-\def\XINT_mul_Mr_end_nocarry 0000\XINT_mul_Mr_end_carry 0000#1{ #1}%
-\def\XINT_mul_Mr_end_carry #1#2#3#4#5{ #5#4#3#2#1}%
+\def\XINT_smallmul_e\Z\XINT_minimulwc_a 1#1.#2\Z #3!%
+ {\xint_gob_til_eightzeroes #1\XINT_smallmul_f 000000001\relax #1!1\Z!}%
+\def\XINT_smallmul_f 000000001\relax 00000000!1{1\relax}%
% \end{macrocode}
-% \subsubsection{``Small'' multiplication variant: \csh{XINT_mul_M}}
-% \lverb|&
-% << Petite >> multiplication.
-% renvoie le résultat *à l'endroit*, avec *nettoyage des leading zéros*.$\
-% \romannumeral0\XINT_mul_M {<n>}<N>\Z\Z\Z\Z$\
-% Fait la multiplication de <N> par <n>, qui est < 10000.
-% <N> est présenté *à l'envers*, sur *4n*. |
+% \lverb|This is multiplication by 1 up to 21. Last time I checked it is never
+% called with a wasteful multiplicand of 1.|
% \begin{macrocode}
-\def\XINT_mul_M #1%
-{%
- \expandafter\XINT_mul_M_checkifzeroorone\expandafter{\the\numexpr #1}%
-}%
-\def\XINT_mul_M_checkifzeroorone #1%
-{%
- \ifcase #1
- \expandafter\XINT_mul_M_zero
- \or
- \expandafter\XINT_mul_M_one
- \else
- \expandafter\XINT_mul_N
- \fi
- {0000}{}{#1}%
-}%
-\def\XINT_mul_M_zero #1\Z\Z\Z\Z { 0}%
-\def\XINT_mul_M_one #1#2#3#4\Z\Z\Z\Z
-{%
- \expandafter\xint_cleanupzeros_andstop\romannumeral0\xintreverseorder{#4}%
-}%
-\def\XINT_mul_N #1#2#3#4#5#6#7%
-{%
- \xint_gob_til_Z #4\xint_mul_p\Z\XINT_mul_P {#1}{#3}{#7#6#5#4}{#2}{#3}%
-}%
-\def\XINT_mul_P #1#2#3%
-{%
- \expandafter\XINT_mul_L\the\numexpr \xint_c_x^viii+#1+#2*#3\relax
-}%
-\def\XINT_mul_L 1#1#2#3#4#5#6#7#8#9%
-{%
- \XINT_mul_N {#1#2#3#4}{#5#6#7#8#9}%
-}%
-\def\xint_mul_p\Z\XINT_mul_P #1#2#3#4#5%
-{%
- \XINT_mul_M_end #1#4%
-}%
-\edef\XINT_mul_M_end #1#2#3#4#5#6#7#8%
-{%
- \noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4#5#6#7#8\relax
-}%
-% \end{macrocode}
-% \subsubsection{Main routine: \csh{XINT_mul_enter}}
-% \lverb|&
-% Routine de multiplication principale
-% (attention délimiteurs modifiés pour 1.08)$\
-% Le résultat partiel est toujours maintenu avec significatif à
-% droite et il a un nombre multiple de 4 de chiffres$\
-% \romannumeral0\XINT_mul_enter <N1>\Z\Z\Z\Z <N2>\W\W\W\W$\
-% avec <N1> *renversé*, *longueur 4n* (zéros éventuellement ajoutés
-% au-delà du chiffre le plus significatif)
-% et <N2> dans l'ordre *normal*, et pas forcément longueur 4n.
-% pas de signes.$\
-% Pour 1.08: dans \XINT_mul_enter et les modifs de 1.03
-% qui filtrent les courts, on pourrait croire que le
-% second opérande a au moins quatre chiffres; mais le problème c'est que
-% ceci est appelé par \XINT_sqr. Et de plus \XINT_sqr est utilisé dans
-% la nouvelle routine d'extraction de racine carrée: je ne veux pas
-% rajouter l'overhead à \XINT_sqr de voir si a longueur est au moins 4.
-% Dilemme donc. Il ne semble pas y avoir d'autres accès
-% directs (celui de big fac n'est pas un problème). J'ai presque été
-% tenté de faire du 5x4, mais si on veut maintenir les résultats
-% intermédiaires sur 4n, il y a des complications. Par ailleurs,
-% je modifie aussi un petit peu la façon de coder la suite, compte tenu
-% du style que j'ai développé ultérieurement. Attention terminaison
-% modifiée pour le deuxième opérande.|
-% \begin{macrocode}
-\def\XINT_mul_enter #1\Z\Z\Z\Z #2#3#4#5%
-{%
- \xint_gob_til_W #5\XINT_mul_exit_a\W
- \XINT_mul_start {#2#3#4#5}#1\Z\Z\Z\Z
-}%
-\def\XINT_mul_exit_a\W\XINT_mul_start #1%
-{%
- \XINT_mul_exit_b #1%
-}%
-\def\XINT_mul_exit_b #1#2#3#4%
+\def\XINT_verysmallmul #1.#2!1#3!%
{%
- \xint_gob_til_W
- #2\XINT_mul_exit_ci
- #3\XINT_mul_exit_cii
- \W\XINT_mul_exit_ciii #1#2#3#4%
-}%
-\def\XINT_mul_exit_ciii #1\W #2\Z\Z\Z\Z \W\W\W
-{%
- \XINT_mul_M {#1}#2\Z\Z\Z\Z
-}%
-\def\XINT_mul_exit_cii\W\XINT_mul_exit_ciii #1\W\W #2\Z\Z\Z\Z \W\W
-{%
- \XINT_mul_M {#1}#2\Z\Z\Z\Z
-}%
-\def\XINT_mul_exit_ci\W\XINT_mul_exit_cii
- \W\XINT_mul_exit_ciii #1\W\W\W #2\Z\Z\Z\Z \W
-{%
- \XINT_mul_M {#1}#2\Z\Z\Z\Z
-}%
-\def\XINT_mul_start #1#2\Z\Z\Z\Z
-{%
- \expandafter\XINT_mul_main\expandafter
- {\romannumeral0\XINT_mul_Mr {#1}#2\Z\Z\Z\Z}#2\Z\Z\Z\Z
-}%
-\def\XINT_mul_main #1#2\Z\Z\Z\Z #3#4#5#6%
-{%
- \xint_gob_til_W #6\XINT_mul_finish_a\W
- \XINT_mul_compute {#3#4#5#6}{#1}#2\Z\Z\Z\Z
+ \xint_gob_til_Z #3\XINT_verysmallmul_e\Z
+ \expandafter\XINT_verysmallmul_a
+ \the\numexpr #2*#3+#1.#2!%
}%
-\def\XINT_mul_compute #1#2#3\Z\Z\Z\Z
+\def\XINT_verysmallmul_e\Z\expandafter\XINT_verysmallmul_a\the\numexpr
+ #1+#2#3.#4!%
+{\xint_gob_til_zero #2\XINT_verysmallmul_f 0\xint_c_x^viii+#2#3!1\Z!}%
+\def\XINT_verysmallmul_f #1!1{1\relax}%
+\def\XINT_verysmallmul_a #1#2.%
{%
- \expandafter\XINT_mul_main\expandafter
- {\romannumeral0\expandafter
- \XINT_mul_Ar\expandafter0\expandafter{\expandafter}%
- \romannumeral0\XINT_mul_Mr {#1}#3\Z\Z\Z\Z
- \W\X\Y\Z 0000#2\W\X\Y\Z }#3\Z\Z\Z\Z
+ \unless\ifnum #1#2<\xint_c_x^ix
+ \expandafter\XINT_verysmallmul_bi\else
+ \expandafter\XINT_verysmallmul_bj\fi
+ \the\numexpr \xint_c_x^ix+#1#2.%
}%
+\def\XINT_verysmallmul_bj{\expandafter\XINT_verysmallmul_cj }%
+\def\XINT_verysmallmul_cj 1#1#2.%
+ {1#2\expandafter!\the\numexpr\XINT_verysmallmul #1.}%
+\def\XINT_verysmallmul_bi\the\numexpr\xint_c_x^ix+#1#2#3.%
+ {1#3\expandafter!\the\numexpr\XINT_verysmallmul #1#2.}%
% \end{macrocode}
-% \lverb|&
-% Ici, le deuxième nombre se termine. Fin du calcul. On utilise la variante
-% \XINT_addm_A de l'addition car on sait que le deuxième terme est au moins
-% aussi long que le premier. Lorsque le multiplicateur avait longueur 4n, la
-% dernière addition a fourni le résultat à l'envers, il faut donc encore le
-% renverser. |
+% \lverb|Used by division and by squaring, not by multiplication itself.|
% \begin{macrocode}
-\def\XINT_mul_finish_a\W\XINT_mul_compute #1%
-{%
- \XINT_mul_finish_b #1%
-}%
-\def\XINT_mul_finish_b #1#2#3#4%
-{%
- \xint_gob_til_W
- #1\XINT_mul_finish_c
- #2\XINT_mul_finish_ci
- #3\XINT_mul_finish_cii
- \W\XINT_mul_finish_ciii #1#2#3#4%
-}%
-\def\XINT_mul_finish_ciii #1\W #2#3\Z\Z\Z\Z \W\W\W
+\def\XINT_minimul_a #1.#2!#3#4#5#6#7!%
{%
- \expandafter\XINT_addm_A\expandafter0\expandafter{\expandafter}%
- \romannumeral0\XINT_mul_Mr {#1}#3\Z\Z\Z\Z \W\X\Y\Z 000#2\W\X\Y\Z
+ \expandafter\XINT_minimul_b
+ \the\numexpr \xint_c_x^viii+#2*#7.#2*#3#4#5#6+#1*#7.#1*#3#4#5#6.%
}%
-\def\XINT_mul_finish_cii
- \W\XINT_mul_finish_ciii #1\W\W #2#3\Z\Z\Z\Z \W\W
+\def\XINT_minimul_b 1#1#2#3#4#5.#6.%
{%
- \expandafter\XINT_addm_A\expandafter0\expandafter{\expandafter}%
- \romannumeral0\XINT_mul_Mr {#1}#3\Z\Z\Z\Z \W\X\Y\Z 00#2\W\X\Y\Z
+ \expandafter\XINT_minimul_c
+ \the\numexpr \xint_c_x^ix+#1#2#3#4+#6.#5.%
}%
-\def\XINT_mul_finish_ci #1\XINT_mul_finish_ciii #2\W\W\W #3#4\Z\Z\Z\Z \W
+\def\XINT_minimul_c 1#1#2#3#4#5#6.#7.#8.%
{%
- \expandafter\XINT_addm_A\expandafter0\expandafter{\expandafter}%
- \romannumeral0\XINT_mul_Mr {#2}#4\Z\Z\Z\Z \W\X\Y\Z 0#3\W\X\Y\Z
-}%
-\def\XINT_mul_finish_c #1\XINT_mul_finish_ciii \W\W\W\W #2#3\Z\Z\Z\Z
-{%
- \expandafter\xint_cleanupzeros_andstop\romannumeral0\xintreverseorder{#2}%
+ 1#6#7\expandafter!\the\numexpr \xint_c_x^viii+#1#2#3#4#5+#8!%
}%
% \end{macrocode}
-% \subsubsection{Variant: \csh{XINT_mulr_enter}}
-% \lverb|&
-% \romannumeral0\XINT_mulr_enter <N1>\Z\Z\Z\Z <N2>\W\W\W\W $\
-% Ici <N1> est à l'envers sur 4n, et <N2> est à l'endroit, pas sur 4n, comme
-% dans \XINT_mul_enter, mais le résultat est lui-même fourni *à l'envers*, sur
-% *4n* (en faisant attention de ne pas avoir 0000 à la fin).$\
-% Utilisé par le calcul des puissances. J'ai modifié dans 1.08 sur le
-% modèle de la nouvelle version de \XINT_mul_enter. Je pourrais économiser des
-% macros et fusionner \XINT_mul_enter et \XINT_mulr_enter. Une autre fois.|
+% \subsection{\csh{xintiSqr}, \csh{xintiiSqr}}
+% \lverb|Rewritten for v1.2.|
% \begin{macrocode}
-\def\XINT_mulr_enter #1\Z\Z\Z\Z #2#3#4#5%
-{%
- \xint_gob_til_W #5\XINT_mulr_exit_a\W
- \XINT_mulr_start {#2#3#4#5}#1\Z\Z\Z\Z
-}%
-\def\XINT_mulr_exit_a\W\XINT_mulr_start #1%
-{%
- \XINT_mulr_exit_b #1%
-}%
-\def\XINT_mulr_exit_b #1#2#3#4%
-{%
- \xint_gob_til_W
- #2\XINT_mulr_exit_ci
- #3\XINT_mulr_exit_cii
- \W\XINT_mulr_exit_ciii #1#2#3#4%
-}%
-\def\XINT_mulr_exit_ciii #1\W #2\Z\Z\Z\Z \W\W\W
-{%
- \XINT_mul_Mr {#1}#2\Z\Z\Z\Z
-}%
-\def\XINT_mulr_exit_cii\W\XINT_mulr_exit_ciii #1\W\W #2\Z\Z\Z\Z \W\W
-{%
- \XINT_mul_Mr {#1}#2\Z\Z\Z\Z
-}%
-\def\XINT_mulr_exit_ci\W\XINT_mulr_exit_cii
- \W\XINT_mulr_exit_ciii #1\W\W\W #2\Z\Z\Z\Z \W
-{%
- \XINT_mul_Mr {#1}#2\Z\Z\Z\Z
-}%
-\def\XINT_mulr_start #1#2\Z\Z\Z\Z
-{%
- \expandafter\XINT_mulr_main\expandafter
- {\romannumeral0\XINT_mul_Mr {#1}#2\Z\Z\Z\Z}#2\Z\Z\Z\Z
-}%
-\def\XINT_mulr_main #1#2\Z\Z\Z\Z #3#4#5#6%
-{%
- \xint_gob_til_W #6\XINT_mulr_finish_a\W
- \XINT_mulr_compute {#3#4#5#6}{#1}#2\Z\Z\Z\Z
-}%
-\def\XINT_mulr_compute #1#2#3\Z\Z\Z\Z
-{%
- \expandafter\XINT_mulr_main\expandafter
- {\romannumeral0\expandafter
- \XINT_mul_Ar\expandafter0\expandafter{\expandafter}%
- \romannumeral0\XINT_mul_Mr {#1}#3\Z\Z\Z\Z
- \W\X\Y\Z 0000#2\W\X\Y\Z }#3\Z\Z\Z\Z
-}%
-\def\XINT_mulr_finish_a\W\XINT_mulr_compute #1%
-{%
- \XINT_mulr_finish_b #1%
-}%
-\def\XINT_mulr_finish_b #1#2#3#4%
+\def\xintiiSqr {\romannumeral0\xintiisqr }%
+\def\xintiisqr #1%
{%
- \xint_gob_til_W
- #1\XINT_mulr_finish_c
- #2\XINT_mulr_finish_ci
- #3\XINT_mulr_finish_cii
- \W\XINT_mulr_finish_ciii #1#2#3#4%
+ \expandafter\XINT_sqr\romannumeral0\xintiiabs{#1}\Z
}%
-\def\XINT_mulr_finish_ciii #1\W #2#3\Z\Z\Z\Z \W\W\W
+\def\xintiSqr {\romannumeral0\xintisqr }%
+\def\xintisqr #1%
{%
- \expandafter\XINT_addp_A\expandafter0\expandafter{\expandafter}%
- \romannumeral0\XINT_mul_Mr {#1}#3\Z\Z\Z\Z \W\X\Y\Z 000#2\W\X\Y\Z
+ \expandafter\XINT_sqr\romannumeral0\xintiabs{#1}\Z
}%
-\def\XINT_mulr_finish_cii
- \W\XINT_mulr_finish_ciii #1\W\W #2#3\Z\Z\Z\Z \W\W
+\def\XINT_sqr #1\Z
{%
- \expandafter\XINT_addp_A\expandafter0\expandafter{\expandafter}%
- \romannumeral0\XINT_mul_Mr {#1}#3\Z\Z\Z\Z \W\X\Y\Z 00#2\W\X\Y\Z
+ \expandafter\XINT_sqr_a
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #1\R\R\R\R\R\R\R\R{10}0000001\W
+ #1\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_iii
+ \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii
+ \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W
+ \Z
}%
-\def\XINT_mulr_finish_ci #1\XINT_mulr_finish_ciii #2\W\W\W #3#4\Z\Z\Z\Z \W
-{%
- \expandafter\XINT_addp_A\expandafter0\expandafter{\expandafter}%
- \romannumeral0\XINT_mul_Mr {#2}#4\Z\Z\Z\Z \W\X\Y\Z 0#3\W\X\Y\Z
+\def\XINT_sqr_a #1.%
+{%
+ \ifnum #1=\xint_c_i \expandafter\XINT_sqr_small
+ \else\expandafter\XINT_sqr_start\fi
}%
-\def\XINT_mulr_finish_c #1\XINT_mulr_finish_ciii \W\W\W\W #2#3\Z\Z\Z\Z { #2}%
-% \end{macrocode}
-% \subsection{\csh{xintiSqr}, \csh{xintiiSqr}}
-% \begin{macrocode}
-\def\xintiiSqr {\romannumeral0\xintiisqr }%
-\def\xintiisqr #1%
+\def\XINT_sqr_small 1#1#2#3#4#5!\Z
{%
- \expandafter\XINT_sqr\expandafter {\romannumeral0\xintiiabs{#1}}%
+ \ifnum #1#2#3#4#5<46341 \expandafter\XINT_sqr_verysmall\fi
+ \expandafter\XINT_sqr_small_out
+ \the\numexpr\XINT_minimul_a #1#2#3#4.#5!#1#2#3#4#5!%
}%
-\def\xintiSqr {\romannumeral0\xintisqr }%
-\def\xintisqr #1%
+\edef\XINT_sqr_verysmall
+ \expandafter\XINT_sqr_small_out\the\numexpr\XINT_minimul_a #1!#2!%
+ {\noexpand\expandafter\space\noexpand\the\numexpr #2*#2\relax}%
+\def\XINT_sqr_small_out 1#1!1#2!%
{%
- \expandafter\XINT_sqr\expandafter {\romannumeral0\xintiabs{#1}}%
+ \XINT_cuz #2#1\R
}%
-\let\xintSqr\xintiSqr \let\xintsqr\xintisqr
-\def\XINT_sqr #1%
+\def\XINT_sqr_start #1\Z
{%
- \expandafter\XINT_mul_enter
- \romannumeral0%
- \XINT_RQ {}#1\R\R\R\R\R\R\R\R\Z
- \Z\Z\Z\Z #1\W\W\W\W
+ \expandafter\XINT_mul_out
+ \the\numexpr\XINT_mul_loop 100000000!\Z\W #11\Z!\W #11\Z!%
+ 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
}%
% \end{macrocode}
% \subsection{\csh{xintiPow}, \csh{xintiiPow}}
-% \lverb|1.02 modified the \XINT_posprod routine, the was renamed
-% \XINT_pow_posprod and moved here, as it was well adapted for computing powers.
-% Then 1.03 moved the special variants of multiplication (hence of addition)
-% which were needed to earlier in this style file.
-%
-% Modified in 1.06, the exponent is given to a \numexpr rather than twice
-% expanded. \xintnum added in 1.09a.
-%
-% \XINT_pow_posprod: Routine de produit servant pour le calcul des
-% puissances. Chaque nouveau terme est plus grand que ce qui a déjà été calculé.
-% Par conséquent on a intérêt à le conserver en second dans la routine de
-% multiplication, donc le précédent calcul a intérêt à avoir été donné sur 4n, à
-% l'envers. Il faut donc modifier la multiplication pour qu'elle fasse cela. Ce
-% qui oblige à utiliser une version spéciale de l'addition également.
-%
-% 1.09j has reorganized the main loop, the described above \XINT_pow_posprod
-% routine has been removed, intermediate multiplications are done
-% immediately. Also, the maximal accepted exponent is now 100000 (no such
-% restriction in \xintFloatPow, which accepts any exponent less than 2^31, and
-% in \xintFloatPower which accepts long integers as exponent).
-%
-% 2^100000=9.990020930143845e30102 and multiplication of two numbers
-% with 30000 digits would take hours on my laptop (seconds for 1000 digits).|
+% \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.|
% \begin{macrocode}
\def\xintiiPow {\romannumeral0\xintiipow }%
\def\xintiipow #1%
@@ -17076,7 +16825,6 @@ $1$ or $-1$.
{%
\expandafter\xint_pow\romannumeral0\xintnum{#1}\Z%
}%
-\let\xintPow\xintiPow \let\xintpow\xintipow
\def\xint_pow #1#2\Z
{%
\xint_UDsignfork
@@ -17140,7 +16888,7 @@ $1$ or $-1$.
\ifcase\XINT_cntSgn #1\Z
\expandafter\XINT_pow_BisZero
\or
- \expandafter\XINT_pow_checkBsize
+ \expandafter\XINT_pow_I_in
\else
\expandafter\XINT_pow_BisNegative
\fi
@@ -17150,117 +16898,233 @@ $1$ or $-1$.
{\noexpand\xintError:FractionRoundedToZero\space 0}%
\def\XINT_pow_BisZero #1#2{ 1}%
% \end{macrocode}
-% \lverb|B = #1 > 0, A = #2 > 1. With 1.05, I replace \xintiLen{#1}>9 by
-% direct use of \numexpr [to generate an error message if the exponent is too
-% large] 1.06: \numexpr was already used above.|
-% \begin{macrocode}
-\def\XINT_pow_checkBsize #1%
-{%
- \ifnum #1>100000
- \expandafter\XINT_pow_BtooBig
+% \lverb|B = #1 > 0, A = #2 > 1.|
+% \begin{macrocode}
+% \def\XINT_pow_checkBsize #1%
+% {%
+% \ifnum #1>131000
+% \expandafter\XINT_pow_BtooBig
+% \else
+% \expandafter\XINT_pow_I_in
+% \fi
+% {#1}%
+% }%
+% \edef\XINT_pow_BtooBig #1#2{\noexpand\xintError:ExponentTooBig\space 0}%
+%%%%%%%%%%%%
+\def\XINT_pow_I_in #1#2%
+{%
+ \expandafter\XINT_pow_I_loop
+ \the\numexpr #1\expandafter.%
+ \romannumeral0\expandafter\XINT_sepandrev
+ \romannumeral0\XINT_zeroes_forviii #2\R\R\R\R\R\R\R\R{10}0000001\W
+ #2\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax XX%
+ \R.\R.\R.\R.\R.\R.\R.\R.\W 1\Z!\W
+ 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+}%
+\def\XINT_pow_I_loop #1.%
+{%
+ \ifnum #1 = \xint_c_i\expandafter\XINT_pow_I_exit\fi
+ \ifodd #1
+ \expandafter\XINT_pow_II_in
\else
- \expandafter\XINT_pow_loopI
- \fi
- {#1}%
+ \expandafter\XINT_pow_I_squareit
+ \fi #1.%
}%
-\edef\XINT_pow_BtooBig #1#2{\noexpand\xintError:ExponentTooBig\space 0}%
-\def\XINT_pow_loopI #1%
+\def\XINT_pow_I_exit \ifodd #1\fi #2.#3\W {\XINT_mul_out #3}%
+\def\XINT_pow_I_squareit #1.#2\W%
{%
- \ifnum #1=\xint_c_i\XINT_pow_Iend\fi
+ \expandafter\XINT_pow_I_loop
+ \the\numexpr #1/\xint_c_ii\expandafter.%
+ \the\numexpr\XINT_pow_mulbutcheckifsmall #2\W #2\W
+}%
+%%%%%%%%%%%%
+\def\XINT_pow_mulbutcheckifsmall #1!1#2%
+{%
+ \xint_gob_til_Z #2\XINT_pow_mul_small\Z
+ \XINT_mul_loop 100000000!\Z\W #1!1#2%
+}%
+\def\XINT_pow_mul_small\Z\XINT_mul_loop 100000000!\Z\W 1#1!1\Z!\W
+{%
+ \XINT_smallmul 1#1!%
+}%
+%%%%%%%%%%%%
+\def\XINT_pow_II_in #1.#2\W
+{%
+ \expandafter\XINT_pow_II_loop
+ \the\numexpr #1/\xint_c_ii-\xint_c_i\expandafter.%
+ \the\numexpr\XINT_pow_mulbutcheckifsmall #2\W #2\W #2\W
+}%
+\def\XINT_pow_II_loop #1.%
+{%
+ \ifnum #1 = \xint_c_i\expandafter\XINT_pow_II_exit\fi
\ifodd #1
- \expandafter\XINT_pow_loopI_odd
+ \expandafter\XINT_pow_II_odda
\else
- \expandafter\XINT_pow_loopI_even
- \fi
- {#1}%
+ \expandafter\XINT_pow_II_even
+ \fi #1.%
}%
-\edef\XINT_pow_Iend\fi #1\fi #2#3{\noexpand\fi\space #3}%
-\def\XINT_pow_loopI_even #1#2%
+\def\XINT_pow_II_exit\ifodd #1\fi #2.#3\W #4\W
{%
- \expandafter\XINT_pow_loopI\expandafter
- {\the\numexpr #1/\xint_c_ii\expandafter}\expandafter
- {\romannumeral0\xintiisqr {#2}}%
+ \expandafter\XINT_mul_out
+ \the\numexpr\XINT_pow_mulbutcheckifsmall #4\W #3%
}%
-\def\XINT_pow_loopI_odd #1#2%
+\def\XINT_pow_II_even #1.#2\W
{%
- \expandafter\XINT_pow_loopI_odda\expandafter
- {\romannumeral0\XINT_RQ {}#2\R\R\R\R\R\R\R\R\Z }{#1}{#2}%
+ \expandafter\XINT_pow_II_loop
+ \the\numexpr #1/\xint_c_ii\expandafter.%
+ \the\numexpr\XINT_pow_mulbutcheckifsmall #2\W #2\W
}%
-\def\XINT_pow_loopI_odda #1#2#3%
+\def\XINT_pow_II_odda #1.#2\W #3\W
{%
- \expandafter\XINT_pow_loopII\expandafter
- {\the\numexpr #2/\xint_c_ii-\xint_c_i\expandafter}\expandafter
- {\romannumeral0\xintiisqr {#3}}{#1}%
+ \expandafter\XINT_pow_II_oddb
+ \the\numexpr #1/\xint_c_ii-\xint_c_i\expandafter.%
+ \the\numexpr\XINT_pow_mulbutcheckifsmall #3\W #2\W #2\W
}%
-\def\XINT_pow_loopII #1%
+\def\XINT_pow_II_oddb #1.#2\W #3\W
{%
- \ifnum #1 = \xint_c_i\XINT_pow_IIend\fi
- \ifodd #1
- \expandafter\XINT_pow_loopII_odd
+ \expandafter\XINT_pow_II_loop
+ \the\numexpr #1\expandafter.%
+ \the\numexpr\XINT_pow_mulbutcheckifsmall #3\W #3\W #2\W
+}%
+% \end{macrocode}
+% \subsection{\csh{xintiFac}, \csh{xintiiFac}}
+% \lverb|Moved to xintcore.sty with release 1.2 (to be usable by \bnumexpr).
+% The routine has been partially rewritten and there is an intrinsic limit at
+% 9999. Anyhow with current default settings of the etex memory and the
+% current 1.2 routine (last commit: eada1b1), the maximal possible computation
+% is 5971! (which has 19956 digits). Also, I add \xintiiFac which does only
+% \romannumeral-`0 and not \numexpr on its argument. This is for a silly
+% slight optimization of the \xintiiexpr (and \bnumexpr) parsers. If the
+% argument is >=2^31 an arithmetic overflow will occur in the \ifnum. This is
+% not as good as in the \numexpr, but well.|
+% \begin{macrocode}
+\def\xintiFac {\romannumeral0\xintifac }%
+\def\xintifac #1%
+{%
+ \expandafter\XINT_fac_fork\expandafter {\the\numexpr#1}%
+}%
+\def\xintiiFac {\romannumeral0\xintiifac }%
+\def\xintiifac #1%
+{%
+ \expandafter\XINT_fac_fork\expandafter {\romannumeral-`0#1}%
+}%
+\let\xintFac\xintiFac \let\xintfac\xintifac
+\def\XINT_fac_fork #1%
+{%
+ \ifcase\XINT_cntSgn #1\Z
+ \xint_afterfi{\expandafter\space\expandafter 1\xint_gobble_i }%
+ \or
+ \expandafter\XINT_fac_checksize
\else
- \expandafter\XINT_pow_loopII_even
+ \xint_afterfi{\expandafter\xintError:FactorialOfNegativeNumber
+ \expandafter\space\expandafter 1\xint_gobble_i }%
\fi
{#1}%
}%
-\def\XINT_pow_loopII_even #1#2%
+\def\XINT_fac_checksize #1%
{%
- \expandafter\XINT_pow_loopII\expandafter
- {\the\numexpr #1/\xint_c_ii\expandafter}\expandafter
- {\romannumeral0\xintiisqr {#2}}%
+ \ifnum #1>9999
+ \xint_dothis{\expandafter\xintError:FactorialOfTooBigNumber
+ \expandafter\space\expandafter 1\xint_gob_til_W }\fi
+ \ifnum #1>465 \xint_dothis{\XINT_fac_bigloop_a #1.}\fi
+ \ifnum #1>101 \xint_dothis{\XINT_fac_medloop_a #1.\XINT_mul_out}\fi
+ \xint_orthat{\XINT_fac_smallloop_a #1.\XINT_mul_out}%
+ 1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
}%
-\def\XINT_pow_loopII_odd #1#2#3%
+\def\XINT_fac_bigloop_a #1.%
{%
- \expandafter\XINT_pow_loopII_odda\expandafter
- {\romannumeral0\XINT_mulr_enter #3\Z\Z\Z\Z #2\W\W\W\W}{#1}{#2}%
+ \expandafter\XINT_fac_bigloop_b \the\numexpr
+ #1+\xint_c_i-\xint_c_ii*((#1-464)/\xint_c_ii).#1.%
}%
-\def\XINT_pow_loopII_odda #1#2#3%
+\def\XINT_fac_bigloop_b #1.#2.%
{%
- \expandafter\XINT_pow_loopII\expandafter
- {\the\numexpr #2/\xint_c_ii-\xint_c_i\expandafter}\expandafter
- {\romannumeral0\xintiisqr {#3}}{#1}%
+ \expandafter\XINT_fac_medloop_a
+ \the\numexpr #1-\xint_c_i.{\XINT_fac_bigloop_loop #1.#2.}%
+}%
+\def\XINT_fac_bigloop_loop #1.#2.%
+{%
+ \ifnum #1>#2 \expandafter\XINT_fac_bigloop_exit\fi
+ \expandafter\XINT_fac_bigloop_loop
+ \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!%
+{%
+ \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\Z!%
+}%
+\expandafter\def\csname XINT_fac_smallloop_-2\endcsname #1.%
+{%
+ \XINT_fac_smallloop_loop 3.#1.100000002!1\Z!%
+}%
+\expandafter\def\csname XINT_fac_smallloop_-1\endcsname #1.%
+{%
+ \XINT_fac_smallloop_loop 4.#1.100000006!1\Z!%
+}%
+\expandafter\def\csname XINT_fac_smallloop_0\endcsname #1.%
+{%
+ \XINT_fac_smallloop_loop 5.#1.1000000024!1\Z!%
+}%
+\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_pow_IIend\fi #1\fi #2#3#4%
+\def\XINT_fac_smallloop_mul #1!%
{%
- \fi\XINT_mul_enter #4\Z\Z\Z\Z #3\W\W\W\W
+ \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\Z!#3{#3#2\Z!}%
% \end{macrocode}
% \subsection{\csh{xintiDivision}, \csh{xintiQuo}, \csh{xintiRem},
% \csh{xintiiDivision}, \csh{xintiiQuo}, \csh{xintiiRem}}
-% \lverb|The 1.09a release inserted the use of \xintnum. The \xintiiDivision
-% etc... are the ones which do only \romannumeral-`0.
-%
-% January 5, 2014: Naturally, addition, subtraction, multiplication and division
-% are the first things I did and since then I had left the division
-% untouched. So in preparation of release 1.09j, I started revisiting the
-% division, I did various minor improvements obtaining roughly
-% 10$% efficiency gain. Then I decided I
-% should deliberately impact the input save stack, with the hope to gain more
-% speed from removing tokens and leaving them upstream.
-%
-% For this however I had to modify the underlying mathematical algorithm. The
-% initial one is a bit unusual I guess, and, I trust, rather efficient, but it
-% does not produce the quotient digits (in base 10000) one by one; at any given
-% time it is possible that some correction will be made, which means it is not
-% an appropriate algorithm for a TeX implementation which will abandon the
-% quotient upstream. Thus I now have with 1.09j a new underlying mathematical
-% algorithm, presumably much more standard. It is a bit complicated to implement
-% expandably these things, but in the end I had regained the already mentioned
-% 10$% efficiency and even more for
-% small to medium sized inputs (up to 30$% perhaps). And in passing I did a
-% special routine for divisors < 10000, which is 5 to 10 times faster still.
-%
-% But, I then tested a variant of my new implementation which again did
-% not impact the input save stack and, for sizes of up to 200 digits, it
-% is not much worse, indeed it is perhaps actually better than the one
-% abandoning the quotient digits upstream (and in the end putting them
-% in the correct order). So, finally, I re-incorporated the produced
-% quotient digits within a tail recursion. Hence \xintiDivision, like all
-% other routines in xint (except \xintSeq without optional parameter)
-% does not impact the input save stack. One can have a produced
-% quotient longer than 4x5000=20000 digits, and no need to worry about
-% consequences propagating to \xintTrunc, \xintRound, \xintFloat,
-% \xintFloatSqrt, etc... and all other places using the division. See
-% also \xintXTrunc in this context.|
+% \lverb|Completely rewritten for v1.2.
+% WARNING: some comments below try to describe the flow of tokens but they
+% date back from xint 1.09j and I updated them on the fly while doing the 1.2
+% version. As the new works in base 10^8, not 10^4 and "drops" the quotient
+% digits,rather than store them upfront as the earlier code, I may well have
+% not correctly converted all such comments. At the last minute some
+% previously #1 became stuff like #1#2#3#4, then of course the old comments
+% describing what the macro parameters stand for are necessarily wrong.|
% \begin{macrocode}
\def\xintiiQuo {\romannumeral0\xintiiquo }%
\def\xintiiRem {\romannumeral0\xintiirem }%
@@ -17270,16 +17134,15 @@ $1$ or $-1$.
\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 % deprecated (1.1)
-\let\xintRem\xintiRem\let\xintrem\xintirem % deprecated (1.1)
+\let\xintQuo\xintiQuo\let\xintquo\xintiquo % deprecated
+\let\xintRem\xintiRem\let\xintrem\xintirem % deprecated
% \end{macrocode}
% \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 #1{\expandafter\XINT_division\romannumeral0\xintnum{#1}\Z }%
-\let\xintDivision\xintiDivision \let\xintdivision\xintidivision % deprecated
-\def\XINT_division #1#2\Z #3{\expandafter\XINT_iidivision_a\expandafter #1%
+\def\xintidivision #1{\expandafter\XINT_idivision\romannumeral0\xintnum{#1}\Z }%
+\def\XINT_idivision #1#2\Z #3{\expandafter\XINT_iidivision_a\expandafter #1%
\romannumeral0\xintnum{#3}\Z #2\Z }%
\def\xintiiDivision {\romannumeral0\xintiidivision }%
\def\xintiidivision #1{\expandafter\XINT_iidivision \romannumeral-`0#1\Z }%
@@ -17293,10 +17156,10 @@ $1$ or $-1$.
\romannumeral0\XINT_iidivision_bpos #1}\fi
\xint_orthat{\XINT_iidivision_bpos #1#2}%
}%
-\def\XINT_iidivision_divbyzero #1\Z #2\Z {\xintError:DivisionByZero\space {0}{0}}%
-\def\XINT_iidivision_aiszero #1\Z #2\Z { {0}{0}}%
+\def\XINT_iidivision_divbyzero #1\Z #2\Z {\xintError:DivisionByZero{0}{0}}%
+\def\XINT_iidivision_aiszero #1\Z #2\Z {{0}{0}}%
\def\XINT_iidivision_bneg #1% q->-q, r unchanged
- {\expandafter\space\expandafter{\romannumeral0\XINT_opp #1}}%
+ {\expandafter{\romannumeral0\XINT_opp #1}}%
\def\XINT_iidivision_bpos #1%
{%
\xint_UDsignfork
@@ -17313,7 +17176,7 @@ $1$ or $-1$.
\else
\expandafter\XINT_iidivision_aneg_rpos
\fi {#1}{#2}}%
-\def\XINT_iidivision_aneg_rzero #1#2#3{ {-#1}{0}}% necessarily q was >0
+\def\XINT_iidivision_aneg_rzero #1#2#3{{-#1}{0}}% necessarily q was >0
\def\XINT_iidivision_aneg_rpos #1%
{%
\expandafter\XINT_iidivision_aneg_end\expandafter
@@ -17321,229 +17184,211 @@ $1$ or $-1$.
}%
\def\XINT_iidivision_aneg_end #1#2#3%
{%
- \expandafter\xint_exchangetwo_keepbraces_thenstop
- \expandafter{\romannumeral0\XINT_sub_pre {#3}{#2}}{#1}% r-> b-r
+ \expandafter\xint_exchangetwo_keepbraces
+ \expandafter{\romannumeral0\XINT_sub_mm_a {}{}#3\Z #2\Z}{#1}% r-> b-r
}%
-% \end{macrocode}
-% \lverb|&
-% Pour la suite A et B sont > 0.
-% #1 = B. Pour le moment à l'endroit.
-% Calcul du plus petit K = 4n >= longueur de B|
-% \begin{macrocode}
+%%%%%%%%%%%%
\def\XINT_div_prepare #1%
{%
- \expandafter \XINT_div_prepareB_aa \expandafter
- {\romannumeral0\xintlength {#1}}{#1}% B > 0 ici
+ \XINT_div_prepare_a #1\R\R\R\R\R\R\R\R {10}0000001\W !{#1}%
}%
-\def\XINT_div_prepareB_aa #1%
+\def\XINT_div_prepare_a #1#2#3#4#5#6#7#8#9%
{%
- \ifnum #1=\xint_c_i
- \expandafter\XINT_div_prepareB_onedigit
- \else
- \expandafter\XINT_div_prepareB_a
- \fi
- {#1}%
-}%
-\def\XINT_div_prepareB_a #1%
-{%
- \expandafter\XINT_div_prepareB_c\expandafter
- {\the\numexpr \xint_c_iv*((#1+\xint_c_i)/\xint_c_iv)}{#1}%
+ \xint_gob_til_R #9\XINT_div_prepare_small\R
+ \XINT_div_prepare_b #9%
}%
-% \end{macrocode}
-% \lverb|B=1 and B=2 treated specially.|
-% \begin{macrocode}
-\def\XINT_div_prepareB_onedigit #1#2%
+%%%%%%%%%%%%
+\def\XINT_div_prepare_small\R #1!#2%
{%
- \ifcase#2
+ \ifcase #2
\or\expandafter\XINT_div_BisOne
\or\expandafter\XINT_div_BisTwo
- \else\expandafter\XINT_div_prepareB_e
- \fi {000}{0}{4}{#2}%
+ \else\expandafter\XINT_div_small_a
+ \fi {#2}%
}%
-\def\XINT_div_BisOne #1#2#3#4#5{ {#5}{0}}%
-\def\XINT_div_BisTwo #1#2#3#4#5%
+\def\XINT_div_BisOne #1#2{{#2}{0}}%
+\def\XINT_div_BisTwo #1#2%
{%
\expandafter\expandafter\expandafter\XINT_div_BisTwo_a
- \ifodd\xintiiLDg{#5} \expandafter1\else \expandafter0\fi {#5}%
+ \ifodd\xintLDg{#2} \expandafter1\else \expandafter0\fi {#2}%
}%
-\edef\XINT_div_BisTwo_a #1#2%
+\def\XINT_div_BisTwo_a #1#2%
{%
- \noexpand\expandafter\space\noexpand\expandafter
- {\noexpand\romannumeral0\noexpand\xinthalf {#2}}{#1}%
+ \expandafter{\romannumeral0\xinthalf {#2}}{#1}%
}%
-% \end{macrocode}
-% \lverb|#1 = K. 1.09j uses \csname, earlier versions did it with
-% \ifcase.|
-% \begin{macrocode}
-\def\XINT_div_prepareB_c #1#2%
+\def\XINT_div_small_a #1#2%
{%
- \csname XINT_div_prepareB_d\romannumeral\numexpr#1-#2\endcsname
- {#1}%
+ \expandafter\XINT_div_small_b
+ \the\numexpr #1/\xint_c_ii\expandafter
+ .\the\numexpr \xint_c_x^viii+#1\expandafter!%
+ \romannumeral0%
+ \XINT_div_small_ba #2\R\R\R\R\R\R\R\R{10}0000001\W
+ #2\XINT_sepbyviii_Z_end 2345678\relax
}%
-\def\XINT_div_prepareB_d {\XINT_div_prepareB_e {}{0000}}%
-\def\XINT_div_prepareB_di {\XINT_div_prepareB_e {0}{000}}%
-\def\XINT_div_prepareB_dii {\XINT_div_prepareB_e {00}{00}}%
-\def\XINT_div_prepareB_diii {\XINT_div_prepareB_e {000}{0}}%
-\def\XINT_div_cleanR #10000.{{#1}}%
-% \end{macrocode}
-% \lverb|#1 = zéros à rajouter à B, #2=c [modifié dans 1.09j, ce sont maintenant
-% des zéros explicites en nombre 4 - ancien c, et on utilisera
-% \XINT_div_cleanR et non plus \XINT_dsh_checksignx pour nettoyer à la fin
-% des zéros en excès dans le Reste; in all comments next, «c» stands now {0} or
-% {00} or {000} or {0000} rather than a digit as in earlier versions], #3=K, #4
-% = B|
-% \begin{macrocode}
-\def\XINT_div_prepareB_e #1#2#3#4%
+\def\XINT_div_small_b #1!#2{#2#1!}%
+\def\XINT_div_small_ba #1#2#3#4#5#6#7#8#9%
{%
- \ifnum#3=\xint_c_iv\expandafter\XINT_div_prepareLittleB_f
- \else\expandafter\XINT_div_prepareB_f
- \fi
- #4#1{#3}{#2}{#1}%
+ \xint_gob_til_R #9\XINT_div_smallsmall\R
+ \expandafter\XINT_div_dosmalldiv
+ \the\numexpr\expandafter\XINT_sepbyviii_Z
+ \romannumeral0\XINT_zeroes_forviii
+ #1#2#3#4#5#6#7#8#9%
}%
-% \end{macrocode}
-% \lverb|x = #1#2#3#4 = 4 premiers chiffres de B. #1 est non nul. B is reversed.
-% With 1.09j or latter x+1 and (x+1)/2 are pre-computed. Si K=4 on ne renverse
-% pas B, et donc B=x dans la suite. De plus pour K=4 on ne travaille pas avec
-% x+1 et (x+1)/2 mais avec x et x/2.|
-% \begin{macrocode}
-\def\XINT_div_prepareB_f #1#2#3#4#5#{%
- \expandafter\XINT_div_prepareB_g
- \the\numexpr #1#2#3#4+\xint_c_i\expandafter
- .\the\numexpr (#1#2#3#4+\xint_c_i)/\xint_c_ii\expandafter
- .\romannumeral0\xintreverseorder {#1#2#3#4#5}.{#1#2#3#4}%
+\def\XINT_div_smallsmall\R
+ \expandafter\XINT_div_dosmalldiv
+ \the\numexpr\expandafter\XINT_sepbyviii_Z
+ \romannumeral0\XINT_zeroes_forviii #1\R #2\relax
+ {{\XINT_div_dosmallsmall}{#1}}%
+\def\XINT_div_dosmallsmall #1.1#2!#3%
+{%
+ \expandafter\XINT_div_smallsmallend
+ \the\numexpr (#3+#1)/#2-\xint_c_i.#2.#3.%
}%
-\def\XINT_div_prepareLittleB_f #1#{%
- \expandafter\XINT_div_prepareB_g \the\numexpr #1/\xint_c_ii.{}.{}.{#1}%
+\def\XINT_div_smallsmallend #1.#2.#3.{\expandafter
+ {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #3-#1*#2}}%
+\def\XINT_div_dosmalldiv
+ {{\expandafter\XINT_sdiv_out\the\numexpr\XINT_smalldivx_a}}%
+%%%%%%%%%%%%
+\def\XINT_div_prepare_b
+ {\expandafter\XINT_div_prepare_c\romannumeral0\XINT_zeroes_forviii }%
+\def\XINT_div_prepare_c #1!%
+{%
+ \XINT_div_prepare_d #1.00000000!{#1}%
}%
-% \end{macrocode}
-% \lverb|&
-% #1 = x' = x+1= 1+quatre premiers chiffres de B, #2 = y = (x+1)/2 précalculé
-% #3 = B préparé et maintenant renversé, #4=x,
-% #5 = K, #6 = «c», #7= {} ou {0} ou {00} ou {000}, #8 = A initial
-% On multiplie aussi A par 10^c. -> AK{x'yx}B«c». Par contre dans le
-% cas little on a #1=y=(x/2), #2={}, #3={}, #4=x, donc cela donne
-% ->AK{y{}x}{}«c», il n'y a pas de B.|
-% \begin{macrocode}
-\def\XINT_div_prepareB_g #1.#2.#3.#4#5#6#7#8%
+\def\XINT_div_prepare_d #1#2#3#4#5#6#7#8#9%
{%
- \XINT_div_prepareA_a {#8#7}{#5}{{#1}{#2}{#4}}{#3}{#6}%
+ \expandafter\XINT_div_prepare_e\xint_gob_til_dot #1#2#3#4#5#6#7#8#9!%
}%
-% \end{macrocode}
-% \lverb|A, K, {x'yx}, B«c» |
-% \begin{macrocode}
-\def\XINT_div_prepareA_a #1%
+\def\XINT_div_prepare_e #1!#2!#3#4%
{%
- \expandafter\XINT_div_prepareA_b\expandafter
- {\romannumeral0\xintlength {#1}}{#1}%
+ \XINT_div_prepare_f #4#3\X {#1}{#3}%
}%
-% \end{macrocode}
-% \lverb|L0, A, K, {x'yx}, B«c»|
-% \begin{macrocode}
-\def\XINT_div_prepareA_b #1%
+\def\XINT_div_prepare_f #1#2#3#4#5#6#7#8#9\X
{%
- \expandafter\XINT_div_prepareA_c\expandafter
- {\the\numexpr \xint_c_iv*((#1+\xint_c_i)/\xint_c_iv)}{#1}%
+ \expandafter\XINT_div_prepare_g
+ \the\numexpr #1#2#3#4#5#6#7#8+\xint_c_i\expandafter
+ .\the\numexpr (#1#2#3#4#5#6#7#8+\xint_c_i)/\xint_c_ii\expandafter
+ .\the\numexpr #1#2#3#4#5#6#7#8\expandafter
+ .\romannumeral0\XINT_sepandrev_andcount
+ #1#2#3#4#5#6#7#8#9\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678%
+ \relax\xint_c_ii\xint_c_iii
+ \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii
+ \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W
+ \X
}%
-% \end{macrocode}
-% \lverb|L, L0, A, K, {x'yx}, B, «c»|
-% \begin{macrocode}
-\def\XINT_div_prepareA_c #1#2%
+\def\XINT_div_prepare_g #1.#2.#3.#4.#5\X #6#7#8%
{%
- \csname XINT_div_prepareA_d\romannumeral\numexpr #1-#2\endcsname
- {#1}%
+ \expandafter\XINT_div_prepare_h
+ \the\numexpr\expandafter\XINT_sepbyviii_andcount
+ \romannumeral0\XINT_zeroes_forviii #8#7\R\R\R\R\R\R\R\R{10}0000001\W
+ #8#7\XINT_sepbyviii_end 2345678\relax
+ \xint_c_vii!\xint_c_vi!\xint_c_v!\xint_c_iv!%
+ \xint_c_iii!\xint_c_ii!\xint_c_i!\xint_c_\W
+ {#1}{#2}{#3}{#4}{#5}{#6}%
}%
-\def\XINT_div_prepareA_d {\XINT_div_prepareA_e {}}%
-\def\XINT_div_prepareA_di {\XINT_div_prepareA_e {0}}%
-\def\XINT_div_prepareA_dii {\XINT_div_prepareA_e {00}}%
-\def\XINT_div_prepareA_diii {\XINT_div_prepareA_e {000}}%
-% \end{macrocode}
-% \lverb|#1#3 = A préparé, #2 = longueur de ce A préparé, #4=K, #5={x'yx}->
-% LKAx'yxB«c»|
-% \begin{macrocode}
-\def\XINT_div_prepareA_e #1#2#3#4#5%
+\def\XINT_div_prepare_h #11.#2.#3#4#5#6%#7#8%
{%
- \XINT_div_start_a {#2}{#4}{#1#3}#5%
+ \XINT_div_start_a {#2}{#6}{#1}{#3}{#4}{#5}%{#7}{#8}%
}%
% \end{macrocode}
-% \lverb|L, K, A, x',y,x, B, «c» (avec y{}x{} au lieu de x'yxB dans la
-% variante little)|
+% \lverb|L, K, A, x',y,x, B, «c». Attention que K est diminué de 1 plus loin.
+% Comme xint 1.2 a déjà repéré K=1, on a ici au minimum K=2. Attention B est à
+% l'envers, A est à l'endroit et les deux avec séparateurs. Attention que ce
+% n'est pas ici qu'on boucle mais en \XINT_div_I_a.|
% \begin{macrocode}
\def\XINT_div_start_a #1#2%
{%
- \ifnum #2=\xint_c_iv \expandafter\XINT_div_little_b
+ \ifnum #1 < #2
+ \expandafter\XINT_div_zeroQ
\else
- \ifnum #1 < #2
- \expandafter\expandafter\expandafter\XINT_div_III_aa
- \else
- \expandafter\expandafter\expandafter\XINT_div_start_b
- \fi
+ \expandafter\XINT_div_start_b
\fi
{#1}{#2}%
}%
+\def\XINT_div_zeroQ #1#2#3#4#5#6#7%
+{%
+ \expandafter\XINT_div_zeroQ_end
+ \romannumeral0\XINT_unsep_cuzsmall
+ #31\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W .%
+}%
+\def\XINT_div_zeroQ_end #1.#2%
+ {\expandafter{\expandafter0\expandafter}\XINT_div_cleanR #1#2.}%
% \end{macrocode}
-% \lverb|L, K, A, x',y,x, B, «c».|
+% \lverb|L, K, A, x',y,x, B, «c»->K.A.x{LK{x'y}x}B«c»|
% \begin{macrocode}
-\def\XINT_div_III_aa #1#2#3#4#5#6#7%
+\def\XINT_div_start_b #1#2#3#4#5#6%
{%
- \expandafter\expandafter\expandafter
- \XINT_div_III_b\xint_cleanupzeros_nostop #3.{0000}%
+ \expandafter\XINT_div_finish\the\numexpr
+ \XINT_div_start_c {#2}.#3.{#6}{{#1}{#2}{{#4}{#5}}{#6}}%
}%
+\def\XINT_div_finish
+{%
+ \expandafter\XINT_div_finish_a \romannumeral-`0\XINT_div_unsepQ
+}%
+\def\XINT_div_finish_a #1\Z #2.{\XINT_div_finish_b #2.{#1}}%
% \end{macrocode}
-% \lverb|R.Q«c».|
+% \lverb|Ici ce sont routines de fin. Le reste déjà nettoyé. R.Q«c».|
% \begin{macrocode}
-\def\XINT_div_III_b #1%
+\def\XINT_div_finish_b #1%
{%
\if0#1%
- \expandafter\XINT_div_III_bRzero
+ \expandafter\XINT_div_finish_bRzero
\else
- \expandafter\XINT_div_III_bRpos
+ \expandafter\XINT_div_finish_bRpos
\fi
#1%
}%
-\def\XINT_div_III_bRzero 0.#1#2%
-{%
- \expandafter\space\expandafter
- {\romannumeral0\XINT_cuz_loop #1\W\W\W\W\W\W\W\Z}{0}%
-}%
-\def\XINT_div_III_bRpos #1.#2#3%
-{%
- \expandafter\XINT_div_III_c \XINT_div_cleanR #1#3.{#2}%
-}%
-\def\XINT_div_III_c #1#2%
-{%
- \expandafter\space\expandafter
- {\romannumeral0\XINT_cuz_loop #2\W\W\W\W\W\W\W\Z}{#1}%
+\def\XINT_div_finish_bRzero 0.#1#2{{#1}{0}}%
+\def\XINT_div_finish_bRpos #1.#2#3%
+{%
+ \expandafter\xint_exchangetwo_keepbraces\XINT_div_cleanR #1#3.{#2}%
}%
+\def\XINT_div_cleanR #100000000.{{#1}}%
% \end{macrocode}
-% \lverb|L, K, A, x',y,x, B, «c»->K.A.x{LK{x'y}x}B«c»|
+% \lverb|Kalpha.A.x{LK{x'y}x}, B, «c», au début #2=alpha est vide. On fait une
+% boucle pour prendre K unités de A (on a au moins L égal à K) et les mettre
+% dans alpha.|
% \begin{macrocode}
-\def\XINT_div_start_b #1#2#3#4#5#6%
+\def\XINT_div_start_c #1%
{%
- \XINT_div_start_c {#2}.#3.{#6}{{#1}{#2}{{#4}{#5}}{#6}}%
+ \ifnum #1>\xint_c_vi
+ \expandafter\XINT_div_start_ca
+ \else
+ \expandafter\XINT_div_start_cb
+ \fi {#1}%
}%
-% \end{macrocode}
-% \lverb|Kalpha.A.x{LK{x'y}x}, B, «c», au début #2=alpha est vide|
-% \begin{macrocode}
-\def\XINT_div_start_c #1#2.#3#4#5#6%
+\def\XINT_div_start_ca #1#2.#3!#4!#5!#6!#7!#8!#9!%
{%
- \ifnum #1=\xint_c_iv\XINT_div_start_ca\fi
\expandafter\XINT_div_start_c\expandafter
- {\the\numexpr #1-\xint_c_iv}#2#3#4#5#6.%
-}%
-\def\XINT_div_start_ca\fi\expandafter\XINT_div_start_c\expandafter
- #1#2#3#4#5{\fi\XINT_div_start_d {#2#3#4#5}#2#3#4#5}%
+ {\the\numexpr #1-\xint_c_vii}#2#3!#4!#5!#6!#7!#8!#9!.%
+}%
+\def\XINT_div_start_cb #1%
+ {\csname XINT_div_start_c_\romannumeral\numexpr#1\endcsname}%
+\def\XINT_div_start_c_i #1.#2!%
+ {\XINT_div_start_c_ #1#2!.}%
+\def\XINT_div_start_c_ii #1.#2!#3!%
+ {\XINT_div_start_c_ #1#2!#3!.}%
+\def\XINT_div_start_c_iii #1.#2!#3!#4!%
+ {\XINT_div_start_c_ #1#2!#3!#4!.}%
+\def\XINT_div_start_c_iv #1.#2!#3!#4!#5!%
+ {\XINT_div_start_c_ #1#2!#3!#4!#5!.}%
+\def\XINT_div_start_c_v #1.#2!#3!#4!#5!#6!%
+ {\XINT_div_start_c_ #1#2!#3!#4!#5!#6!.}%
+\def\XINT_div_start_c_vi #1.#2!#3!#4!#5!#6!#7!%
+ {\XINT_div_start_c_ #1#2!#3!#4!#5!#6!#7!.}%
% \end{macrocode}
% \lverb|#1=a, #2=alpha (de longueur K, à l'endroit).#3=reste de A.#4=x,
-% #5={LK{x'y}x},#6=B,«c» -> a, x, alpha, B, {0000}, L, K, {x'y},x,
-% alpha'=reste de A, B{}«c». Pour K=4 on a en fait B=x, faudra revoir après.|
+% #5={LK{x'y}x},#6=B,«c» -> a, x, alpha, B, {00000000}, L, K, {x'y},x,
+% alpha'=reste de A, B«c».|
% \begin{macrocode}
-\def\XINT_div_start_d #1#2.#3.#4#5#6%
+\def\XINT_div_start_c_ 1#1!#2.#3.#4#5#6%
{%
- \XINT_div_I_a {#1}{#4}{#2}{#6}{0000}#5{#3}{#6}{}%
+ \XINT_div_I_a {#1}{#4}{1#1!#2}{#6}{00000000}#5{#3}{#6}%
}%
% \end{macrocode}
% \lverb|Ceci est le point de retour de la boucle principale. a, x, alpha, B,
-% q0, L, K, {x'y}, x, alpha', BQ«c» |
+% q0, L, K, {x'y}, x, alpha', B«c» |
% \begin{macrocode}
\def\XINT_div_I_a #1#2%
{%
@@ -17554,17 +17399,17 @@ $1$ or $-1$.
\xint_gob_til_zero #1\XINT_div_I_czero 0\XINT_div_I_c #1%
}%
% \end{macrocode}
-% \lverb|On intercepte quotient nul: #1=a, x, alpha, B, #5=q0, L, K, {x'y}, x,
-% alpha', BQ«c» -> q{alpha} L, K, {x'y}, x, alpha', BQ«c»|
+% \lverb|On intercepte petit quotient nul: #1=a, x, alpha, B, #5=q0, L, K,
+% {x'y}, x, alpha', B«c» -> on lâche un q puis {alpha} L, K, {x'y}, x,
+% alpha', B«c».|
% \begin{macrocode}
-\def\XINT_div_I_czero 0%
- \XINT_div_I_c 0.#1#2#3#4#5{\XINT_div_I_g {#5}{#3}}%
+\def\XINT_div_I_czero 0\XINT_div_I_c 0.#1#2#3#4#5{1#5\XINT_div_I_g {#3}}%
\def\XINT_div_I_c #1.#2#3%
{%
- \expandafter\XINT_div_I_da\the\numexpr #2-#1*#3.#1.%
+ \expandafter\XINT_div_I_da\the\numexpr #2-#1*#3.#1.{#2}{#3}%
}%
% \end{macrocode}
-% \lverb|r.q.alpha, B, q0, L, K, {x'y}, x, alpha', BQ«c»|
+% \lverb|r.q.alpha, B, q0, L, K, {x'y}, x, alpha', B«c»|
% \begin{macrocode}
\def\XINT_div_I_da #1.%
{%
@@ -17578,413 +17423,451 @@ $1$ or $-1$.
\fi
\fi
}%
+% \end{macrocode}
+% \lverb|attention très mauvaises notations avec _b et _db.|
+% \begin{macrocode}
\def\XINT_div_I_dN #1.%
{%
- \expandafter\XINT_div_I_dP\the\numexpr #1-\xint_c_i.%
+ \expandafter\XINT_div_I_b\the\numexpr #1-\xint_c_i.%
}%
-\def\XINT_div_I_db #1.#2#3% #1=q=un chiffre, #2=alpha, #3=B
+\def\XINT_div_I_db #1.#2#3#4#5%
{%
- \expandafter\XINT_div_I_dc\expandafter
- {\romannumeral0\expandafter\XINT_div_sub_xpxp\expandafter
- {\romannumeral0\xintreverseorder{#2}}%
- {\romannumeral0\XINT_mul_Mr {#1}#3\Z\Z\Z\Z }}%
- #1{#2}{#3}%
+ \expandafter\XINT_div_I_dc\expandafter #1%
+ \romannumeral0\expandafter\XINT_div_sub\expandafter
+ {\romannumeral0\XINT_rev_nounsep {}#4\R!\R!\R!\R!\R!\R!\R!\R!\W}%
+ {\the\numexpr\XINT_div_verysmallmul #1!#51\Z!}%
+ \Z {#4}{#5}%
}%
+% \end{macrocode}
+% \lverb|La soustraction spéciale renvoie simplement - si le chiffre q est
+% trop grand. On invoque dans ce cas I_dP.|
+% \begin{macrocode}
\def\XINT_div_I_dc #1#2%
{%
- \if-#1% s'arranger pour que si n\'egatif on ait renvoy\'e alpha=-.
- \expandafter\xint_firstoftwo
- \else\expandafter\xint_secondoftwo\fi
- {\expandafter\XINT_div_I_dP\the\numexpr #2-\xint_c_i.}%
- {\XINT_div_I_e {#1}#2}%
+ \if-#2\expandafter\XINT_div_I_dd\else\expandafter\XINT_div_I_de\fi
+ #1#2%
}%
-% \end{macrocode}
-% \lverb|alpha,q,ancien alpha,B, q0->1nouveauq.alpha, L, K, {x'y},x, alpha',
-% BQ«c»|
-% \begin{macrocode}
-\def\XINT_div_I_e #1#2#3#4#5%
+\def\XINT_div_I_dd #1-\Z
{%
- \expandafter\XINT_div_I_f \the\numexpr \xint_c_x^iv+#2+#5{#1}%
+ \if #11\expandafter\XINT_div_I_dz\fi
+ \expandafter\XINT_div_I_dP\the\numexpr #1-\xint_c_i.XX%
}%
+\def\XINT_div_I_dz #1XX#2#3#4%
+{%
+ 1#4\XINT_div_I_g {#2}%
+}%
+\def\XINT_div_I_de #1#2\Z #3#4#5{1#5+#1\XINT_div_I_g {#2}}%
% \end{macrocode}
-% \lverb|q.alpha, B, q0, L, K, {x'y},x, alpha'BQ«c» (intercepter q=0?)
-% -> 1nouveauq.nouvel alpha, L, K, {x'y}, x, alpha',BQ«c»|
+% \lverb|q.alpha, B, q0, L, K, {x'y},x, alpha'B«c» (q=0 has been intercepted)
+% -> 1nouveauq.nouvel alpha, L, K, {x'y}, x, alpha',B«c»|
% \begin{macrocode}
-\def\XINT_div_I_dP #1.#2#3#4%
+\def\XINT_div_I_dP #1.#2#3#4#5#6%
{%
- \expandafter \XINT_div_I_f \the\numexpr \xint_c_x^iv+#1+#4\expandafter
- {\romannumeral0\expandafter\XINT_div_sub_xpxp\expandafter
- {\romannumeral0\xintreverseorder{#2}}%
- {\romannumeral0\XINT_mul_Mr {#1}#3\Z\Z\Z\Z }}%
+ 1#6+#1\expandafter\XINT_div_I_g\expandafter
+ {\romannumeral0\expandafter\XINT_div_sub\expandafter
+ {\romannumeral0\XINT_rev_nounsep {}#4\R!\R!\R!\R!\R!\R!\R!\R!\W}%
+ {\the\numexpr\XINT_div_verysmallmul #1!#51\Z!}%
+ }%
}%
% \end{macrocode}
-% \lverb|1#1#2#3#4=nouveau q, nouvel alpha, L, K, {x'y},x,alpha', BQ«c»|
+% \lverb|1#1=nouveau q. nouvel alpha, L, K, {x'y},x,alpha', BQ«c»|
% \begin{macrocode}
-\def\XINT_div_I_f 1#1#2#3#4{\XINT_div_I_g {#1#2#3#4}}%
% \end{macrocode}
% \lverb|#1=q,#2=nouvel alpha,#3=L, #4=K, #5={x'y}, #6=x, #7= alpha',#8=B,
-% #9=Q«c» -> {x'y}alpha.alpha'.{{x'y}xKL}B{Qq}«c»|
+% «c» -> on laisse q puis {x'y}alpha.alpha'.{{x'y}xKL}B«c»|
% \begin{macrocode}
-\def\XINT_div_I_g #1#2#3#4#5#6#7#8#9%
+\def\XINT_div_I_g #1#2#3#4#5#6#7%
{%
- \ifnum#3=#4
- \expandafter\XINT_div_III_ab
+ \expandafter !\the\numexpr
+ \ifnum#2=#3
+ \expandafter\XINT_div_exittofinish
\else
\expandafter\XINT_div_I_h
\fi
- {#5}#2.#7.{{#5}{#6}{#4}{#3}}{#8}{#9#1}%
+ {#4}#1.#6.{{#4}{#5}{#3}{#2}}{#7}%
}%
% \end{macrocode}
-% \lverb|{x'y}alpha.alpha'.{{x'y}xKL}B{Qq}«c» -> R sans leading zeros.{Qq}«c»|
+% \lverb|{x'y}alpha.alpha'.{{x'y}xKL}B«c» -> Attention retour à l'envoyeur ici
+% par terminaison des \the\numexpr. On doit reprendre le Q déjà sorti, qui n'a
+% plus de séparateurs, ni de leading 1. Ensuite R sans leading zeros.«c»|
% \begin{macrocode}
-\def\XINT_div_III_ab #1#2.#3.#4#5%
+\def\XINT_div_exittofinish #1#2.#3.#4#5%
{%
- \expandafter\XINT_div_III_b
- \romannumeral0\XINT_cuz_loop #2#3\W\W\W\W\W\W\W\Z.%
+ 1\expandafter\expandafter\expandafter!\expandafter\XINT_unsep_delim
+ \romannumeral0\XINT_div_unsepR #2#31\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W.%
}%
% \end{macrocode}
-% \lverb|#1={x'y}alpha.#2#3#4#5#6=reste de A.
-% #7={{x'y},x,K,L},#8=B,nouveauQ«c» devient {x'y},alpha sur K+4 chiffres.B,
-% {{x'y},x,K,L}, #6= nouvel alpha',B,nouveauQ«c»|
+% \lverb|#1={x'y}alpha.#2!#3=reste de A.
+% #4={{x'y},x,K,L},#5=B,«c» devient {x'y},alpha sur K+4 chiffres.B,
+% {{x'y},x,K,L}, #6= nouvel alpha',B,«c»|
% \begin{macrocode}
-\def\XINT_div_I_h #1.#2#3#4#5#6.#7#8%
+\def\XINT_div_I_h #1.#2!#3.#4#5%
{%
- \XINT_div_II_b #1#2#3#4#5.{#8}{#7}{#6}{#8}%
+ \XINT_div_II_b #1#2!.{#5}{#4}{#3}{#5}%
}%
% \end{macrocode}
-% \lverb|{x'y}alpha.B, {{x'y},x,K,L}, nouveau alpha',B, Q«c» On
-% intercepte la situation avec alpha débutant par 0000 qui est la seule qui
-% pourrait donner un q1 nul. Donc q1 est non nul et la soustraction spéciale
-% recevra un q1*B de longueur K ou K+4 et jamais 0000. Ensuite un q2 éventuel
-% s'il est calculé est nécessairement non nul lui aussi. Comme dans la phase I
-% on a aussi intercepté un q nul, la soustraction spéciale ne reçoit donc jamais
-% un qB nul. Note: j'ai testé plusieurs fois que ma technique de gob_til_zeros
-% est plus rapide que d'utiliser un \ifnum |
+% \lverb|{x'y}alpha.B, {{x'y},x,K,L}, nouveau alpha',B,«c»|
% \begin{macrocode}
-\def\XINT_div_II_b #1#2#3#4#5#6#7#8#9%
+\def\XINT_div_II_b #11#2!#3!%
{%
- \xint_gob_til_zeros_iv #2#3#4#5\XINT_div_II_skipc 0000%
- \XINT_div_II_c #1{#2#3#4#5}{#6#7#8#9}%
+ \xint_gob_til_eightzeroes #2\XINT_div_II_skipc 00000000%
+ \XINT_div_II_c #1{1#2}{#3}%
}%
% \end{macrocode}
-% \lverb|x'y{0000}{4chiffres}reste de alpha.#6=B,#7={{x'y},x,K,L}, alpha',B,
-% Q«c» -> {x'y}x,K,L (à diminuer de 4), {alpha sur
-% K}B{q1=0000}{alpha'}B,Q«c»|
+% \lverb|x'y{100000000}{1<8>}reste de alpha.#6=B,#7={{x'y},x,K,L}, alpha',B,
+% «c» -> {x'y}x,K,L (à diminuer de 4), {alpha sur
+% K}B{q1=00000000}{alpha'}B,«c»|
% \begin{macrocode}
-\def\XINT_div_II_skipc 0000\XINT_div_II_c #1#2#3#4#5.#6#7%
+\def\XINT_div_II_skipc 00000000\XINT_div_II_c #1#2#3#4#5.#6#7%
{%
- \XINT_div_II_k #7{#4#5}{#6}{0000}%
+ \XINT_div_II_k #7{#4!#5}{#6}{00000000}%
}%
% \end{macrocode}
-% \lverb|x'ya->1qx'yalpha.B, {{x'y},x,K,L}, nouveau alpha',B, Q«c»|
+% \lverb|x'ya->1qx'yalpha.B, {{x'y},x,K,L}, nouveau alpha',B, «c».|
% \begin{macrocode}
\def\XINT_div_II_c #1#2#3#4%
{%
- \expandafter\XINT_div_II_d\the\numexpr (#3#4+#2)/#1+\xint_c_ixixixix\relax
- {#1}{#2}#3#4%
+ \expandafter\XINT_div_II_d\the\numexpr\XINT_div_mini
+ #1.#2!#3!#4!{#1}{#2}#3!#4!%
}%
% \end{macrocode}
-% \lverb|1 suivi de q1 sur quatre chiffres, #5=x', #6=y, #7=alpha.#8=B,
-% {{x'y},x,K,L}, alpha', B, Q«c» --> nouvel alpha.x',y,B,q1,{{x'y},x,K,L},
-% alpha', B, Q«c» |
+% \lverb|1 suivi de q1 sur huit chiffres! #2=x', #3=y, #4=alpha.#5=B,
+% {{x'y},x,K,L}, alpha', B, «c» --> nouvel alpha.x',y,B,q1,{{x'y},x,K,L},
+% alpha', B, «c» |
% \begin{macrocode}
-\def\XINT_div_II_d 1#1#2#3#4#5#6#7.#8%
+\def\XINT_div_II_d 1#1#2#3#4#5!#6#7#8.#9%
{%
\expandafter\XINT_div_II_e
- \romannumeral0\expandafter\XINT_div_sub_xpxp\expandafter
- {\romannumeral0\xintreverseorder{#7}}%
- {\romannumeral0\XINT_mul_Mr {#1#2#3#4}#8\Z\Z\Z\Z }.%
- {#5}{#6}{#8}{#1#2#3#4}%
+ \romannumeral0\expandafter\XINT_div_sub\expandafter
+ {\romannumeral0\XINT_rev_nounsep {}#8\R!\R!\R!\R!\R!\R!\R!\R!\W}%
+ {\the\numexpr\XINT_div_smallmul_a 100000000.#1#2#3#4.#5!#91\Z!}%
+ .{#6}{#7}{#9}{#1#2#3#4#5}%
}%
% \end{macrocode}
-% \lverb|alpha.x',y,B,q1, {{x'y},x,K,L}, alpha', B, Q«c»|
+% \lverb|alpha.x',y,B,q1, {{x'y},x,K,L}, alpha', B, «c». Attention la
+% soustraction spéciale doit maintenir les blocs 1<8>!|
% \begin{macrocode}
-\def\XINT_div_II_e #1#2#3#4%
+\def\XINT_div_II_e 1#1!%
{%
- \xint_gob_til_zeros_iv #1#2#3#4\XINT_div_II_skipf 0000%
- \XINT_div_II_f #1#2#3#4%
+ \xint_gob_til_eightzeroes #1\XINT_div_II_skipf 00000000%
+ \XINT_div_II_f 1#1!%
}%
% \end{macrocode}
-% \lverb|0000alpha sur K chiffres.#2=x',#3=y,#4=B,#5=q1, #6={{x'y},x,K,L},
-% #7=alpha',BQ«c» -> {x'y}x,K,L (à diminuer de 4),
-% {alpha sur K}B{q1}{alpha'}BQ«c»|
+% \lverb|100000000!alpha sur K chiffres.#2=x',#3=y,#4=B,#5=q1, #6={{x'y},x,K,L},
+% #7=alpha',B«c» -> {x'y}x,K,L (à diminuer de 1),
+% {alpha sur K}B{q1}{alpha'}B«c»|
% \begin{macrocode}
-\def\XINT_div_II_skipf 0000\XINT_div_II_f 0000#1.#2#3#4#5#6%
+\def\XINT_div_II_skipf 00000000\XINT_div_II_f 100000000!#1.#2#3#4#5#6%
{%
\XINT_div_II_k #6{#1}{#4}{#5}%
}%
% \end{macrocode}
-% \lverb|a1 (huit chiffres), alpha (sur K+4), x', y, B, q1, {{x'y},x,K,L},
-% alpha', B,Q«c»|
+% \lverb|1<a1>!1<a2>!, alpha (sur K+1 blocs de 8). x', y, B, q1, {{x'y},x,K,L},
+% alpha', B,«c».|
% \begin{macrocode}
-\def\XINT_div_II_f #1#2#3#4#5#6#7#8#9.%
+\def\XINT_div_II_f #1!#2!#3.%
{%
- \XINT_div_II_fa {#1#2#3#4#5#6#7#8}{#1#2#3#4#5#6#7#8#9}%
+ \XINT_div_II_fa {#1!#2!}{#1!#2!#3}%
}%
\def\XINT_div_II_fa #1#2#3#4%
{%
- \expandafter\XINT_div_II_g\expandafter
- {\the\numexpr (#1+#4)/#3-\xint_c_i}{#2}%
+ \expandafter\XINT_div_II_g \the\numexpr\XINT_div_mini #3.#4!#1{#2}%
}%
% \end{macrocode}
% \lverb|#1=q, #2=alpha (K+4), #3=B, #4=q1, {{x'y},x,K,L}, alpha', BQ«c»
-% -> 1 puis nouveau q sur 4 chiffres, nouvel alpha sur K chiffres,
-% B, {{x'y},x,K,L}, alpha',BQ«c» |
+% -> 1 puis nouveau q sur 8 chiffres. nouvel alpha sur K blocs,
+% B, {{x'y},x,K,L}, alpha',B«c» |
% \begin{macrocode}
-\def\XINT_div_II_g #1#2#3#4%
+\def\XINT_div_II_g 1#1#2#3#4#5!#6#7#8%
{%
\expandafter \XINT_div_II_h
- \the\numexpr #4+#1+\xint_c_x^iv\expandafter\expandafter\expandafter
- {\expandafter\xint_gobble_iv
- \romannumeral0\expandafter\XINT_div_sub_xpxp\expandafter
- {\romannumeral0\xintreverseorder{#2}}%
- {\romannumeral0\XINT_mul_Mr {#1}#3\Z\Z\Z\Z }}{#3}%
+ \the\numexpr 1#1#2#3#4#5+#8\expandafter\expandafter\expandafter
+ .\expandafter\expandafter\expandafter
+ {\expandafter\xint_gob_til_exclam
+ \romannumeral0\expandafter\XINT_div_sub\expandafter
+ {\romannumeral0\XINT_rev_nounsep {}#6\R!\R!\R!\R!\R!\R!\R!\R!\W}%
+ {\the\numexpr\XINT_div_smallmul_a 100000000.#1#2#3#4.#5!#71\Z!}}%
+ {#7}%
}%
% \end{macrocode}
-% \lverb|1 puis nouveau q sur 4 chiffres, #5=nouvel alpha sur K chiffres,
-% #6=B, #7={{x'y},x,K,L} avec L à ajuster, alpha', BQ«c»
-% -> {x'y}x,K,L à diminuer de 4, {alpha}B{q}, alpha', BQ«c»|
+% \lverb|1 puis nouveau q sur 8 chiffres, #2=nouvel alpha sur K blocs,
+% #3=B, #4={{x'y},x,K,L} avec L à ajuster, alpha', BQ«c»
+% -> {x'y}x,K,L à diminuer de 1, {alpha}B{q}, alpha', BQ«c»|
% \begin{macrocode}
-\def\XINT_div_II_h 1#1#2#3#4#5#6#7%
+\def\XINT_div_II_h 1#1.#2#3#4%
{%
- \XINT_div_II_k #7{#5}{#6}{#1#2#3#4}%
+ \XINT_div_II_k #4{#2}{#3}{#1}%
}%
% \end{macrocode}
-% \lverb|{x'y}x,K,L à diminuer de 4, alpha, B{q}alpha',BQ«c»
-% ->nouveau L.K,x',y,x,alpha.B,q,alpha',B,Q«c»
-% ->{LK{x'y}x},x,a,alpha.B,q,alpha',B,Q«c»|
+% \lverb|{x'y}x,K,L à diminuer de 1, alpha, B{q}alpha',B«c»
+% ->nouveau L.K,x',y,x,alpha.B,q,alpha',B,«c»
+% ->{LK{x'y}x},x,a,alpha.B,q,alpha',B,«c»|
% \begin{macrocode}
\def\XINT_div_II_k #1#2#3#4#5%
{%
- \expandafter\XINT_div_II_l \the\numexpr #4-\xint_c_iv.{#3}#1{#2}#5.%
+ \expandafter\XINT_div_II_l \the\numexpr #4-\xint_c_i.{#3}#1{#2}#5.%
}%
-\def\XINT_div_II_l #1.#2#3#4#5#6#7#8#9%
+\def\XINT_div_II_l #1.#2#3#4#51#6!%
{%
- \XINT_div_II_m {{#1}{#2}{{#3}{#4}}{#5}}{#5}{#6#7#8#9}#6#7#8#9%
+ \XINT_div_II_m {{#1}{#2}{{#3}{#4}}{#5}}{#5}{#6}1#6!%
}%
% \end{macrocode}
-% \lverb|{LK{x'y}x},x,a,alpha.B{q}alpha'BQ -> a, x, alpha, B, q,
-% L, K, {x'y}, x, alpha', BQ«c» |
+% \lverb|{LK{x'y}x},x,a,alpha.B{q}alpha'B -> a, x, alpha, B, q,
+% L, K, {x'y}, x, alpha', B«c» |
% \begin{macrocode}
\def\XINT_div_II_m #1#2#3#4.#5#6%
{%
\XINT_div_I_a {#3}{#2}{#4}{#5}{#6}#1%
}%
% \end{macrocode}
-% \lverb|L, K, A, y,{},x, {},«c»->A.{yx}L{}«c» Comme ici K=4, dans
-% la phase I on n'a pas besoin de alpha, car a = alpha. De plus on a maintenu B
-% dans l'ordre qui est donc la même chose que x. Par ailleurs la phase I est
-% simplifiée, il s'agit simplement de la division euclidienne de a par x, et de
-% plus on n'a à la faire qu'une unique fois et ensuite la phase II peut boucler
-% sur elle-même au lieu de revenir en phase I, par conséquent il n'y a pas non
-% plus de q0 ici. Enfin, le y est (x/2) pas ((x+1)/2) il n'y a pas de x'=x+1|
+% \lverb|This multiplication is exactly like \XINT_smallmul, but it always
+% keeps the ending carry. For optimization I duplicated the whole code.|
% \begin{macrocode}
-\def\XINT_div_little_b #1#2#3#4#5#6#7%
+\def\XINT_div_minimulwc_a 1#1.#2.#3!#4#5#6#7#8.%
{%
- \XINT_div_little_c #3.{{#4}{#6}}{#1}%
+ \expandafter\XINT_div_minimulwc_b
+ \the\numexpr \xint_c_x^ix+#1+#3*#8.#3*#4#5#6#7+#2*#8.#2*#4#5#6#7.%
}%
-% \end{macrocode}
-% \lverb|#1#2#3#4=a, #5=alpha'=reste de A.#6={yx}, #7=L, «c» -> a,
-% y, x, L, alpha'=reste de A, «c».|
-% \begin{macrocode}
-\def\XINT_div_little_c #1#2#3#4#5.#6#7%
+\def\XINT_div_minimulwc_b 1#1#2#3#4#5#6.#7.%
+{%
+ \expandafter\XINT_div_minimulwc_c
+ \the\numexpr \xint_c_x^ix+#1#2#3#4#5+#7.#6.%
+}%
+\def\XINT_div_minimulwc_c 1#1#2#3#4#5#6.#7.#8.%
+{%
+ 1#6#7\expandafter!%
+ \the\numexpr\expandafter\XINT_div_smallmul_a
+ \the\numexpr \xint_c_x^viii+#1#2#3#4#5+#8.%
+}%
+\def\XINT_div_smallmul_a #1.#2.#3!1#4!%
{%
- \XINT_div_littleI_a {#1#2#3#4}#6{#7}{#5}%
+ \xint_gob_til_Z #4\XINT_div_smallmul_e\Z
+ \XINT_div_minimulwc_a #1.#2.#3!#4.#2.#3!%
}%
+\def\XINT_div_smallmul_e\Z\XINT_div_minimulwc_a 1#1.#2\Z #3!{1\relax #1!}%
% \end{macrocode}
-% \lverb|a, y, x, L, alpha',«c» On calcule ici (contrairement à la
-% phase I générale) le vrai quotient euclidien de a par x=B, c'est donc un
-% chiffre de 0 à 9. De plus on n'a à faire cela qu'une unique fois.|
+% \lverb|Special very small multiplication for division. We only need to cater
+% for multiplicands from 1 to 9. The ending is different from standard
+% verysmallmul, a zero carry is not suppressed. And no final 1\Z! is added. If
+% #1=1 let's not forget to add the 100000000! at the end.|
% \begin{macrocode}
-\def\XINT_div_littleI_a #1#2#3%
+\def\XINT_div_verysmallmul #1%
+ {\xint_gob_til_one #1\XINT_div_verysmallisone 1\XINT_div_verysmallmul_a 0.#1}%
+\def\XINT_div_verysmallisone 1\XINT_div_verysmallmul_a 0.1!1#11\Z!%
+ {1\relax #1100000000!}%
+\def\XINT_div_verysmallmul_a #1.#2!1#3!%
{%
- \expandafter\XINT_div_littleI_b
- \the\numexpr (#1+#2)/#3-\xint_c_i{#1}{#2}{#3}%
+ \xint_gob_til_Z #3\XINT_div_verysmallmul_e\Z
+ \expandafter\XINT_div_verysmallmul_b
+ \the\numexpr \xint_c_x^ix+#2*#3+#1.#2!%
}%
+\def\XINT_div_verysmallmul_b 1#1#2.%
+ {1#2\expandafter!\the\numexpr\XINT_div_verysmallmul_a #1.}%
+\def\XINT_div_verysmallmul_e\Z #1\Z +#2#3!{1\relax 0000000#2!}%
% \end{macrocode}
-% \lverb|On intercepte quotient nul: [est-ce vraiment utile? ou n'est-ce pas
-% plutôt une perte de temps en moyenne? il faudrait tester] q=0#1=a,
-% #2=y, x, L, alpha', «c» ->
-% II_a avec L{alpha}alpha'.{yx}{0000}«c». Et en cas de quotient non nul on
-% procède avec littleI_c avec #1=q, #2=a, #3=y, #4=x -> {nouvel alpha sur 4
-% chiffres}q{yx},L,alpha',«c».|
+% \lverb|Special subtraction for division purposes.|
% \begin{macrocode}
-\def\XINT_div_littleI_b #1%
+\def\XINT_div_sub #1#2%
{%
- \xint_gob_til_zero #1\XINT_div_littleI_skip 0\XINT_div_littleI_c #1%
+ \expandafter\XINT_div_sub_clean
+ \the\numexpr\expandafter\XINT_div_sub_a\expandafter
+ 1#2\Z!\Z!\Z!\Z!\Z!\W #1\Z!\Z!\Z!\Z!\Z!\W
}%
-\def\XINT_div_littleI_skip 0\XINT_div_littleI_c 0#1#2#3#4#5%
- {\XINT_div_littleII_a {#4}{#1}#5.{{#2}{#3}}{0000}}%
-\def\XINT_div_littleI_c #1#2#3#4%
+\def\XINT_div_sub_clean #1-#2#3\W
{%
- \expandafter\expandafter\expandafter\XINT_div_littleI_e
- \expandafter\expandafter\expandafter
- {\expandafter\xint_gobble_i\the\numexpr \xint_c_x^iv+#2-#1*#4}#1{{#3}{#4}}%
+ \if1#2\expandafter\XINT_rev_nounsep\else\expandafter\XINT_div_sub_neg\fi
+ {}#1\R!\R!\R!\R!\R!\R!\R!\R!\W
}%
-% \end{macrocode}
-% \lverb|#1=nouvel alpha sur 4 chiffres#2=q,#3={yx}, #4=L, #5=alpha',«c» ->
-% L{alpha}alpha'.{yx}{000q}«c» point d'entrée de la boucle principale|
-% \begin{macrocode}
-\def\XINT_div_littleI_e #1#2#3#4#5%
- {\XINT_div_littleII_a {#4}{#1}#5.{#3}{000#2}}%
-% \end{macrocode}
-% \lverb|L{alpha}alpha'.{yx}Q«c» et c'est là qu'on boucle|
-% \begin{macrocode}
-\def\XINT_div_littleII_a #1%
+\def\XINT_div_sub_neg #1\W { -}%
+\def\XINT_div_sub_a #1!#2!#3!#4!#5\W #6!#7!#8!#9!%
{%
- \ifnum#1=\xint_c_iv
- \expandafter\XINT_div_littleIII_ab
- \else
- \expandafter\XINT_div_littleII_b
- \fi {#1}%
+ \XINT_div_sub_b #1!#6!#2!#7!#3!#8!#4!#9!#5\W
}%
-% \end{macrocode}
-% \lverb|L{alpha}alpha'.{yx}Q«c» -> (en fait #3 est vide normalement ici) R
-% sans leading zeros.Q«c»|
-% \begin{macrocode}
-\def\XINT_div_littleIII_ab #1#2#3.#4%
+\def\XINT_div_sub_b #1#2#3!#4!%
{%
- \expandafter\XINT_div_III_b\the\numexpr #2#3.%
+ \xint_gob_til_Z #4\XINT_div_sub_bi \Z
+ \expandafter\XINT_div_sub_c\the\numexpr#1-#3+1#4-\xint_c_i.%
}%
-% \end{macrocode}
-% \lverb|L{alpha}alpha'.{yx}Q«c». On diminue L de quatre, comme cela c'est
-% fait.|
-% \begin{macrocode}
-\def\XINT_div_littleII_b #1%
+\def\XINT_div_sub_c 1#1#2.%
{%
- \expandafter\XINT_div_littleII_c\expandafter {\the\numexpr #1-\xint_c_iv}%
+ 1#2\expandafter!\the\numexpr\XINT_div_sub_d #1%
}%
-% \end{macrocode}
-% \lverb|{nouveauL}{alpha}alpha'.{yx}Q«c». On prélève 4 chiffres de alpha' ->
-% {nouvel alpha sur huit chiffres}yx{nouveau L}{nouvel alpha'}Q«c». Regarder
-% si l'ancien alpha était 0000 n'avancerait à rien car obligerait à refaire une
-% chose comme la phase I, donc on ne perd pas de temps avec ça, on reste en
-% permanence en phase II.|
-% \begin{macrocode}
-\def\XINT_div_littleII_c #1#2#3#4#5#6#7.#8%
+\def\XINT_div_sub_d #1#2#3!#4!%
{%
- \XINT_div_littleII_d {#2#3#4#5#6}#8{#1}{#7}%
+ \xint_gob_til_Z #4\XINT_div_sub_di \Z
+ \expandafter\XINT_div_sub_e\the\numexpr#1-#3+1#4-\xint_c_i.%
}%
-\def\XINT_div_littleII_d #1#2#3%
+\def\XINT_div_sub_e 1#1#2.%
{%
- \expandafter\XINT_div_littleII_e\the\numexpr (#1+#2)/#3+\xint_c_ixixixix.%
- {#1}{#2}{#3}%
+ 1#2\expandafter!\the\numexpr\XINT_div_sub_f #1%
}%
-% \end{macrocode}
-% \lverb|1 suivi de #1=q1 sur quatre chiffres.#2=alpha, #3=y, #4=x,
-% L, alpha', Q«c» --> nouvel alpha sur 4.{q1}{yx},L,alpha', Q«c» |
-% \begin{macrocode}
-\def\XINT_div_littleII_e 1#1.#2#3#4%
+\def\XINT_div_sub_f #1#2#3!#4!%
{%
- \expandafter\expandafter\expandafter\XINT_div_littleII_f
- \expandafter\xint_gobble_i\the\numexpr \xint_c_x^iv+#2-#1*#4.%
- {#1}{{#3}{#4}}%
+ \xint_gob_til_Z #4\XINT_div_sub_fi \Z
+ \expandafter\XINT_div_sub_g\the\numexpr#1-#3+1#4-\xint_c_i.%
}%
-% \end{macrocode}
-% \lverb|alpha.q,{yx},L,alpha',Q«c»->L{alpha}alpha'.{yx}{Qq}«c»|
-% \begin{macrocode}
-\def\XINT_div_littleII_f #1.#2#3#4#5#6%
+\def\XINT_div_sub_g 1#1#2.%
{%
- \XINT_div_littleII_a {#4}{#1}#5.{#3}{#6#2}%
+ 1#2\expandafter!\the\numexpr\XINT_div_sub_h #1%
}%
-% \end{macrocode}
-% \lverb|La soustraction spéciale. Dans 1.09j, elle fait A-qB, pour A (en fait
-% alpha dans mes dénominations des commentaires du code) et qB chacun de
-% longueur K ou K+4, avec K au moins huit multiple de quatre, qB a ses quatre
-% chiffres significatifs (qui sont à droite) non nuls. Si A-qB<0 il suffit de
-% renvoyer -, le résultat n'importe pas. On est sûr que qB est non nul. On le
-% met dans cette version en premier pour tester plus facilement le cas avec qB
-% de longueur K+4 et A de longueur seulement K. Lorsque la longueur de qB est
-% inférieure ou égale à celle de A, on va jusqu'à la fin de A et donc c'est la
-% retenue finale qui décide du cas négatif éventuel. Le résultat non négatif est
-% toujours donc renvoyé avec la même longueur que A, et il est dans l'ordre.
-% J'ai fait une implémentation des phases I et II en maintenant alpha toujours à
-% l'envers afin d'éviter le reverse order systématique fait sur A (ou plutôt
-% alpha), mais alors il fallait que la soustraction ici s'arrange pour repérer
-% les huit chiffres les plus significatifs, au final ce n'était pas plus rapide,
-% et même pénalisant pour de gros inputs. Dans les versions 1.09i et antérieures
-% (en fait je pense qu'ici rien quasiment n'avait bougé depuis la première
-% implémentation), la soustraction spéciale n'était pratiquée que dans des cas
-% avec certainement A-qB positif ou nul. De plus on n'excluait pas q=0, donc il
-% fallait aussi faire un éventuel reverseorder sur ce qui était encore non
-% traité. Les cas avec q=0 sont maintenant interceptés en amont et comme A et qB
-% ont toujours quasiment la même longueur on ne s'embarrasse pas de
-% complications pour la fin.|
-% \begin{macrocode}
-\def\XINT_div_sub_xpxp #1#2% #1=alpha d\'ej\`a renvers\'e, #2 se d\'eveloppe en qB
+\def\XINT_div_sub_h #1#2#3!#4!%
{%
- \expandafter\XINT_div_sub_xpxp_b #2\W\X\Y\Z #1\W\X\Y\Z
+ \xint_gob_til_Z #4\XINT_div_sub_hi \Z
+ \expandafter\XINT_div_sub_i\the\numexpr#1-#3+1#4-\xint_c_i.%
}%
-\def\XINT_div_sub_xpxp_b
+\def\XINT_div_sub_i 1#1#2.%
{%
- \XINT_div_sub_A 1{}%
+ 1#2\expandafter!\the\numexpr\XINT_div_sub_a #1%
}%
-\def\XINT_div_sub_A #1#2#3#4#5#6%
+\def\XINT_div_sub_bi\Z
+ \expandafter\XINT_div_sub_c\the\numexpr#1-#2+#3.#4!#5!#6!#7!#8!#9!\Z !\W
{%
- \xint_gob_til_W #3\xint_div_sub_az\W
- \XINT_div_sub_B #1{#3#4#5#6}{#2}%
+ \XINT_div_sub_l #1#2!#5!#7!#9!%
}%
-\def\XINT_div_sub_B #1#2#3#4\W\X\Y\Z #5#6#7#8%
+\def\XINT_div_sub_di\Z
+ \expandafter\XINT_div_sub_e\the\numexpr#1-#2+#3.#4!#5!#6!#7!#8\W
{%
- \xint_gob_til_W #5\xint_div_sub_bz\W
- \XINT_div_sub_onestep #1#2{#8#7#6#5}{#3}#4\W\X\Y\Z
+ \XINT_div_sub_l #1#2!#5!#7!%
}%
-\def\XINT_div_sub_onestep #1#2#3#4#5#6%
+\def\XINT_div_sub_fi\Z
+ \expandafter\XINT_div_sub_g\the\numexpr#1-#2+#3.#4!#5!#6\W
{%
- \expandafter\XINT_div_sub_backtoA
- \the\numexpr 11#6-#5#4#3#2+#1-\xint_c_i.%
+ \XINT_div_sub_l #1#2!#5!%
}%
-\def\XINT_div_sub_backtoA #1#2#3.#4%
+\def\XINT_div_sub_hi\Z
+ \expandafter\XINT_div_sub_i\the\numexpr#1-#2+#3.#4\W
{%
- \XINT_div_sub_A #2{#3#4}%
+ \XINT_div_sub_l #1#2!%
}%
-% \end{macrocode}
-% \lverb|si on arrive en sub_bz c'est que qB était de longueur K+4 et A
-% seulement de longueur K, le résultat est donc < 0, renvoyer juste -|
-% \begin{macrocode}
-\def\xint_div_sub_bz\W\XINT_div_sub_onestep #1\Z { -}%
-% \end{macrocode}
-% \lverb|si on arrive en sub_az c'est que qB était de longueur inférieure ou
-% égale à celle de A, donc on continue jusqu'à la fin de A, et on vérifiera la
-% retenue à la fin.|
-% \begin{macrocode}
-\def\xint_div_sub_az\W\XINT_div_sub_B #1#2{\XINT_div_sub_C #1}%
-\def\XINT_div_sub_C #1#2#3#4#5#6%
+\def\XINT_div_sub_l #1%
{%
- \xint_gob_til_W #3\xint_div_sub_cz\W
- \XINT_div_sub_C_onestep #1{#6#5#4#3}{#2}%
+ \xint_UDzerofork
+ #1{-2\relax}%
+ 0\XINT_div_sub_r
+ \krof
}%
-\def\XINT_div_sub_C_onestep #1#2%
+\def\XINT_div_sub_r #1!%
{%
- \expandafter\XINT_div_sub_backtoC \the\numexpr 11#2+#1-\xint_c_i.%
+ -\ifnum 0#1=\xint_c_ 1\else2\fi\relax
}%
-\def\XINT_div_sub_backtoC #1#2#3.#4%
+%%%%%%%%%%%%
+\def\XINT_sdiv_out #1\Z #2\W%
+ {\expandafter
+ {\romannumeral0\XINT_unsep_cuzsmall#11\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W}%
+ {#2}}%
+\def\XINT_smalldivx_a #1.1#2!1#3!%
{%
- \XINT_div_sub_C #2{#3#4}%
+ \expandafter\XINT_smalldivx_b
+ \the\numexpr (#3+#1)/#2-\xint_c_i!#1.#2!#3!%
+}%
+\def\XINT_smalldivx_b #1!%
+{%
+ \if0#1\else
+ \xint_c_x^viii+#1\xint_afterfi{\expandafter!\the\numexpr}\fi
+ \XINT_smalldiv_c #1!%
+}%
+\def\XINT_smalldiv_c #1!#2.#3!#4!%
+{%
+ \expandafter\XINT_smalldiv_d\the\numexpr #4-#1*#3!#2.#3!%
+}%
+\def\XINT_smalldiv_d #1!#2!#3#4!%
+{%
+ \xint_gob_til_Z #4\XINT_smalldiv_end \Z
+ \XINT_smalldiv_e #1!#2!#3#4!%
+}%
+\def\XINT_smalldiv_end\Z\XINT_smalldiv_e #1!#2!1\Z!{1!\Z #1\W }%
+\def\XINT_smalldiv_e #1!#2.#3!%
+{%
+ \expandafter\XINT_smalldiv_f\the\numexpr
+ \xint_c_xi_e_viii_mone+#1*\xint_c_x^viii/#3!#2.#3!#1!%
+}%
+\def\XINT_smalldiv_f 1#1#2#3#4#5#6!#7.#8!%
+{%
+ \xint_gob_til_zero #1\XINT_smalldiv_fz 0%
+ \expandafter\XINT_smalldiv_g
+ \the\numexpr\XINT_minimul_a #2#3#4#5.#6!#8!#2#3#4#5#6!#7.#8!%
+}%
+\def\XINT_smalldiv_fz 0%
+ \expandafter\XINT_smalldiv_g\the\numexpr\XINT_minimul_a
+ 9999.9999!#1!99999999!#2!0!1#3!%
+{%
+ \XINT_smalldiv_i .#3!\xint_c_!#2!%
+}%
+\def\XINT_smalldiv_g 1#1!1#2!#3!#4!#5!#6!%
+{%
+ \expandafter\XINT_smalldiv_h
+ \the\numexpr 1#6-#1.#2!#5!#3!#4!%
+}%
+\def\XINT_smalldiv_h 1#1#2.#3!#4!%
+{%
+ \expandafter\XINT_smalldiv_i
+ \the\numexpr #4-#3+#1-\xint_c_i.#2!%
+}%
+\def\XINT_smalldiv_i #1.#2!#3!#4.#5!%
+{%
+ \expandafter\XINT_smalldiv_j
+ \the\numexpr (#1#2+#4)/#5-\xint_c_i!#3!#1#2!#4.#5!%
+}%
+\def\XINT_smalldiv_j #1!#2!%
+{%
+ \xint_c_x^viii+#1+#2\expandafter!\the\numexpr\XINT_smalldiv_k
+ #1!%
+}%
+\def\XINT_smalldiv_k #1!#2!#3.#4!%
+{%
+ \expandafter\XINT_smalldiv_d\the\numexpr #2-#1*#4!#3.#4!%
+}%
+%%%%%%%%%%%%
+\def\XINT_div_mini #1.#2!1#3!%
+{%
+ \expandafter\XINT_div_mini_a\the\numexpr
+ \xint_c_xi_e_viii_mone+#3*\xint_c_x^viii/#1!#1.#2!#3!%
}%
% \end{macrocode}
-% \lverb|une fois arrivé en sub_cz on teste la retenue pour voir si le résultat
-% final est en fait négatif, dans ce cas on renvoie seulement -|
+% \lverb|Note (2015/10/08). Attention à la différence dans l'ordre des
+% arguments avec ce que je vois en comparaison avec \XINT_smalldiv_f. Je ne me
+% souviens plus du tout s'il y a une raison quelconque.|
% \begin{macrocode}
-\def\xint_div_sub_cz\W\XINT_div_sub_C_onestep #1#2%
+\def\XINT_div_mini_a 1#1#2#3#4#5#6!#7.#8!%
{%
- \if#10% retenue
- \expandafter\xint_div_sub_neg
- \else\expandafter\xint_div_sub_ok
- \fi
+ \xint_gob_til_zero #1\XINT_div_mini_w 0%
+ \expandafter\XINT_div_mini_b
+ \the\numexpr\XINT_minimul_a #2#3#4#5.#6!#7!#2#3#4#5#6!#7.#8!%
+}%
+\def\XINT_div_mini_w 0%
+ \expandafter\XINT_div_mini_b\the\numexpr\XINT_minimul_a
+ 9999.9999!#1!99999999!#2.#3!00000000!#4!%
+{%
+ \xint_c_x^viii_mone+(#4+#3)/#2!%
+}%
+\def\XINT_div_mini_b 1#1!1#2!#3!#4!#5!#6!%
+{%
+ \expandafter\XINT_div_mini_c
+ \the\numexpr 1#6-#1.#2!#5!#3!#4!%
+}%
+\def\XINT_div_mini_c 1#1#2.#3!#4!%
+{%
+ \expandafter\XINT_div_mini_d
+ \the\numexpr #4-#3+#1-\xint_c_i.#2!%
+}%
+\def\XINT_div_mini_d #1.#2!#3!#4.#5!%
+{%
+ \xint_c_x^viii_mone+#3+(#1#2+#5)/#4!%
}%
-\def\xint_div_sub_neg #1{ -}%
-\def\xint_div_sub_ok #1{ #1}%
% \end{macrocode}
% \subsection{\csh{xintiDivRound}, \csh{xintiiDivRound}}
-% \lverb|v1.1, transferred from first release of bnumexpr.|
+% \lverb|v1.1, transferred from first release of bnumexpr. Rewritten for v1.2.|
% \begin{macrocode}
\def\xintiDivRound {\romannumeral0\xintidivround }%
-\def\xintidivround #1{\expandafter\XINT_iidivround\romannumeral0\xintnum{#1}\Z }%
+\def\xintidivround #1%
+ {\expandafter\XINT_idivround\romannumeral0\xintnum{#1}\Z }%
\def\xintiiDivRound {\romannumeral0\xintiidivround }%
\def\xintiidivround #1{\expandafter\XINT_iidivround \romannumeral-`0#1\Z }%
-\def\XINT_iidivround #1#2\Z #3{\expandafter\XINT_iidivround_a\expandafter #1%
- \romannumeral-`0#3\Z #2\Z }%
+\def\XINT_idivround #1#2\Z #3%
+ {\expandafter\XINT_iidivround_a\expandafter #1%
+ \romannumeral0\xintnum{#3}\Z #2\Z }%
+\def\XINT_iidivround #1#2\Z #3%
+ {\expandafter\XINT_iidivround_a\expandafter #1\romannumeral-`0#3\Z #2\Z }%
\def\XINT_iidivround_a #1#2% #1 de A, #2 de B.
{%
\if0#2\xint_dothis\XINT_iidivround_divbyzero\fi
@@ -18008,19 +17891,50 @@ $1$ or $-1$.
-{\xintiiopp\XINT_iidivround_pos #1}%
\krof
}%
-\def\XINT_iidivround_pos #1#2\Z #3\Z{\expandafter\XINT_iidivround_pos_a
- \romannumeral0\XINT_div_prepare {#2}{#1#30}}%
-\def\XINT_iidivround_pos_a #1#2{\xintReverseOrder {#1\XINT_iidivround_pos_b}\Z }%
-\def\XINT_iidivround_pos_b #1#2{\xint_gob_til_Z #2\XINT_iidivround_pos_small\Z
- \XINT_iidivround_pos_c #1#2}%
-\def\XINT_iidivround_pos_c #1#2\Z {\ifnum #1>\xint_c_iv
- \expandafter\XINT_iidivround_pos_up
- \else \expandafter\xintreverseorder
- \fi {#2}}%
-\def\XINT_iidivround_pos_up #1{\xintinc {\xintReverseOrder{#1}}}%
-\def\XINT_iidivround_pos_small\Z\XINT_iidivround_pos_c #1#2%
- {\ifnum #1>\xint_c_iv\expandafter\xint_secondoftwo\else\expandafter
- \xint_firstoftwo\fi { 0}{ 1}}%
+\def\XINT_iidivround_pos #1#2\Z #3\Z
+{%
+ \expandafter\XINT_iidivround_pos_a
+ \romannumeral0\XINT_div_prepare {#2}{#1#30}%
+}%
+\def\XINT_iidivround_pos_a #1#2%
+{%
+ \expandafter\XINT_iidivround_pos_b
+ \romannumeral0\expandafter\XINT_sepandrev
+ \romannumeral0\XINT_zeroes_forviii #1\R\R\R\R\R\R\R\R{10}0000001\W
+ #1\XINT_rsepbyviii_end_A 2345678\XINT_rsepbyviii_end_B 2345678\relax XX%
+ \R.\R.\R.\R.\R.\R.\R.\R.\W
+ \Z!\Z!\Z!\Z!\Z!\W
+}%
+\def\XINT_iidivround_pos_b 1#1#2#3#4#5#6#7#8!#9%
+{%
+ \xint_gob_til_Z #9\XINT_iidivround_small\Z
+ \ifnum #8>\xint_c_iv
+ \expandafter\XINT_iidivround_pos_up
+ \else \expandafter\XINT_iidivround_pos_finish
+ \fi
+ 1#1#2#3#4#5#6#70!#9%
+}%
+\def\XINT_iidivround_pos_up
+{%
+ \expandafter\XINT_iidivround_pos_finish
+ \the\numexpr\XINT_add_a\xint_c_ii 100000010!\Z!\Z!\Z!\Z!\Z!\W
+}%
+\def\XINT_iidivround_pos_finish #10!#2\Z #3\W
+{%
+ \expandafter\XINT_cuz_small\romannumeral0\XINT_unrevbyviii {}%
+ #1!#21\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W
+}%
+\def\XINT_iidivround_small\Z\ifnum #1>#2\fi 1#30!#4\W
+{%
+ \ifnum #1>\xint_c_iv
+ \expandafter\XINT_iidivround_small_up
+ \else \expandafter\XINT_iidivround_small_trunc
+ \fi {#3}%
+}%
+\edef\XINT_iidivround_small_up #1%
+ {\noexpand\expandafter\space\noexpand\the\numexpr #1+\xint_c_i\relax }%
+\edef\XINT_iidivround_small_trunc #1%
+ {\noexpand\expandafter\space\noexpand\the\numexpr #1\relax }%
% \end{macrocode}
% \subsection{\csh{xintiDivTrunc}, \csh{xintiiDivTrunc}}
% \begin{macrocode}
@@ -18052,7 +17966,8 @@ $1$ or $-1$.
\krof
}%
\def\XINT_iidivtrunc_pos #1#2\Z #3\Z%
- {\expandafter\xint_firstoftwo_thenstop\romannumeral0\XINT_div_prepare {#2}{#1#3}}%
+ {\expandafter\xint_firstoftwo_thenstop
+ \romannumeral0\XINT_div_prepare {#2}{#1#3}}%
% \end{macrocode}
% \subsection{\csh{xintiMod}, \csh{xintiiMod}}
% \begin{macrocode}
@@ -18084,7 +17999,20 @@ $1$ or $-1$.
\krof
}%
\def\XINT_iimod_pos #1#2\Z #3\Z%
- {\expandafter\xint_secondoftwo_thenstop\romannumeral0\XINT_div_prepare {#2}{#1#3}}%
+ {\expandafter\xint_secondoftwo_thenstop\romannumeral0\XINT_div_prepare
+ {#2}{#1#3}}%
+% \end{macrocode}
+% \subsection{``Load \xintfracnameimp'' macros}
+% \lverb|Originally was used in \xintiiexpr. Transferred from xintfrac for 1.1.|
+% \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!}%
\XINT_restorecatcodes_endinput%
% \end{macrocode}
%\catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11
@@ -18099,9 +18027,10 @@ $1$ or $-1$.
%
% \localtableofcontents
%
-% The basic arithmetic routines |\xintiiAdd|, |\xintiiSub|,
-% |\xintiiMul|, |\xintiiQuo| and |\xintiiPow| have been moved to new
-% package \xintcorenameimp.
+% 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
@@ -18151,7 +18080,7 @@ $1$ or $-1$.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xint}%
- [2015/09/12 v1.1c Expandable operations on big integers (jfB)]%
+ [2015/10/10 v1.2 Expandable operations on big integers (jfB)]%
% \end{macrocode}
% \subsection{More token management}
% \begin{macrocode}
@@ -18161,6 +18090,10 @@ $1$ or $-1$.
\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}%
+\edef\xint_cleanupzeros_andstop #1#2#3#4%
+{%
+ \noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4\relax
+}%
% \end{macrocode}
% \subsection{\csh{xintSgnFork}}
% \lverb|Expandable three-way fork added in 1.07. The argument #1 must expand
@@ -18201,24 +18134,12 @@ $1$ or $-1$.
% However this last aspect does not appear like a very useful thing. And despite
% the fact that a special check is made for a sign, actually the input is not
% given to \xintnum, contrarily to \xintLen. This is all a bit incoherent.
-% Should be fixed.|
+% Should be fixed.
+%
+% 1.2 has \xintReverseDigits and I thus make \xintRev an alias. Remarks above
+% not addressed.|
% \begin{macrocode}
-\def\xintRev {\romannumeral0\xintrev }%
-\def\xintrev #1%
-{%
- \expandafter\XINT_rev_fork
- \romannumeral-`0#1\xint_relax % empty #1 ok, \xint_relax stops expansion
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_bye\xint_bye\xint_bye\xint_bye
- \xint_relax
-}%
-\def\XINT_rev_fork #1%
-{%
- \xint_UDsignfork
- #1{\expandafter\xint_minus_thenstop\romannumeral0\XINT_rord_main {}}%
- -{\XINT_rord_main {}#1}%
- \krof
-}%
+\let\xintRev\xintReverseDigits
% \end{macrocode}
% \subsection{\csh{xintLen}}
% \lverb|\xintLen is ONLY for (possibly long) integers. Gets extended to
@@ -18463,143 +18384,183 @@ $1$ or $-1$.
}%
% \end{macrocode}
% \subsection{\csh{xintCmp}, \csh{xintiiCmp}}
-% \lverb|Release 1.09a has \xintnum inserted into \xintCmp. Unnecessary
-% \xintiCmp suppressed in 1.09f. And 1.1a does \xintiiCmp, for
-% optimization in \xintiiexpr. (not needed before, because \XINT_cmp_fork was
-% directly used, or \XINT_Cmp)|
+% \lverb|Faster than doing the full subtraction.|
% \begin{macrocode}
-\def\xintCmp {\romannumeral0\xintcmp }%
-\def\xintcmp #1%
+\def\xintCmp {\romannumeral0\xintcmp }%
+\def\xintcmp #1{\expandafter\XINT_icmp\romannumeral0\xintnum{#1}\Z }%
+\def\xintiiCmp {\romannumeral0\xintiicmp }%
+\def\xintiicmp #1{\expandafter\XINT_iicmp\romannumeral-`0#1\Z }%
+\def\XINT_iicmp #1#2\Z #3%
{%
- \expandafter\xint_cmp\expandafter{\romannumeral0\xintnum{#1}}%
+ \expandafter\XINT_cmp_nfork\expandafter #1\romannumeral-`0#3\Z #2\Z
}%
-\def\xint_cmp #1#2%
+% \end{macrocode}
+% \lverb|New fork of 1.2 makes it less convenient here for \XINT_cmp_pre and
+% \XINT_Cmp, which just avoided the \romannumeral-`0. Nanosecond loss ? I
+% vaguely recalled that for \xintNewExpr things, I did need another name such
+% as \XINT_cmp for \xintiiCmp.|
+% \begin{macrocode}
+\let\XINT_Cmp \xintiiCmp
+\def\XINT_icmp #1#2\Z #3%
{%
- \expandafter\XINT_cmp_fork \romannumeral0\xintnum{#2}\Z #1\Z
+ \expandafter\XINT_cmp_nfork\expandafter #1\romannumeral0\xintnum{#3}\Z #2\Z
}%
-\def\xintiiCmp {\romannumeral0\xintiicmp }%
-\def\xintiicmp #1%
+\def\XINT_cmp_nfork #1#2%
{%
- \expandafter\xint_iicmp\expandafter{\romannumeral-`0#1}%
+ \xint_UDzerofork
+ #1\XINT_cmp_firstiszero
+ #2\XINT_cmp_secondiszero
+ 0{}%
+ \krof
+ \xint_UDsignsfork
+ #1#2\XINT_cmp_minusminus
+ #1-\XINT_cmp_minusplus
+ #2-\XINT_cmp_plusminus
+ --\XINT_cmp_plusplus
+ \krof #1#2%
}%
-\def\xint_iicmp #1#2%
+\def\XINT_cmp_firstiszero #1\krof 0#2#3\Z #4\Z
{%
- \expandafter\XINT_cmp_fork \romannumeral-`0#2\Z #1\Z
-}%
-\def\XINT_Cmp #1#2{\romannumeral0\XINT_cmp_fork #2\Z #1\Z }%
-% \end{macrocode}
-% \lverb|&
-% COMPARAISON $\
-% 1 si #3#4>#1#2, 0 si #3#4=#1#2, -1 si #3#4<#1#2$\
-% #3#4 vient du *premier*,$
-% #1#2 vient du *second*|
-% \begin{macrocode}
-\def\XINT_cmp_fork #1#2\Z #3#4\Z
+ \xint_UDzerominusfork
+ #2-{ 0}%
+ 0#2{ 1}%
+ 0-{ -1}%
+ \krof
+}%
+\def\XINT_cmp_secondiszero #1\krof #20#3\Z #4\Z
{%
- \xint_UDsignsfork
- #1#3\XINT_cmp_minusminus
- #1-\XINT_cmp_minusplus
- #3-\XINT_cmp_plusminus
- --{\xint_UDzerosfork
- #1#3\XINT_cmp_zerozero
- #10\XINT_cmp_zeroplus
- #30\XINT_cmp_pluszero
- 00\XINT_cmp_plusplus
- \krof }%
+ \xint_UDzerominusfork
+ #2-{ 0}%
+ 0#2{ -1}%
+ 0-{ 1}%
\krof
- {#2}{#4}#1#3%
+}%
+\def\XINT_cmp_plusminus #1\Z #2\Z{ 1}%
+\def\XINT_cmp_minusplus #1\Z #2\Z{ -1}%
+\def\XINT_cmp_minusminus
+ --{\expandafter\XINT_opp\romannumeral0\XINT_cmp_plusplus {}{}}%
+\def\XINT_cmp_plusplus #1#2#3\Z
+{%
+ \expandafter\XINT_cmp_pp
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #2#3\R\R\R\R\R\R\R\R{10}0000001\W
+ #2#3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_iii
+ \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii
+ \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W
+ \X #1%
+}%
+\def\XINT_cmp_pp #1.#2\X #3\Z
+{%
+ \expandafter\XINT_cmp_checklengths
+ \the\numexpr #1\expandafter.%
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #3\R\R\R\R\R\R\R\R{10}0000001\W
+ #3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax \xint_c_ii\xint_c_iii
+ \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii
+ \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W
+ \Z!\Z!\Z!\Z!\Z!\W #2\Z!\Z!\Z!\Z!\Z!\W
+}%
+\def\XINT_cmp_checklengths #1.#2.%
+{%
+ \ifnum #1=#2
+ \expandafter\xint_firstoftwo
+ \else
+ \expandafter\xint_secondoftwo
+ \fi
+ \XINT_cmp_aa {\XINT_cmp_distinctlengths {#1}{#2}}%
}%
-\def\XINT_cmp_minusplus #1#2#3#4{ 1}%
-\def\XINT_cmp_plusminus #1#2#3#4{ -1}%
-\def\XINT_cmp_zerozero #1#2#3#4{ 0}%
-\def\XINT_cmp_zeroplus #1#2#3#4{ 1}%
-\def\XINT_cmp_pluszero #1#2#3#4{ -1}%
-\def\XINT_cmp_plusplus #1#2#3#4%
+\def\XINT_cmp_distinctlengths #1#2#3\W #4\W
{%
- \XINT_cmp_pre {#4#2}{#3#1}%
+ \ifnum #1>#2
+ \expandafter\xint_firstoftwo
+ \else
+ \expandafter\xint_secondoftwo
+ \fi
+ { -1}{ 1}%
}%
-\def\XINT_cmp_minusminus #1#2#3#4%
+%%%%%%%%%%%%
+\def\XINT_cmp_aa {\expandafter\XINT_cmp_w\the\numexpr\XINT_cmp_a \xint_c_i }%
+%%%%%%%%%%%%
+\def\XINT_cmp_a #1!#2!#3!#4!#5\W #6!#7!#8!#9!%
{%
- \XINT_cmp_pre {#1}{#2}%
+ \XINT_cmp_b #1!#6!#2!#7!#3!#8!#4!#9!#5\W
}%
-\def\XINT_cmp_pre #1%
+\def\XINT_cmp_b #1#2#3!#4!%
{%
- \expandafter\XINT_cmp_pre_b\expandafter
- {\romannumeral0\XINT_RQ {}#1\R\R\R\R\R\R\R\R\Z }%
+ \xint_gob_til_Z #2\XINT_cmp_bi \Z
+ \expandafter\XINT_cmp_c\the\numexpr#1+1#4-#3-\xint_c_i.%
}%
-\def\XINT_cmp_pre_b #1#2%
+\def\XINT_cmp_c 1#1#2.%
{%
- \expandafter\XINT_cmp_A
- \expandafter1\expandafter{\expandafter}%
- \romannumeral0\XINT_RQ {}#2\R\R\R\R\R\R\R\R\Z
- \W\X\Y\Z #1\W\X\Y\Z
+ 1#2\expandafter!\the\numexpr\XINT_cmp_d #1%
}%
-% \end{macrocode}
-% \lverb|&
-% COMPARAISON$\
-% N1 et N2 sont présentés à l'envers ET ON A RAJOUTÉ DES ZÉROS
-% POUR QUE LEUR LONGUEURS À CHACUN SOIENT MULTIPLES DE 4, MAIS
-% AUCUN NE SE TERMINE EN 0000.
-% routine appelée via$\
-% \XINT_cmp_A 1{}<N1>\W\X\Y\Z<N2>\W\X\Y\Z$\
-% ATTENTION RENVOIE 1 SI N1 < N2, 0 si N1 = N2, -1 si N1 > N2|
-% \begin{macrocode}
-\def\XINT_cmp_A #1#2#3\W\X\Y\Z #4#5#6#7%
+\def\XINT_cmp_d #1#2#3!#4!%
{%
- \xint_gob_til_W #4\xint_cmp_az\W
- \XINT_cmp_B #1{#4#5#6#7}{#2}#3\W\X\Y\Z
+ \xint_gob_til_Z #2\XINT_cmp_di \Z
+ \expandafter\XINT_cmp_e\the\numexpr#1+1#4-#3-\xint_c_i.%
}%
-\def\XINT_cmp_B #1#2#3#4#5#6#7%
+\def\XINT_cmp_e 1#1#2.%
{%
- \xint_gob_til_W#4\xint_cmp_bz\W
- \XINT_cmp_onestep #1#2{#7#6#5#4}{#3}%
+ 1#2\expandafter!\the\numexpr\XINT_cmp_f #1%
}%
-\def\XINT_cmp_onestep #1#2#3#4#5#6%
+\def\XINT_cmp_f #1#2#3!#4!%
{%
- \expandafter\XINT_cmp_backtoA\the\numexpr 11#5#4#3#2-#6+#1-\xint_c_i.%
+ \xint_gob_til_Z #2\XINT_cmp_fi \Z
+ \expandafter\XINT_cmp_g\the\numexpr#1+1#4-#3-\xint_c_i.%
}%
-\def\XINT_cmp_backtoA #1#2#3.#4%
+\def\XINT_cmp_g 1#1#2.%
{%
- \XINT_cmp_A #2{#3#4}%
+ 1#2\expandafter!\the\numexpr\XINT_cmp_h #1%
}%
-\def\xint_cmp_bz\W\XINT_cmp_onestep #1\Z { 1}%
-\def\xint_cmp_az\W\XINT_cmp_B #1#2#3#4#5#6#7%
+\def\XINT_cmp_h #1#2#3!#4!%
{%
- \xint_gob_til_W #4\xint_cmp_ez\W
- \XINT_cmp_Eenter #1{#3}#4#5#6#7%
+ \xint_gob_til_Z #2\XINT_cmp_hi \Z
+ \expandafter\XINT_cmp_i\the\numexpr#1+1#4-#3-\xint_c_i.%
}%
-\def\XINT_cmp_Eenter #1\Z { -1}%
-\def\xint_cmp_ez\W\XINT_cmp_Eenter #1%
+\def\XINT_cmp_i 1#1#2.%
{%
- \xint_UDzerofork
- #1\XINT_cmp_K % il y a une retenue
- 0\XINT_cmp_L % pas de retenue
- \krof
+ 1#2\expandafter!\the\numexpr\XINT_cmp_a #1%
+}%
+\def\XINT_cmp_bi\Z
+ \expandafter\XINT_cmp_c\the\numexpr#1+1#2-#3.#4!#5!#6!#7!#8!#9!\Z !\W
+{%
+ \XINT_cmp_k #1#2!#5!#7!#9!%
}%
-\def\XINT_cmp_K #1\Z { -1}%
-\def\XINT_cmp_L #1{\XINT_OneIfPositive_main #1}%
-\def\XINT_OneIfPositive #1%
+\def\XINT_cmp_di\Z
+ \expandafter\XINT_cmp_e\the\numexpr#1+1#2-#3.#4!#5!#6!#7!#8\W
{%
- \XINT_OneIfPositive_main #1\W\X\Y\Z%
+ \XINT_cmp_k #1#2!#5!#7!%
}%
-\def\XINT_OneIfPositive_main #1#2#3#4%
+\def\XINT_cmp_fi\Z
+ \expandafter\XINT_cmp_g\the\numexpr#1+1#2-#3.#4!#5!#6\W
{%
- \xint_gob_til_Z #4\xint_OneIfPositive_terminated\Z
- \XINT_OneIfPositive_onestep #1#2#3#4%
+ \XINT_cmp_k #1#2!#5!%
}%
-\def\xint_OneIfPositive_terminated\Z\XINT_OneIfPositive_onestep\W\X\Y\Z { 0}%
-\def\XINT_OneIfPositive_onestep #1#2#3#4%
+\def\XINT_cmp_hi\Z
+ \expandafter\XINT_cmp_i\the\numexpr#1+1#2-#3.#4\W
{%
- \expandafter\XINT_OneIfPositive_check\the\numexpr #1#2#3#4\relax
+ \XINT_cmp_k #1#2!%
}%
-\def\XINT_OneIfPositive_check #1%
+%%%%%%%%%%%%
+\def\XINT_cmp_k #1#2\W
{%
- \xint_gob_til_zero #1\xint_OneIfPositive_backtomain 0%
- \XINT_OneIfPositive_finish #1%
+ \xint_UDzerofork
+ #1{-1\relax \XINT_cmp_greater}%
+ 0{-1\relax \XINT_cmp_lessorequal}%
+ \krof
}%
-\def\XINT_OneIfPositive_finish #1\W\X\Y\Z{ 1}%
-\def\xint_OneIfPositive_backtomain 0\XINT_OneIfPositive_finish 0%
- {\XINT_OneIfPositive_main }%
+\def\XINT_cmp_w #1-1#2{#2#11\Z!\W}%
+\def\XINT_cmp_greater #1\Z!\W{ 1}%
+\def\XINT_cmp_lessorequal 1#1!%
+ {\xint_gob_til_Z #1\XINT_cmp_equal\Z
+ \xint_gob_til_eightzeroes #1\XINT_cmp_continue 00000000%
+ \XINT_cmp_less }%
+\def\XINT_cmp_less #1\W { -1}%
+\def\XINT_cmp_continue 00000000\XINT_cmp_less {\XINT_cmp_lessorequal }%
+\def\XINT_cmp_equal\Z\xint_gob_til_eightzeroes\Z\XINT_cmp_continue
+ 00000000\XINT_cmp_less\W { 0}%
% \end{macrocode}
% \subsection{\csh{xintEq}, \csh{xintGt}, \csh{xintLt}}
% \lverb|1.09a.|
@@ -18711,101 +18672,159 @@ $1$ or $-1$.
}%
\def\XINT_xorof_e #1\Z #2{ #2}%
% \end{macrocode}
-% \subsection{\csh{xintGeq}}
+% \subsection{\csh{xintGeq}, \csh{xintiiGeq}}
% \lverb|&
-% Release 1.09a has \xintnum added into \xintGeq.
% PLUS GRAND OU ÉGAL
% attention compare les **valeurs absolues**|
% \begin{macrocode}
-\def\xintGeq {\romannumeral0\xintgeq }%
-\def\xintgeq #1%
+\def\xintGeq {\romannumeral0\xintgeq }%
+\def\xintgeq #1{\expandafter\XINT_geq\romannumeral0\xintnum{#1}\Z }%
+\def\xintiiGeq {\romannumeral0\xintiigeq }%
+\def\xintiigeq #1{\expandafter\XINT_iigeq\romannumeral-`0#1\Z }%
+\def\XINT_iigeq #1#2\Z #3%
{%
- \expandafter\xint_geq\expandafter {\romannumeral0\xintnum{#1}}%
+ \expandafter\XINT_geq_fork\expandafter #1\romannumeral-`0#3\Z #2\Z
}%
-\def\xint_geq #1#2%
+\let\XINT_geq_pre \xintiigeq % TEMPORAIRE
+\let\XINT_Geq \xintGeq % TEMPORAIRE ATTENTION FAIT xintNum
+\def\XINT_geq #1#2\Z #3%
{%
- \expandafter\XINT_geq_fork \romannumeral0\xintnum{#2}\Z #1\Z
+ \expandafter\XINT_geq_fork\expandafter #1\romannumeral0\xintnum{#3}\Z #2\Z
}%
-\def\XINT_Geq #1#2{\romannumeral0\XINT_geq_fork #2\Z #1\Z }%
-% \end{macrocode}
-% \lverb|&
-% PLUS GRAND OU ÉGAL
-% ATTENTION, TESTE les VALEURS ABSOLUES|
-% \begin{macrocode}
-\def\XINT_geq_fork #1#2\Z #3#4\Z
+\def\XINT_geq_fork #1#2%
{%
\xint_UDzerofork
- #1\XINT_geq_secondiszero % |#1#2|=0
- #3\XINT_geq_firstiszero % |#1#2|>0
- 0{\xint_UDsignsfork
- #1#3\XINT_geq_minusminus
- #1-\XINT_geq_minusplus
- #3-\XINT_geq_plusminus
- --\XINT_geq_plusplus
- \krof }%
+ #1\XINT_geq_firstiszero
+ #2\XINT_geq_secondiszero
+ 0{}%
\krof
- {#2}{#4}#1#3%
+ \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\Z #4\Z
+ {\xint_UDzerofork #2{ 1}0{ 0}\krof }%
+\def\XINT_geq_secondiszero #1\krof #20#3\Z #4\Z { 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 #1#2#3\Z #4\Z {\XINT_geq_pp #1#4\Z #2#3\Z }%
+\def\XINT_geq_pp #1\Z
+{%
+ \expandafter\XINT_geq_pp_a
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #1\R\R\R\R\R\R\R\R{10}0000001\W
+ #1\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax\xint_c_ii\xint_c_iii
+ \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii
+ \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W
+ \X
+}%
+\def\XINT_geq_pp_a #1.#2\X #3\Z
+{%
+ \expandafter\XINT_geq_checklengths
+ \the\numexpr #1\expandafter.%
+ \romannumeral0\expandafter\XINT_sepandrev_andcount
+ \romannumeral0\XINT_zeroes_forviii #3\R\R\R\R\R\R\R\R{10}0000001\W
+ #3\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678\relax \xint_c_ii\xint_c_iii
+ \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii
+ \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W
+ \Z!\Z!\Z!\Z!\Z!\W #2\Z!\Z!\Z!\Z!\Z!\W
+}%
+\def\XINT_geq_checklengths #1.#2.%
+{%
+ \ifnum #1=#2
+ \expandafter\xint_firstoftwo
+ \else
+ \expandafter\xint_secondoftwo
+ \fi
+ \XINT_geq_aa {\XINT_geq_distinctlengths {#1}{#2}}
+}%
+\def\XINT_geq_distinctlengths #1#2#3\W #4\W
+{%
+ \ifnum #1>#2
+ \expandafter\xint_firstoftwo
+ \else
+ \expandafter\xint_secondoftwo
+ \fi
+ { 1}{ 0}%
}%
-\def\XINT_geq_secondiszero #1#2#3#4{ 1}%
-\def\XINT_geq_firstiszero #1#2#3#4{ 0}%
-\def\XINT_geq_plusplus #1#2#3#4{\XINT_geq_pre {#4#2}{#3#1}}%
-\def\XINT_geq_minusminus #1#2#3#4{\XINT_geq_pre {#2}{#1}}%
-\def\XINT_geq_minusplus #1#2#3#4{\XINT_geq_pre {#4#2}{#1}}%
-\def\XINT_geq_plusminus #1#2#3#4{\XINT_geq_pre {#2}{#3#1}}%
-\def\XINT_geq_pre #1%
+%%%%%%%%%%%%
+\def\XINT_geq_aa {\expandafter\XINT_geq_w\the\numexpr\XINT_geq_a \xint_c_i }%
+%%%%%%%%%%%%
+\def\XINT_geq_a #1!#2!#3!#4!#5\W #6!#7!#8!#9!%
{%
- \expandafter\XINT_geq_pre_b\expandafter
- {\romannumeral0\XINT_RQ {}#1\R\R\R\R\R\R\R\R\Z }%
+ \XINT_geq_b #1!#6!#2!#7!#3!#8!#4!#9!#5\W
}%
-\def\XINT_geq_pre_b #1#2%
+\def\XINT_geq_b #1#2#3!#4!%
{%
- \expandafter\XINT_geq_A
- \expandafter1\expandafter{\expandafter}%
- \romannumeral0\XINT_RQ {}#2\R\R\R\R\R\R\R\R\Z
- \W\X\Y\Z #1 \W\X\Y\Z
+ \xint_gob_til_Z #2\XINT_geq_bi \Z
+ \expandafter\XINT_geq_c\the\numexpr#1+1#4-#3-\xint_c_i.%
}%
-% \end{macrocode}
-% \lverb|&
-% PLUS GRAND OU ÉGAL$\
-% N1 et N2 sont présentés à l'envers ET ON A RAJOUTÉ DES ZÉROS
-% POUR QUE LEURS LONGUEURS À CHACUN SOIENT MULTIPLES DE 4, MAIS
-% AUCUN NE SE TERMINE EN 0000$\
-% routine appelée via$\
-% \romannumeral0\XINT_geq_A 1{}<N1>\W\X\Y\Z<N2>\W\X\Y\Z$\
-% ATTENTION RENVOIE 1 SI N1 < N2 ou N1 = N2 et 0 si N1 > N2|
-% \begin{macrocode}
-\def\XINT_geq_A #1#2#3\W\X\Y\Z #4#5#6#7%
+\def\XINT_geq_c 1#1#2.%
{%
- \xint_gob_til_W #4\xint_geq_az\W
- \XINT_geq_B #1{#4#5#6#7}{#2}#3\W\X\Y\Z
+ 1#2\expandafter!\the\numexpr\XINT_geq_d #1%
}%
-\def\XINT_geq_B #1#2#3#4#5#6#7%
+\def\XINT_geq_d #1#2#3!#4!%
{%
- \xint_gob_til_W #4\xint_geq_bz\W
- \XINT_geq_onestep #1#2{#7#6#5#4}{#3}%
+ \xint_gob_til_Z #2\XINT_geq_di \Z
+ \expandafter\XINT_geq_e\the\numexpr#1+1#4-#3-\xint_c_i.%
}%
-\def\XINT_geq_onestep #1#2#3#4#5#6%
+\def\XINT_geq_e 1#1#2.%
{%
- \expandafter\XINT_geq_backtoA\the\numexpr 11#5#4#3#2-#6+#1-\xint_c_i.%
+ 1#2\expandafter!\the\numexpr\XINT_geq_f #1%
}%
-\def\XINT_geq_backtoA #1#2#3.#4%
+\def\XINT_geq_f #1#2#3!#4!%
{%
- \XINT_geq_A #2{#3#4}%
+ \xint_gob_til_Z #2\XINT_geq_fi \Z
+ \expandafter\XINT_geq_g\the\numexpr#1+1#4-#3-\xint_c_i.%
}%
-\def\xint_geq_bz\W\XINT_geq_onestep #1\W\X\Y\Z { 1}%
-\def\xint_geq_az\W\XINT_geq_B #1#2#3#4#5#6#7%
+\def\XINT_geq_g 1#1#2.%
{%
- \xint_gob_til_W #4\xint_geq_ez\W
- \XINT_geq_Eenter #1%
+ 1#2\expandafter!\the\numexpr\XINT_geq_h #1%
}%
-\def\XINT_geq_Eenter #1\W\X\Y\Z { 0}%
-\def\xint_geq_ez\W\XINT_geq_Eenter #1%
+\def\XINT_geq_h #1#2#3!#4!%
{%
- \xint_UDzerofork
- #1{ 0} % il y a une retenue
- 0{ 1} % pas de retenue
- \krof
+ \xint_gob_til_Z #2\XINT_geq_hi \Z
+ \expandafter\XINT_geq_i\the\numexpr#1+1#4-#3-\xint_c_i.%
+}%
+\def\XINT_geq_i 1#1#2.%
+{%
+ 1#2\expandafter!\the\numexpr\XINT_geq_a #1%
+}%
+\def\XINT_geq_bi\Z
+ \expandafter\XINT_geq_c\the\numexpr#1+1#2-#3.#4!#5!#6!#7!#8!#9!\Z !\W
+{%
+ \XINT_geq_k #1#2!#5!#7!#9!%
+}%
+\def\XINT_geq_di\Z
+ \expandafter\XINT_geq_e\the\numexpr#1+1#2-#3.#4!#5!#6!#7!#8\W
+{%
+ \XINT_geq_k #1#2!#5!#7!%
}%
+\def\XINT_geq_fi\Z
+ \expandafter\XINT_geq_g\the\numexpr#1+1#2-#3.#4!#5!#6\W
+{%
+ \XINT_geq_k #1#2!#5!%
+}%
+\def\XINT_geq_hi\Z
+ \expandafter\XINT_geq_i\the\numexpr#1+1#2-#3.#4\W
+{%
+ \XINT_geq_k #1#2!%
+}%
+%%%%%%%%%%%%
+\def\XINT_geq_k #1#2\W
+{%
+ \xint_UDzerofork
+ #1{-1\relax { 0}}%
+ 0{-1\relax { 1}}%
+ \krof
+}%
+\def\XINT_geq_w #1-1#2{#2}%
% \end{macrocode}
% \subsection{\csh{xintiMax}, \csh{xintiiMax}}
% \lverb|&
@@ -18816,7 +18835,9 @@ $1$ or $-1$.
% 1.09a has \xintnum added into \xintiMax.
%
% 1.1 adds the missing \xintiiMax. Using \xintMax and not \xintiMax in xint is
-% deprecated.|
+% deprecated.
+%
+% 1.2 REMOVES \xintMax, \xintMin, \xintMaxof, \xintMinof.|
% \begin{macrocode}
\def\xintiMax {\romannumeral0\xintimax }%
\def\xintimax #1%
@@ -18836,7 +18857,6 @@ $1$ or $-1$.
{%
\expandafter\XINT_max_pre\expandafter {\romannumeral-`0#2}{#1}%
}%
-\let\xintMax\xintiMax \let\xintmax\xintimax % deprecated, should be only with xintfrac
\def\XINT_max_pre #1#2{\XINT_max_fork #1\Z #2\Z {#2}{#1}}%
\def\XINT_Max #1#2{\romannumeral0\XINT_max_fork #2\Z #1\Z {#1}{#2}}%
% \end{macrocode}
@@ -18888,8 +18908,8 @@ $1$ or $-1$.
\fi
}%
% \end{macrocode}
-% \subsection{\csh{xintMaxof}}
-% \lverb|New with 1.09a.|
+% \subsection{\csh{xintiMaxof}}
+% \lverb|New with 1.09a. 1.2 has NO MORE \xintMaxof, requires \xintfracname.|
% \begin{macrocode}
\def\xintiMaxof {\romannumeral0\xintimaxof }%
\def\xintimaxof #1{\expandafter\XINT_imaxof_a\romannumeral-`0#1\relax }%
@@ -18901,11 +18921,11 @@ $1$ or $-1$.
\def\XINT_imaxof_d #1\Z
{\expandafter\XINT_imaxof_b\romannumeral0\xintimax {#1}}%
\def\XINT_imaxof_e #1\Z #2\Z { #2}%
-\let\xintMaxof\xintiMaxof \let\xintmaxof\xintimaxof
% \end{macrocode}
% \subsection{\csh{xintiMin}, \csh{xintiiMin}}
% \lverb|\xintnum added New with 1.09a. I add \xintiiMin in 1.1 and mark as
-% deprecated \xintMin, renamed \xintiMin.|
+% deprecated \xintMin, renamed \xintiMin. \xintMin NOW REMOVED (1.2, as
+% \xintMax, \xintMaxof), only provided by \xintfracnameimp.|
% \begin{macrocode}
\def\xintiMin {\romannumeral0\xintimin }%
\def\xintimin #1%
@@ -18925,7 +18945,6 @@ $1$ or $-1$.
{%
\expandafter\XINT_min_pre\expandafter {\romannumeral-`0#2}{#1}%
}%
-\let\xintMin\xintiMin \let\xintmin\xintimin % deprecated
\def\XINT_min_pre #1#2{\XINT_min_fork #1\Z #2\Z {#2}{#1}}%
\def\XINT_Min #1#2{\romannumeral0\XINT_min_fork #2\Z #1\Z {#1}{#2}}%
% \end{macrocode}
@@ -18990,12 +19009,11 @@ $1$ or $-1$.
\def\XINT_iminof_d #1\Z
{\expandafter\XINT_iminof_b\romannumeral0\xintimin {#1}}%
\def\XINT_iminof_e #1\Z #2\Z { #2}%
-\let\xintMinof\xintiMinof \let\xintminof\xintiminof
% \end{macrocode}
% \subsection{\csh{xintiiSum}}
% \lverb|&
-% \xintSum {{a}{b}...{z}}$\
-% \xintSumExpr {a}{b}...{z}\relax$\
+% \xintiiSum {{a}{b}...{z}}$\
+% \xintiiSumExpr {a}{b}...{z}\relax$\
% 1.03 (drastically) simplifies and makes the routines more efficient (for big
% computations). Also the way \xintSum and \xintSumExpr ...\relax are related.
% has been modified. Now \xintSumExpr \z \relax is accepted input when
@@ -19003,55 +19021,36 @@ $1$ or $-1$.
% was possible).
%
% 1.09a does NOT add the \xintnum overhead. 1.09h renames \xintiSum to
-% \xintiiSum to correctly reflect this.|
+% \xintiiSum to correctly reflect this.
+%
+% The xint 1.0x routine could benefit from the fact that addition and
+% subtraction did not check the lengths of the arguments and were able to do
+% their job independently of the order (but not at equal speed). Thus it was
+% possible to add separately positive and negative summands and do one big
+% subtraction at the end, keeping during all that time the intermediate result
+% in reverse order suitable for both addition and subtraction. The lazy
+% programmer being a bit tired after the 95$% rewrite of xintcore has not
+% tried to do the same with the new model. Thus we just do stupidly repeated
+% additions. The code is thus much shorter... and in fact I just copied the
+% routine for products and changed products to sums.|
% \begin{macrocode}
\def\xintiiSum {\romannumeral0\xintiisum }%
\def\xintiisum #1{\xintiisumexpr #1\relax }%
\def\xintiiSumExpr {\romannumeral0\xintiisumexpr }%
\def\xintiisumexpr {\expandafter\XINT_sumexpr\romannumeral-`0}%
-\let\xintSum\xintiiSum \let\xintsum\xintiisum
-\let\xintSumExpr\xintiiSumExpr \let\xintsumexpr\xintiisumexpr
-\def\XINT_sumexpr {\XINT_sum_loop {0000}{0000}}%
-\def\XINT_sum_loop #1#2#3%
-{%
- \expandafter\XINT_sum_checksign\romannumeral-`0#3\Z {#1}{#2}%
-}%
-\def\XINT_sum_checksign #1%
-{%
- \xint_gob_til_relax #1\XINT_sum_finished\relax
- \xint_gob_til_zero #1\XINT_sum_skipzeroinput0%
- \xint_UDsignfork
- #1\XINT_sum_N
- -{\XINT_sum_P #1}%
- \krof
-}%
-\def\XINT_sum_finished #1\Z #2#3%
-{%
- \XINT_sub_A 1{}#3\W\X\Y\Z #2\W\X\Y\Z
-}%
-\def\XINT_sum_skipzeroinput #1\krof #2\Z {\XINT_sum_loop }%
-\def\XINT_sum_P #1\Z #2%
-{%
- \expandafter\XINT_sum_loop\expandafter
- {\romannumeral0\expandafter
- \XINT_addr_A\expandafter0\expandafter{\expandafter}%
- \romannumeral0\XINT_RQ {}#1\R\R\R\R\R\R\R\R\Z
- \W\X\Y\Z #2\W\X\Y\Z }%
-}%
-\def\XINT_sum_N #1\Z #2#3%
-{%
- \expandafter\XINT_sum_NN\expandafter
- {\romannumeral0\expandafter
- \XINT_addr_A\expandafter0\expandafter{\expandafter}%
- \romannumeral0\XINT_RQ {}#1\R\R\R\R\R\R\R\R\Z
- \W\X\Y\Z #3\W\X\Y\Z }{#2}%
-}%
-\def\XINT_sum_NN #1#2{\XINT_sum_loop {#2}{#1}}%
+\def\XINT_sumexpr {\XINT_sum_loop_a 0\Z }%
+\def\XINT_sum_loop_a #1\Z #2%
+ {\expandafter\XINT_sum_loop_b \romannumeral-`0#2\Z #1\Z \Z}%
+\def\XINT_sum_loop_b #1%
+ {\xint_gob_til_relax #1\XINT_sum_finished\relax\XINT_sum_loop_c #1}%
+\def\XINT_sum_loop_c
+ {\expandafter\XINT_sum_loop_a\romannumeral0\XINT_add_fork }%
+\def\XINT_sum_finished #1\Z #2\Z \Z { #2}%
% \end{macrocode}
% \subsection{\csh{xintiiPrd}}
% \lverb|&
-% \xintPrd {{a}...{z}}$\
-% \xintPrdExpr {a}...{z}\relax$\
+% \xintiiPrd {{a}...{z}}$\
+% \xintiiPrdExpr {a}...{z}\relax$\
% Release 1.02 modified the product routine. The earlier version was faster in
% situations where each new term is bigger than the product of all previous
% terms, a situation which arises in the algorithm for computing powers. The
@@ -19077,119 +19076,16 @@ $1$ or $-1$.
% \begin{macrocode}
\def\xintiiPrd {\romannumeral0\xintiiprd }%
\def\xintiiprd #1{\xintiiprdexpr #1\relax }%
-\let\xintPrd\xintiiPrd
-\let\xintprd\xintiiprd
\def\xintiiPrdExpr {\romannumeral0\xintiiprdexpr }%
\def\xintiiprdexpr {\expandafter\XINT_prdexpr\romannumeral-`0}%
-\let\xintPrdExpr\xintiiPrdExpr
-\let\xintprdexpr\xintiiprdexpr
\def\XINT_prdexpr {\XINT_prod_loop_a 1\Z }%
\def\XINT_prod_loop_a #1\Z #2%
- {\expandafter\XINT_prod_loop_b \romannumeral-`0#2\Z #1\Z \Z}%
+ {\expandafter\XINT_prod_loop_b \romannumeral-`0#2\Z #1\Z \Z}%
\def\XINT_prod_loop_b #1%
{\xint_gob_til_relax #1\XINT_prod_finished\relax\XINT_prod_loop_c #1}%
\def\XINT_prod_loop_c
{\expandafter\XINT_prod_loop_a\romannumeral0\XINT_mul_fork }%
-\def\XINT_prod_finished #1\Z #2\Z \Z { #2}%
-% \end{macrocode}
-% \subsection{\csh{xintFac}}
-% \lverb|&
-% Modified with 1.02 and again in 1.03 for greater efficiency. I am
-% tempted,
-% here and elsewhere, to use \ifcase\XINT_Geq {#1}{1000000000} rather than
-% \ifnum\xintLength {#1}>9 but for the time being I leave things as they stand.
-% With release 1.05, rather than using \xintLength I opt finally for direct use
-% of \numexpr (which will throw a suitable number too big message), and to raise
-% the \xintError:$\ FactorialOfTooBigNumber for argument larger than 1000000
-% (rather than 1000000000). With 1.09a, \xintFac uses \xintnum.
-%
-% 1.09j for no special reason, I lower the maximal number from 999999 to 100000.
-% Any how this computation would need more memory than TL2013 standard allows to
-% TeX. And I don't even mention time... |
-% \begin{macrocode}
-\def\xintiFac {\romannumeral0\xintifac }%
-\def\xintifac #1%
-{%
- \expandafter\XINT_fac_fork\expandafter{\the\numexpr #1}%
-}%
-\let\xintFac\xintiFac \let\xintfac\xintifac
-\def\XINT_fac_fork #1%
-{%
- \ifcase\XINT_cntSgn #1\Z
- \xint_afterfi{\expandafter\space\expandafter 1\xint_gobble_i }%
- \or
- \expandafter\XINT_fac_checklength
- \else
- \xint_afterfi{\expandafter\xintError:FactorialOfNegativeNumber
- \expandafter\space\expandafter 1\xint_gobble_i }%
- \fi
- {#1}%
-}%
-\def\XINT_fac_checklength #1%
-{%
- \ifnum #1>100000
- \xint_afterfi{\expandafter\xintError:FactorialOfTooBigNumber
- \expandafter\space\expandafter 1\xint_gobble_i }%
- \else
- \xint_afterfi{\ifnum #1>\xint_c_ixixixix
- \expandafter\XINT_fac_big_loop
- \else
- \expandafter\XINT_fac_loop
- \fi }%
- \fi
- {#1}%
-}%
-\def\XINT_fac_big_loop #1{\XINT_fac_big_loop_main {10000}{#1}{}}%
-\def\XINT_fac_big_loop_main #1#2#3%
-{%
- \ifnum #1<#2
- \expandafter
- \XINT_fac_big_loop_main
- \expandafter
- {\the\numexpr #1+1\expandafter }%
- \else
- \expandafter\XINT_fac_big_docomputation
- \fi
- {#2}{#3{#1}}%
-}%
-\def\XINT_fac_big_docomputation #1#2%
-{%
- \expandafter \XINT_fac_bigcompute_loop \expandafter
- {\romannumeral0\XINT_fac_loop {9999}}#2\relax
-}%
-\def\XINT_fac_bigcompute_loop #1#2%
-{%
- \xint_gob_til_relax #2\XINT_fac_bigcompute_end\relax
- \expandafter\XINT_fac_bigcompute_loop\expandafter
- {\expandafter\XINT_mul_enter
- \romannumeral0\XINT_RQ {}#2\R\R\R\R\R\R\R\R\Z
- \Z\Z\Z\Z #1\W\W\W\W }%
-}%
-\def\XINT_fac_bigcompute_end #1#2#3#4#5%
-{%
- \XINT_fac_bigcompute_end_ #5%
-}%
-\def\XINT_fac_bigcompute_end_ #1\R #2\Z \W\X\Y\Z #3\W\X\Y\Z { #3}%
-\def\XINT_fac_loop #1{\XINT_fac_loop_main 1{1000}{#1}}%
-\def\XINT_fac_loop_main #1#2#3%
-{%
- \ifnum #3>#1
- \else
- \expandafter\XINT_fac_loop_exit
- \fi
- \expandafter\XINT_fac_loop_main\expandafter
- {\the\numexpr #1+1\expandafter }\expandafter
- {\romannumeral0\XINT_mul_Mr {#1}#2\Z\Z\Z\Z }%
- {#3}%
-}%
-\def\XINT_fac_loop_exit #1#2#3#4#5#6#7%
-{%
- \XINT_fac_loop_exit_ #6%
-}%
-\def\XINT_fac_loop_exit_ #1#2#3%
-{%
- \XINT_mul_M
-}%
+\def\XINT_prod_finished\relax\XINT_prod_loop_c #1\Z #2\Z \Z { #2}%
% \end{macrocode}
% \lverb|&
% &
@@ -19735,15 +19631,15 @@ $1$ or $-1$.
\def\xintisqrt {\expandafter\XINT_sqrt_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_pos #1\R\R\R\R\R\R\R\R\Z \W\W\W\W\W\W\W\W }%
+\def\XINT_sqrt_post #1#2{\XINT_dec_pos #1\Z }%
% \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<N, donc rounded->#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}% Lt <-> a<b
- { #1}{\XINT_dec_pos #1\R\R\R\R\R\R\R\R\Z \W\W\W\W\W\W\W\W }}%
-\def\xintisquareroot #1{\expandafter\XINT_sqrt_checkin\romannumeral0\xintnum{#1}\Z }%
+\def\XINT_sqrtr_post #1#2{\xintiiifLt {#2}{#1}{ #1}{\XINT_dec_pos #1\Z}}%
+\def\xintisquareroot #1%
+ {\expandafter\XINT_sqrt_checkin\romannumeral0\xintnum{#1}\Z }%
\def\xintiisquareroot #1{\expandafter\XINT_sqrt_checkin\romannumeral-`0#1\Z }%
\def\XINT_sqrt_checkin #1%
{%
@@ -19889,8 +19785,7 @@ $1$ or $-1$.
\def\XINT_sqrt_big_g #1#2%
{%
\expandafter\XINT_sqrt_big_j
- \romannumeral0\xintiidivision{#1}%
- {\romannumeral0\XINT_dbl_pos #2\R\R\R\R\R\R\R\Z \W\W\W\W\W\W\W }{#2}%
+ \romannumeral0\xintiidivision{#1}{\romannumeral0\XINT_dbl_pos #2\Z}{#2}%
}%
\def\XINT_sqrt_big_j #1%
{%
@@ -19920,6 +19815,19 @@ $1$ or $-1$.
{\expandafter\XINT_iie\the\numexpr #2\expandafter.\expandafter{\romannumeral-`0#1}}%
\def\XINT_iie #1.#2{\ifnum#1>\xint_c_ \xint_dothis{\xint_dsh {#2}{-#1}}\fi
\xint_orthat{ #2}}%
+% \end{macrocode}
+% \subsection{``Load \xintfracnameimp'' macros}
+% \lverb|Originally was used in \xintiiexpr. Transferred from xintfrac for 1.1.|
+% \begin{macrocode}
+\catcode`! 11
+\def\xintMax {\Did_you_mean_iiMax?or_load_xintfrac!}%
+\def\xintMin {\Did_you_mean_iiMin?or_load_xintfrac!}%
+\def\xintMaxof {\Did_you_mean_iMaxof?or_load_xintfrac!}%
+\def\xintMinof {\Did_you_mean_iMinof?or_load_xintfrac!}%
+\def\xintSum {\Did_you_mean_iiSum?or_load_xintfrac!}%
+\def\xintPrd {\Did_you_mean_iiPrd?or_load_xintfrac!}%
+\def\xintPrdExpr {\Did_you_mean_iiPrdExpr?or_load_xintfrac!}%
+\def\xintSumExpr {\Did_you_mean_iiSumExpr?or_load_xintfrac!}%
\XINT_restorecatcodes_endinput%
% \end{macrocode}
%\catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11
@@ -19994,21 +19902,14 @@ $1$ or $-1$.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintbinhex}%
- [2015/09/12 v1.1c Expandable binary and hexadecimal conversions (jfB)]%
+ [2015/10/10 v1.2 Expandable binary and hexadecimal conversions (jfB)]%
% \end{macrocode}
% \subsection{Constants, etc...}
% \lverb!v1.08!
% \begin{macrocode}
-\chardef\xint_c_xvi 16
-% \chardef\xint_c_ii^v 32 % already in xint.sty
-% \chardef\xint_c_ii^vi 64 % already in xint.sty
-\chardef\xint_c_ii^vii 128
-\mathchardef\xint_c_ii^viii 256
-\mathchardef\xint_c_ii^xii 4096
-\newcount\xint_c_ii^xv \xint_c_ii^xv 32768
-\newcount\xint_c_ii^xvi \xint_c_ii^xvi 65536
+\newcount\xint_c_ii^xv \xint_c_ii^xv 32768
+\newcount\xint_c_ii^xvi \xint_c_ii^xvi 65536
\newcount\xint_c_x^v \xint_c_x^v 100000
-\newcount\xint_c_x^ix \xint_c_x^ix 1000000000
\def\XINT_tmpa #1{\ifx\relax#1\else
\expandafter\edef\csname XINT_sdth_#1\endcsname
{\ifcase #1 0\or 1\or 2\or 3\or 4\or 5\or 6\or 7\or
@@ -20103,6 +20004,40 @@ $1$ or $-1$.
\csname XINT_sdtb_\the\numexpr #2-\xint_c_xvi*#1\endcsname
}%
% \end{macrocode}
+% \subsection{\csh{XINT_OQ}}
+% \lverb|Moved with release 1.2 from xintcore 1.1 as it is used only here.
+% Will be probably suppressed once I review the code of xintbinhex.|
+% \begin{macrocode}
+\def\XINT_OQ #1#2#3#4#5#6#7#8#9%
+{%
+ \xint_gob_til_R #9\XINT_OQ_end_a\R\XINT_OQ {#9#8#7#6#5#4#3#2#1}%
+}%
+\def\XINT_OQ_end_a\R\XINT_OQ #1#2\Z
+{%
+ \XINT_OQ_end_b #1\Z
+}%
+\def\XINT_OQ_end_b #1#2#3#4#5#6#7#8%
+{%
+ \xint_gob_til_R
+ #8\XINT_OQ_end_viii
+ #7\XINT_OQ_end_vii
+ #6\XINT_OQ_end_vi
+ #5\XINT_OQ_end_v
+ #4\XINT_OQ_end_iv
+ #3\XINT_OQ_end_iii
+ #2\XINT_OQ_end_ii
+ \R\XINT_OQ_end_i
+ \Z #2#3#4#5#6#7#8%
+}%
+\def\XINT_OQ_end_viii #1\Z #2#3#4#5#6#7#8#9\Z { #9}%
+\def\XINT_OQ_end_vii #1\Z #2#3#4#5#6#7#8#9\Z { #8#90000000}%
+\def\XINT_OQ_end_vi #1\Z #2#3#4#5#6#7#8#9\Z { #7#8#9000000}%
+\def\XINT_OQ_end_v #1\Z #2#3#4#5#6#7#8#9\Z { #6#7#8#900000}%
+\def\XINT_OQ_end_iv #1\Z #2#3#4#5#6#7#8#9\Z { #5#6#7#8#90000}%
+\def\XINT_OQ_end_iii #1\Z #2#3#4#5#6#7#8#9\Z { #4#5#6#7#8#9000}%
+\def\XINT_OQ_end_ii #1\Z #2#3#4#5#6#7#8#9\Z { #3#4#5#6#7#8#900}%
+\def\XINT_OQ_end_i \Z #1#2#3#4#5#6#7#8\Z { #1#2#3#4#5#6#7#80}%
+% \end{macrocode}
% \subsection{\csh{xintDecToHex}, \csh{xintDecToBin}}
% \lverb!v1.08!
% \begin{macrocode}
@@ -20668,7 +20603,7 @@ $1$ or $-1$.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintgcd}%
- [2015/09/12 v1.1c Euclide algorithm with xint package (jfB)]%
+ [2015/10/10 v1.2 Euclide algorithm with xint package (jfB)]%
% \end{macrocode}
% \subsection{\csh{xintGCD}, \csh{xintiiGCD}}
% \lverb|The macros of 1.09a benefits from the \xintnum which has been inserted
@@ -20918,8 +20853,8 @@ $1$ or $-1$.
\def\XINT_bezout_loop_b #1#2#3#4#5#6#7#8%
{%
\expandafter \XINT_bezout_loop_c \expandafter
- {\romannumeral0\xintiiadd{\XINT_Mul{#5}{#2}}{#7}}%
- {\romannumeral0\xintiiadd{\XINT_Mul{#6}{#2}}{#8}}%
+ {\romannumeral0\xintiiadd{\XINT_mul_fork #5\Z #2\Z}{#7}}%
+ {\romannumeral0\xintiiadd{\XINT_mul_fork #6\Z #2\Z}{#8}}%
{#1}{#3}{#4}{#5}{#6}%
}%
% \end{macrocode}
@@ -21370,8 +21305,7 @@ $1$ or $-1$.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintfrac}%
- [2015/09/12 v1.1c Expandable operations on fractions (jfB)]%
-\chardef\xint_c_xviii 18
+ [2015/10/10 v1.2 Expandable operations on fractions (jfB)]%
% \end{macrocode}
% \subsection{\csh{XINT_cntSgnFork}}
% \lverb|1.09i. Used internally, #1 must expand to \m@ne, \z@, or \@ne or
@@ -21481,137 +21415,168 @@ $1$ or $-1$.
% e only. The \xintexpr parser does accept uppercase E also. Ah, by the way,
% perhaps I should at least say what this macro does? (belated addition
% 2014/10/22...), before I forget! It prepares the fraction in the internal
-% format {exponent}{Numerator}{Denominator} where Denominator is at least 1.|
+% format {exponent}{Numerator}{Denominator} where Denominator is at least 1.
+%
+% 2015/10/09: this venerable macro from the early days (1.03, 2013/04/14) has
+% gotten a lifting for release 1.2. There were two kinds of issues:$newline
+%
+% 1) use of \W, \Z, \T delimiters was very poor choice as this could clash with
+% user input,
+%
+% 2) the new \XINT_frac_gen handles macros (possibly empty) in the input as
+% general as \A.\Be\C/\D.\Ee\F. The earlier version would not have expanded
+% the \B for example (only \A, \D, \C, \F).
+%
+% I wanted to make stricter the restricted A/B[N] case, doing no expansion of
+% B, but this clashed with some established uses in the documentation like
+% 1/\xintiiSqr{...}[0] for example. Thus I maintained it despite overhead of
+% having to go over A one more time. Careful also here about potential brace
+% removals if one does stuff like #1/#2#3[#4] regarding the #3. And while I
+% was at it I added \numexpr parsing of the N, which earlier was restricted to
+% be only explicit digits, and I even allowed [] with an empty N.
+%
+% This little event makes me think I should read again other remaining
+% portions my early code, as I was still learning TeX coding at that time.|
% \begin{macrocode}
\def\XINT_inFrac {\romannumeral0\XINT_infrac }%
\def\XINT_infrac #1%
{%
- \expandafter\XINT_infrac_ \romannumeral-`0#1[\W]\Z\T
+ \expandafter\XINT_infrac_fork\romannumeral-`0#1/\XINT_W[\XINT_W\XINT_T
}%
-\def\XINT_infrac_ #1[#2#3]#4\Z
+\def\XINT_infrac_fork #1[#2%
{%
- \xint_UDwfork
- #2\XINT_infrac_A
- \W\XINT_infrac_B
+ \xint_UDXINTWfork
+ #2\XINT_frac_gen
+ \XINT_W\XINT_infrac_res_a % strict A[N] or A/B[N] input
\krof
- #1[#2#3]#4%
+ #1[#2%
}%
-\def\XINT_infrac_A #1[\W]\T
+\def\XINT_infrac_res_a #1%
{%
- \XINT_frac #1/\W\Z
+ \xint_gob_til_zero #1\XINT_infrac_res_zero 0\XINT_infrac_res_b #1%
}%
-\def\XINT_infrac_B #1%
+\def\XINT_infrac_res_zero 0\XINT_infrac_res_b #1\XINT_T {{0}{0}{1}}%
+\def\XINT_infrac_res_b #1/#2%
{%
- \xint_gob_til_zero #1\XINT_infrac_Zero0\XINT_infrac_BB #1%
-}%
-\def\XINT_infrac_BB #1[\W]\T {\XINT_infrac_BC #1/\W\Z }%
-\def\XINT_infrac_BC #1/#2#3\Z
-{%
- \xint_UDwfork
- #2\XINT_infrac_BCa
- \W{\expandafter\XINT_infrac_BCb \romannumeral-`0#2}%
+ \xint_UDXINTWfork
+ #2\XINT_infrac_res_ca
+ \XINT_W\XINT_infrac_res_cb
\krof
- #3\Z #1\Z
+ #1/#2%
}%
-\def\XINT_infrac_BCa \Z #1[#2]#3\Z { {#2}{#1}{1}}%
-\def\XINT_infrac_BCb #1[#2]/\W\Z #3\Z { {#2}{#3}{#1}}%
-\def\XINT_infrac_Zero #1\T { {0}{0}{1}}%
+\def\XINT_infrac_res_ca #1[#2]/\XINT_W[\XINT_W\XINT_T
+ {\expandafter{\the\numexpr 0#2}{#1}{1}}%
+\def\XINT_infrac_res_cb #1/#2[%
+ {\expandafter\XINT_infrac_res_cc\romannumeral-`0#2~#1[}%
+\def\XINT_infrac_res_cc #1~#2[#3]/\XINT_W[\XINT_W\XINT_T
+ {\expandafter{\the\numexpr 0#3}{#2}{#1}}%
% \end{macrocode}
-% \subsection{\csh{XINT_frac}}
+% \subsection{\csh{XINT_frac_gen}}
% \lverb|Extended in 1.07 to recognize and accept scientific notation both at
% the numerator and (possible) denominator. Only a lowercase e will do here, but
-% uppercase E is possible within an \xintexpr..\relax |
+% uppercase E is possible within an \xintexpr..\relax
+%
+% Completely rewritten for 1.2 2015/10/10. It now is able to handles inputs
+% such as \A.\Be\C/\D.\Ee\F where each of \A, \B, \D, and \E may need
+% \fexpan sion and \C and \F will end up in \numexpr.|
% \begin{macrocode}
-\def\XINT_frac #1/#2#3\Z
+\def\XINT_frac_gen #1/#2%
{%
- \xint_UDwfork
- #2\XINT_frac_A
- \W{\expandafter\XINT_frac_U \romannumeral-`0#2}%
+ \xint_UDXINTWfork
+ #2\XINT_frac_gen_A
+ \XINT_W\XINT_frac_gen_B
\krof
- #3e\W\Z #1e\W\Z
+ #1/#2%
}%
-\def\XINT_frac_U #1e#2#3\Z
+\def\XINT_frac_gen_A #1/\XINT_W [\XINT_W {\XINT_frac_gen_C 0~1!#1ee.\XINT_W }%
+\def\XINT_frac_gen_B #1/#2/\XINT_W[%\XINT_W
{%
- \xint_UDwfork
- #2\XINT_frac_Ua
- \W{\XINT_frac_Ub #2}%
- \krof
- #3\Z #1\Z
+ \expandafter\XINT_frac_gen_Ba
+ \romannumeral-`0#2ee.\XINT_W\XINT_Z #1ee.%\XINT_W
}%
-\def\XINT_frac_Ua \Z #1/\W\Z {\XINT_frac_B #1.\W\Z {0}}%
-\def\XINT_frac_Ub #1/\W e\W\Z #2\Z {\XINT_frac_B #2.\W\Z {#1}}%
-\def\XINT_frac_B #1.#2#3\Z
+\def\XINT_frac_gen_Ba #1.#2%
{%
- \xint_UDwfork
- #2\XINT_frac_Ba
- \W{\XINT_frac_Bb #2}%
+ \xint_UDXINTWfork
+ #2\XINT_frac_gen_Bb
+ \XINT_W\XINT_frac_gen_Bc
\krof
- #3\Z #1\Z
+ #1.#2%
}%
-\def\XINT_frac_Ba \Z #1\Z {\XINT_frac_T {0}{#1}}%
-\def\XINT_frac_Bb #1.\W\Z #2\Z
+\def\XINT_frac_gen_Bb #1e#2e#3\XINT_Z
+ {\expandafter\XINT_frac_gen_C\the\numexpr 0#2~#1!}%
+\def\XINT_frac_gen_Bc #1.#2e%
{%
- \expandafter \XINT_frac_T \expandafter
- {\romannumeral0\xintlength {#1}}{#2#1}%
+ \expandafter\XINT_frac_gen_Bd\romannumeral-`0#2.#1e%
}%
-\def\XINT_frac_A e\W\Z {\XINT_frac_T {0}{1}{0}}%
-\def\XINT_frac_T #1#2#3#4e#5#6\Z
+\def\XINT_frac_gen_Bd #1.#2e#3e#4\XINT_Z
{%
- \xint_UDwfork
- #5\XINT_frac_Ta
- \W{\XINT_frac_Tb #5}%
- \krof
- #6\Z #4\Z {#1}{#2}{#3}%
+ \expandafter\XINT_frac_gen_C\the\numexpr 0#3-\romannumeral0\expandafter
+ \XINT_length_loop
+ 0.#1\xint_relax\xint_relax\xint_relax\xint_relax
+ \xint_relax\xint_relax\xint_relax\xint_relax\xint_bye~#2#1!%
}%
-\def\XINT_frac_Ta \Z #1\Z {\XINT_frac_C #1.\W\Z {0}}%
-\def\XINT_frac_Tb #1e\W\Z #2\Z {\XINT_frac_C #2.\W\Z {#1}}%
-\def\XINT_frac_C #1.#2#3\Z
+\def\XINT_frac_gen_C #1!#2.#3%
{%
- \xint_UDwfork
- #2\XINT_frac_Ca
- \W{\XINT_frac_Cb #2}%
+ \xint_UDXINTWfork
+ #3\XINT_frac_gen_Ca
+ \XINT_W\XINT_frac_gen_Cb
\krof
- #3\Z #1\Z
+ #1!#2.#3%
}%
-\def\XINT_frac_Ca \Z #1\Z {\XINT_frac_D {0}{#1}}%
-\def\XINT_frac_Cb #1.\W\Z #2\Z
+\def\XINT_frac_gen_Ca #1~#2!#3e#4e#5\XINT_T
{%
- \expandafter\XINT_frac_D\expandafter
- {\romannumeral0\xintlength {#1}}{#2#1}%
+ \expandafter\XINT_frac_gen_F\the\numexpr #4-#1\expandafter
+ ~\romannumeral0\XINT_num_loop
+ #2\xint_relax\xint_relax\xint_relax\xint_relax
+ \xint_relax\xint_relax\xint_relax\xint_relax\Z~#3~%
}%
-\def\XINT_frac_D #1#2#3#4#5#6%
+\def\XINT_frac_gen_Cb #1.#2e%
{%
- \expandafter \XINT_frac_E \expandafter
- {\the\numexpr -#1+#3+#4-#6\expandafter}\expandafter
- {\romannumeral0\XINT_num_loop #2%
- \xint_relax\xint_relax\xint_relax\xint_relax
- \xint_relax\xint_relax\xint_relax\xint_relax\Z }%
- {\romannumeral0\XINT_num_loop #5%
- \xint_relax\xint_relax\xint_relax\xint_relax
- \xint_relax\xint_relax\xint_relax\xint_relax\Z }%
+ \expandafter\XINT_frac_gen_Cc\romannumeral-`0#2.#1e%
}%
-\def\XINT_frac_E #1#2#3%
+\def\XINT_frac_gen_Cc #1.#2~#3!#4e#5e#6\XINT_T
{%
- \expandafter \XINT_frac_F #3\Z {#2}{#1}%
+ \expandafter\XINT_frac_gen_F\the\numexpr #5-#2-%
+ \romannumeral0\XINT_length_loop
+ 0.#1\xint_relax\xint_relax\xint_relax\xint_relax
+ \xint_relax\xint_relax\xint_relax\xint_relax\xint_bye\expandafter
+ ~\romannumeral0\XINT_num_loop
+ #3\xint_relax\xint_relax\xint_relax\xint_relax
+ \xint_relax\xint_relax\xint_relax\xint_relax\Z
+ ~#4#1~%
}%
-\def\XINT_frac_F #1%
+\def\XINT_frac_gen_F #1~#2%
{%
\xint_UDzerominusfork
- #1-\XINT_frac_Gdivisionbyzero
- 0#1\XINT_frac_Gneg
- 0-{\XINT_frac_Gpos #1}%
- \krof
+ #2-\XINT_frac_gen_Gdivbyzero
+ 0#2{\XINT_frac_gen_G -{}}%
+ 0-{\XINT_frac_gen_G {}#2}%
+ \krof #1~%
+}%
+\def\XINT_frac_gen_Gdivbyzero #1~~#2~%
+{%
+ \expandafter\XINT_frac_gen_Gdivbyzero_a
+ \romannumeral0\XINT_num_loop
+ #2\xint_relax\xint_relax\xint_relax\xint_relax
+ \xint_relax\xint_relax\xint_relax\xint_relax\Z~#1~%
}%
-\edef\XINT_frac_Gdivisionbyzero #1\Z #2#3%
+\def\XINT_frac_gen_Gdivbyzero_a #1~#2~%
{%
- \noexpand\xintError:DivisionByZero\space {0}{#2}{0}%
+ \xintError:DivisionByZero {#2}{#1}{0}%
}%
-\def\XINT_frac_Gneg #1\Z #2#3%
+\def\XINT_frac_gen_G #1#2#3~#4~#5~%
{%
- \expandafter\XINT_frac_H \expandafter{\romannumeral0\XINT_opp #2}{#3}{#1}%
+ \expandafter\XINT_frac_gen_Ga
+ \romannumeral0\XINT_num_loop
+ #1#5\xint_relax\xint_relax\xint_relax\xint_relax
+ \xint_relax\xint_relax\xint_relax\xint_relax\Z~#3~{#2#4}%
}%
-\def\XINT_frac_H #1#2{ {#2}{#1}}%
-\def\XINT_frac_Gpos #1\Z #2#3{ {#3}{#2}{#1}}%
+\def\XINT_frac_gen_Ga #1#2~#3~%
+{%
+ \xint_gob_til_zero #1\XINT_frac_gen_zero 0%
+ {#3}{#1#2}%
+}%
+\def\XINT_frac_gen_zero 0#1#2#3{{0}{0}{1}}%
% \end{macrocode}
% \subsection{\csh{XINT_factortens}, \csh{XINT_cuz_cnt}}
% \begin{macrocode}
@@ -21709,6 +21674,102 @@ $1$ or $-1$.
\xint_relax }{#1}%
}%
% \end{macrocode}
+% \subsection{\csh{XINT_addm_A}}
+% \lverb|This is a routine from xintcore 1.0x, which is needed by \xintFloat,
+% \XINTinFloat and \xintRound, for the time being. I should moved it here, now
+% that xintcore has been entirely rewritten with release 1.2.|
+% \begin{macrocode}
+\def\XINT_addm_A #1#2#3#4#5#6%
+{%
+ \xint_gob_til_W #3\xint_addm_az\W
+ \XINT_addm_AB #1{#3#4#5#6}{#2}%
+}%
+\def\xint_addm_az\W\XINT_addm_AB #1#2%
+{%
+ \XINT_addm_AC_checkcarry #1%
+}%
+\def\XINT_addm_AB #1#2#3#4\W\X\Y\Z #5#6#7#8%
+{%
+ \XINT_addm_ABE #1#2{#8#7#6#5}{#3}#4\W\X\Y\Z
+}%
+\def\XINT_addm_ABE #1#2#3#4#5#6%
+{%
+ \expandafter\XINT_addm_ABEA\the\numexpr #1+10#5#4#3#2+#6.%
+}%
+\def\XINT_addm_ABEA #1#2#3.#4%
+{%
+ \XINT_addm_A #2{#3#4}%
+}%
+\def\XINT_addm_AC_checkcarry #1%
+{%
+ \xint_gob_til_zero #1\xint_addm_AC_nocarry 0\XINT_addm_C
+}%
+\def\xint_addm_AC_nocarry 0\XINT_addm_C #1#2\W\X\Y\Z
+{%
+ \expandafter
+ \xint_cleanupzeros_andstop
+ \romannumeral0%
+ \XINT_rord_main {}#2%
+ \xint_relax
+ \xint_bye\xint_bye\xint_bye\xint_bye
+ \xint_bye\xint_bye\xint_bye\xint_bye
+ \xint_relax
+ #1%
+}%
+\def\XINT_addm_C #1#2#3#4#5%
+{%
+ \xint_gob_til_W
+ #5\xint_addm_cw
+ #4\xint_addm_cx
+ #3\xint_addm_cy
+ #2\xint_addm_cz
+ \W\XINT_addm_CD {#5#4#3#2}{#1}%
+}%
+\def\XINT_addm_CD #1%
+{%
+ \expandafter\XINT_addm_CC\the\numexpr 1+10#1.%
+}%
+\def\XINT_addm_CC #1#2#3.#4%
+{%
+ \XINT_addm_AC_checkcarry #2{#3#4}%
+}%
+\def\xint_addm_cw
+ #1\xint_addm_cx
+ #2\xint_addm_cy
+ #3\xint_addm_cz
+ \W\XINT_addm_CD
+{%
+ \expandafter\XINT_addm_CDw\the\numexpr 1+#1#2#3.%
+}%
+\def\XINT_addm_CDw #1.#2#3\X\Y\Z
+{%
+ \XINT_addm_end #1#3%
+}%
+\def\xint_addm_cx
+ #1\xint_addm_cy
+ #2\xint_addm_cz
+ \W\XINT_addm_CD
+{%
+ \expandafter\XINT_addm_CDx\the\numexpr 1+#1#2.%
+}%
+\def\XINT_addm_CDx #1.#2#3\Y\Z
+{%
+ \XINT_addm_end #1#3%
+}%
+\def\xint_addm_cy
+ #1\xint_addm_cz
+ \W\XINT_addm_CD
+{%
+ \expandafter\XINT_addm_CDy\the\numexpr 1+#1.%
+}%
+\def\XINT_addm_CDy #1.#2#3\Z
+{%
+ \XINT_addm_end #1#3%
+}%
+\def\xint_addm_cz\W\XINT_addm_CD #1#2#3{\XINT_addm_end #1#3}%
+\edef\XINT_addm_end #1#2#3#4#5%
+ {\noexpand\expandafter\space\noexpand\the\numexpr #1#2#3#4#5\relax}%
+% \end{macrocode}
% \subsection{\csh{xintRaw}}
% \lverb|&
% 1.07: this macro simply prints in a user readable form the fraction after its
@@ -22175,8 +22236,8 @@ $1$ or $-1$.
\def\XINT_jrr_loop_b #1#2#3#4#5#6#7%
{%
\expandafter \XINT_jrr_loop_c \expandafter
- {\romannumeral0\xintiiadd{\XINT_Mul{#4}{#1}}{#6}}%
- {\romannumeral0\xintiiadd{\XINT_Mul{#5}{#1}}{#7}}%
+ {\romannumeral0\xintiiadd{\XINT_mul_fork #4\Z #1\Z}{#6}}%
+ {\romannumeral0\xintiiadd{\XINT_mul_fork #5\Z #1\Z}{#7}}%
{#2}{#3}{#4}{#5}%
}%
\def\XINT_jrr_loop_c #1#2%
@@ -22489,7 +22550,15 @@ $1$ or $-1$.
% D-|N| last digits from Q, etc.. we compare D-|N| with the length M of Q etc...
% (well in this last, very uncommon, branch, I stopped trying to optimize things
% and I even do an \xintnum to ensure a 0 if something comes out empty from
-% \xintDecSplit).@
+% \xintDecSplit).
+%
+% [2015/10/04] Although the explanations above are extremely clear, there are
+% just too complicated for me to be now able to understand them fully. I
+% miraculously managed to do the minimal changes (all happens between
+% \XINT_xtrunc_Q and \XINT_xtrunc_Pa) in order for \xintXTrunc to use the 1.2
+% division routine. Seems to work. But some thought should be given to how to
+% adapt \xintXTrunc for it to better use the abilities and characteristics of
+% the new division routines in xincore.@
% \begin{macrocode}
\def\xintXTrunc #1#2%
{%
@@ -22615,33 +22684,7 @@ $1$ or $-1$.
\expandafter\XINT_xtrunc_negNC\expandafter
{\the\numexpr\xintLength {#1}-#2}{#1}%
}%
-\def\XINT_xtrunc_Q #1%
-{%
- \expandafter\XINT_xtrunc_prepare_I
- \romannumeral0\XINT_dsx_zeroloop {#1}{}\Z
-}%
-\def\XINT_xtrunc_prepare_I #1.#2#3%
-{%
- \expandafter\XINT_xtrunc_prepareB_aa\expandafter
- {\romannumeral0\xintlength {#2}}{#2}{#1}%
-}%
-\def\XINT_xtrunc_prepareB_aa #1%
-{%
- \ifnum #1=\xint_c_i
- \expandafter\XINT_xtrunc_prepareB_onedigit
- \else
- \expandafter\XINT_xtrunc_prepareB_PaBa
- \fi
- {#1}%
-}%
-\def\XINT_xtrunc_prepareB_onedigit #1#2%
-{%
- \ifcase#2
- \or\expandafter\XINT_xtrunc_BisOne
- \or\expandafter\XINT_xtrunc_BisTwo
- \else\expandafter\XINT_xtrunc_prepareB_PaBe
- \fi {000}{0}{4}{#2}%
-}%
+%%%%%%%%%%%%
\def\XINT_xtrunc_BisOne #1#2#3#4#5#6#7%
{%
#5.\romannumeral0\expandafter\XINT_dsx_zeroloop\expandafter
@@ -22661,48 +22704,76 @@ $1$ or $-1$.
0000000000000000000000000000000000000000000000000000000000000000%
\repeat
}%
-\def\XINT_xtrunc_prepareB_PaBa #1#2%
+%%%%%%%%%%%%
+\def\XINT_xtrunc_Q #1%
+{%
+ \expandafter\XINT_xtrunc_prepare
+ \romannumeral0\XINT_dsx_zeroloop {#1}{}\Z
+}%
+\def\XINT_xtrunc_prepare #1.#2#3%
{%
\expandafter\XINT_xtrunc_Pa\expandafter
- {\romannumeral0\XINT_xtrunc_prepareB_a {#1}{#2}}%
+ {\romannumeral0%
+ \XINT_xtrunc_prepare_a #2\R\R\R\R\R\R\R\R {10}0000001\W !{#2}}{#1}%
}%
-\def\XINT_xtrunc_prepareB_a #1%
+%%%%%%%%%%%%
+\def\XINT_xtrunc_prepare_a #1#2#3#4#5#6#7#8#9%
{%
- \expandafter\XINT_xtrunc_prepareB_c\expandafter
- {\the\numexpr \xint_c_iv*((#1+\xint_c_i)/\xint_c_iv)}{#1}%
+ \xint_gob_til_R #9\XINT_xtrunc_prepare_small\R
+ \XINT_xtrunc_prepare_b #9%
}%
-\def\XINT_xtrunc_prepareB_c #1#2%
+\def\XINT_xtrunc_prepare_small\R #1!#2%
{%
- \csname XINT_xtrunc_prepareB_d\romannumeral\numexpr#1-#2\endcsname
- {#1}%
+ \ifcase #2
+ \or\xint_afterfi{ \XINT_div_BisOne}%
+ \or\xint_afterfi{ \XINT_div_BisTwo}%
+ \else\expandafter\XINT_xtrunc_small_aa
+ \fi {#2}%
}%
-\def\XINT_xtrunc_prepareB_d {\XINT_xtrunc_prepareB_e {}{0000}}%
-\def\XINT_xtrunc_prepareB_di {\XINT_xtrunc_prepareB_e {0}{000}}%
-\def\XINT_xtrunc_prepareB_dii {\XINT_xtrunc_prepareB_e {00}{00}}%
-\def\XINT_xtrunc_prepareB_diii {\XINT_xtrunc_prepareB_e {000}{0}}%
-\def\XINT_xtrunc_prepareB_PaBe #1#2#3#4%
+\def\XINT_xtrunc_small_aa #1%
{%
- \expandafter\XINT_xtrunc_Pa\expandafter
- {\romannumeral0\XINT_xtrunc_prepareB_e {#1}{#2}{#3}{#4}}%
+ \expandafter\space\expandafter\XINT_xtrunc_small_a
+ \the\numexpr #1/\xint_c_ii\expandafter
+ .\the\numexpr \xint_c_x^viii+#1!%
}%
-\def\XINT_xtrunc_prepareB_e #1#2#3#4%
+%%%%%%%%%%%%
+\def\XINT_xtrunc_small_a #1.#2!#3%
{%
- \ifnum#3=\xint_c_iv\expandafter\XINT_xtrunc_prepareLittleB_f
- \else\expandafter\XINT_xtrunc_prepareB_f
- \fi
- #4#1{#3}{#2}{#1}%
+ \expandafter\XINT_div_small_b\the\numexpr #1\expandafter
+ .\the\numexpr #2\expandafter!%
+ \romannumeral0\XINT_div_small_ba #3\R\R\R\R\R\R\R\R{10}0000001\W
+ #3\XINT_sepbyviii_Z_end 2345678\relax
}%
-\def\XINT_xtrunc_prepareB_f #1#2#3#4#5#{%
- \expandafter\space
- \expandafter\XINT_div_prepareB_g
- \the\numexpr #1#2#3#4+\xint_c_i\expandafter
- .\the\numexpr (#1#2#3#4+\xint_c_i)/\xint_c_ii\expandafter
- .\romannumeral0\xintreverseorder {#1#2#3#4#5}.{#1#2#3#4}%
+%%%%%%%%%%%%
+\def\XINT_xtrunc_prepare_b
+ {\expandafter\XINT_xtrunc_prepare_c\romannumeral0\XINT_zeroes_forviii }%
+\def\XINT_xtrunc_prepare_c #1!%
+{%
+ \XINT_xtrunc_prepare_d #1.00000000!{#1}%
}%
-\def\XINT_xtrunc_prepareLittleB_f #1#{%
- \expandafter\space\expandafter
- \XINT_div_prepareB_g \the\numexpr #1/\xint_c_ii.{}.{}.{#1}%
+\def\XINT_xtrunc_prepare_d #1#2#3#4#5#6#7#8#9%
+{%
+ \expandafter\XINT_xtrunc_prepare_e\xint_gob_til_dot #1#2#3#4#5#6#7#8#9!%
+}%
+\def\XINT_xtrunc_prepare_e #1!#2!#3#4%
+{%
+ \XINT_xtrunc_prepare_f #4#3\X {#1}{#3}%
}%
+\def\XINT_xtrunc_prepare_f #1#2#3#4#5#6#7#8#9\X
+{%
+ \expandafter\space\expandafter\XINT_div_prepare_g
+ \the\numexpr #1#2#3#4#5#6#7#8+\xint_c_i\expandafter
+ .\the\numexpr (#1#2#3#4#5#6#7#8+\xint_c_i)/\xint_c_ii\expandafter
+ .\the\numexpr #1#2#3#4#5#6#7#8\expandafter
+ .\romannumeral0\XINT_sepandrev_andcount
+ #1#2#3#4#5#6#7#8#9\XINT_rsepbyviii_end_A 2345678%
+ \XINT_rsepbyviii_end_B 2345678%
+ \relax\xint_c_ii\xint_c_iii
+ \R.\xint_c_vi\R.\xint_c_v\R.\xint_c_iv\R.\xint_c_iii
+ \R.\xint_c_ii\R.\xint_c_i\R.\xint_c_\W
+ \X
+}%
+%%%%%%%%%%%%
\def\XINT_xtrunc_Pa #1#2%
{%
\expandafter\XINT_xtrunc_Pb\romannumeral0#1{#2}{#1}%
@@ -22758,10 +22829,7 @@ $1$ or $-1$.
% gains. The earlier version was seriously silly when dealing with
% inputs having a big power of ten. Again some modifications in 1.08b
% for a better treatment of cases with long explicit numerators or
-% denominators.
-%
-% Here again some inner macros used the \xintiquo with extra \xintnum overhead
-% in 1.09a, 1.09f reinstalled use of \xintiiquo without this overhead.|
+% denominators.|
% \begin{macrocode}
\def\xintFloat {\romannumeral0\xintfloat }%
\def\xintfloat #1{\XINT_float_chkopt #1\xint_relax }%
@@ -23147,7 +23215,7 @@ $1$ or $-1$.
}%
\def\XINT_fadd_C #1#2#3%
{%
- \ifcase\romannumeral0\XINT_cmp_pre {#2}{#3} %<- intentional space here.
+ \ifcase\romannumeral0\xintiicmp {#2}{#3} %<- intentional space here.
\expandafter\XINT_fadd_eq
\or\expandafter\XINT_fadd_D
\else\expandafter\XINT_fadd_Da
@@ -23636,8 +23704,8 @@ $1$ or $-1$.
\def\XINT_minof_e #1\Z #2\Z { #2}%
% \end{macrocode}
% \subsection{\csh{xintCmp}}
-% \lverb|Rewritten completely in 1.08a to be less dumb when comparing fractions having
-% big powers of tens.|
+% \lverb|Rewritten completely in 1.08a to be less dumb when comparing
+% fractions having big powers of tens.|
% \begin{macrocode}
%\def\xintCmp {\romannumeral0\xintcmp }%
\def\xintcmp #1%
@@ -23708,32 +23776,42 @@ $1$ or $-1$.
\expandafter\XINT_fcmp_Fe\expandafter
{\romannumeral0\XINT_dsx_addzerosnofuss {#1}{#3}}{#2}%
}%
-\def\XINT_fcmp_Fe #1#2{\XINT_cmp_pre {#2}{#1}}%
+\def\XINT_fcmp_Fe #1#2{\xintiicmp {#2}{#1}}%
\def\XINT_fcmp_Fn #1\Z #2#3%
{%
- \expandafter\XINT_cmp_pre\expandafter
+ \expandafter\xintiicmp\expandafter
{\romannumeral0\XINT_dsx_addzerosnofuss {#1}{#2}}{#3}%
}%
% \end{macrocode}
% \subsection{\csh{xintAbs}}
-% \lverb|Simplified in 1.09i. (original macro had been written before \xintRaw)|
% \begin{macrocode}
\def\xintAbs {\romannumeral0\xintabs }%
\def\xintabs #1{\expandafter\XINT_abs\romannumeral0\xintraw {#1}}%
% \end{macrocode}
% \subsection{\csh{xintOpp}}
-% \lverb|caution that -#1 would not be ok if #1 has [n]
-% stuff. Simplified in 1.09i. (original macro had been written before \xintRaw)|
% \begin{macrocode}
\def\xintOpp {\romannumeral0\xintopp }%
\def\xintopp #1{\expandafter\XINT_opp\romannumeral0\xintraw {#1}}%
% \end{macrocode}
% \subsection{\csh{xintSgn}}
-% \lverb|Simplified in 1.09i. (original macro had been written before \xintRaw)|
% \begin{macrocode}
\def\xintSgn {\romannumeral0\xintsgn }%
\def\xintsgn #1{\expandafter\XINT_sgn\romannumeral0\xintraw {#1}\Z }%
% \end{macrocode}
+% \subsection{Floating point macros}
+% \begin{framed}
+% 1.2 release has not touched the floating point routines apart from adding
+% the new \csh{xintFloatFac}. The others should be revised for some
+% optimizations related to the underlying model of the new core routines.
+% This is particularly the case for \csh{xintFloatPow} and
+% \csh{xintFloatPower} which should keep intermediate results in a suitable
+% format, like \csh{xintiiPow} does.
+%
+% The switch to 1.2 was smooth (apart from the writing up of the new
+% \csh{xintFloatFac}), as I didn't have to change a single line of code
+% anywhere here !
+% \end{framed}
+%
% \subsection{\csh{xintFloatAdd}, \csh{XINTinFloatAdd}}
% \lverb|1.07; 1.09ka improves a bit the efficieny of the coding of
% \XINT_FL_Add_d.|
@@ -23810,6 +23888,10 @@ $1$ or $-1$.
}%
% \end{macrocode}
% \subsection{\csh{xintFloatMul}, \csh{XINTinFloatMul}}
+% \begin{framed}
+% It is a long-standing issue here that I must at some point revise the code
+% and avoid compute with 2P digits the exact intermediate result.
+% \end{framed}
% \lverb|1.07|
% \begin{macrocode}
\def\xintFloatMul {\romannumeral0\xintfloatmul}%
@@ -23874,6 +23956,11 @@ $1$ or $-1$.
\def\XINT_FL_Div_b #1[#2]#3[#4]{\xintE{#3/#1}{#4-#2}}%
% \end{macrocode}
% \subsection{\csh{xintFloatPow}, \csh{XINTinFloatPow}}
+% \begin{framed}
+% This definitely should be revised to better take into account the new
+% multiplication to maintain through intermediate states a suitable internal
+% format, optimized for calls to \csh{XINT_mul_loop}.
+% \end{framed}
% \lverb|1.07. Release 1.09j has re-organized the core loop, and
% \XINT_flpow_prd sub-routine has been removed.|
% \begin{macrocode}
@@ -24144,6 +24231,215 @@ $1$ or $-1$.
#4{#3}{#5}%
}%
% \end{macrocode}
+% \subsection{\csh{xintFloatFac}, \csh{XINTFloatFac}}
+% \lverb|1.2. Je dois documenter le raisonnement sur la précision à imposer
+% pour les calculs par blocs de huit faits en sous-main. Par ailleurs j'ai été
+% amené à une routine smallmul spéciale.|
+% \begin{macrocode}
+\def\xintFloatFac {\romannumeral0\xintfloatfac}%
+\def\xintfloatfac #1{\XINT_flfac_chkopt \xintfloat #1\xint_relax }%
+\def\XINTinFloatFac {\romannumeral0\XINTinfloatfac }%
+\def\XINTinfloatfac #1{\XINT_flfac_chkopt \XINTinfloat #1\xint_relax }%
+\def\XINT_flfac_chkopt #1#2%
+{%
+ \ifx [#2\expandafter\XINT_flfac_opt
+ \else\expandafter\XINT_flfac_noopt
+ \fi
+ #1#2%
+}%
+\def\XINT_flfac_noopt #1#2\xint_relax
+{%
+ \expandafter\XINT_FL_fac_start\expandafter
+ {\the\numexpr #2}{\XINTdigits}{#1[\XINTdigits]}%
+}%
+\def\XINT_flfac_opt #1[\xint_relax #2]#3%
+{%
+ \expandafter\XINT_FL_fac_start\expandafter
+ {\the\numexpr #3\expandafter}\expandafter{\the\numexpr#2}{#1[#2]}%
+}%
+\def\XINT_FL_fac_start #1%
+{%
+ \ifcase\XINT_cntSgn #1\Z
+ \expandafter\XINT_FL_fac_iszero
+ \or
+ \expandafter\XINT_FL_fac_increaseP
+ \else
+ \expandafter\XINT_FL_fac_isneg
+ \fi {#1}%
+}%
+\def\XINT_FL_fac_iszero #1#2#3{#3{1/1[0]}}%
+\def\XINT_FL_fac_isneg #1#2#3%
+ {\expandafter\xintError:FactorialOfNegativeNumber #3{1/1[0]}}%
+\def\XINT_FL_fac_increaseP #1#2%
+{%
+ \expandafter\XINT_FL_fac_fork
+ \the\numexpr \xint_c_viii*%
+ ((\xint_c_v+#2+\XINT_FL_fac_extradigits #187654321\Z)/\xint_c_viii).%
+ #1.%
+}%
+\def\XINT_FL_fac_extradigits #1#2#3#4#5#6#7#8{\XINT_FL_fac_extra_a }%
+\def\XINT_FL_fac_extra_a #1#2\Z {#1}%
+\def\XINT_FL_fac_fork #1.#2.#3%
+{%
+ \ifnum #2>99999999 \xint_dothis{\XINT_FL_fac_toobig }\fi
+ \ifnum #2>9999 \xint_dothis{\XINT_FL_fac_vbigloop_a }\fi
+ \ifnum #2>465 \xint_dothis{\XINT_FL_fac_bigloop_a }\fi
+ \ifnum #2>101 \xint_dothis{\XINT_FL_fac_medloop_a }\fi
+ \xint_orthat{\XINT_FL_fac_smallloop_a }%
+ #2.#1.{\XINT_FL_fac_out}{#3}%
+}%
+\def\XINT_FL_fac_toobig #1.#2.#3#4%
+ {\expandafter\xintError:FactorialOfTooBigNumber #4{1/1[0]}}%
+\def\XINT_FL_fac_out #1\Z![#2]#3{#3{\romannumeral0\XINT_mul_out
+ #1\Z!1\R!1\R!1\R!1\R!1\R!1\R!1\R!1\R!\W [#2]}}%
+\def\XINT_FL_fac_vbigloop_a #1.#2.%
+{%
+ \XINT_FL_fac_bigloop_a 9999.#2.%
+ {\expandafter\XINT_FL_fac_vbigloop_loop\the\numexpr 100010000\expandafter.%
+ \the\numexpr \xint_c_x^viii+#1.}%
+}%
+\def\XINT_FL_fac_vbigloop_loop #1.#2.%
+{%
+ \ifnum #1>#2 \expandafter\XINT_FL_fac_loop_exit\fi
+ \expandafter\XINT_FL_fac_vbigloop_loop
+ \the\numexpr #1+\xint_c_i\expandafter.%
+ \the\numexpr #2\expandafter.\the\numexpr\XINT_FL_fac_mul #1!%
+}%
+\def\XINT_FL_fac_bigloop_a #1.%
+{%
+ \expandafter\XINT_FL_fac_bigloop_b \the\numexpr
+ #1+\xint_c_i-\xint_c_ii*((#1-464)/\xint_c_ii).#1.%
+}%
+\def\XINT_FL_fac_bigloop_b #1.#2.#3.%
+{%
+ \expandafter\XINT_FL_fac_medloop_a
+ \the\numexpr #1-\xint_c_i.#3.{\XINT_FL_fac_bigloop_loop #1.#2.}%
+}%
+\def\XINT_FL_fac_bigloop_loop #1.#2.%
+{%
+ \ifnum #1>#2 \expandafter\XINT_FL_fac_loop_exit\fi
+ \expandafter\XINT_FL_fac_bigloop_loop
+ \the\numexpr #1+\xint_c_ii\expandafter.%
+ \the\numexpr #2\expandafter.\the\numexpr\XINT_FL_fac_bigloop_mul #1!%
+}%
+\def\XINT_FL_fac_bigloop_mul #1!%
+{%
+ \expandafter\XINT_FL_fac_mul
+ \the\numexpr \xint_c_x^viii+#1*(#1+\xint_c_i)!%
+}%
+\def\XINT_FL_fac_medloop_a #1.%
+{%
+ \expandafter\XINT_FL_fac_medloop_b
+ \the\numexpr #1+\xint_c_i-\xint_c_iii*((#1-100)/\xint_c_iii).#1.%
+}%
+\def\XINT_FL_fac_medloop_b #1.#2.#3.%
+{%
+ \expandafter\XINT_FL_fac_smallloop_a
+ \the\numexpr #1-\xint_c_i.#3.{\XINT_FL_fac_medloop_loop #1.#2.}%
+}%
+\def\XINT_FL_fac_medloop_loop #1.#2.%
+{%
+ \ifnum #1>#2 \expandafter\XINT_FL_fac_loop_exit\fi
+ \expandafter\XINT_FL_fac_medloop_loop
+ \the\numexpr #1+\xint_c_iii\expandafter.%
+ \the\numexpr #2\expandafter.\the\numexpr\XINT_FL_fac_medloop_mul #1!%
+}%
+\def\XINT_FL_fac_medloop_mul #1!%
+{%
+ \expandafter\XINT_FL_fac_mul
+ \the\numexpr
+ \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)!%
+}%
+\def\XINT_FL_fac_smallloop_a #1.%
+{%
+ \csname
+ XINT_FL_fac_smallloop_\the\numexpr #1-\xint_c_iv*(#1/\xint_c_iv)\relax
+ \endcsname #1.%
+}%
+\expandafter\def\csname XINT_FL_fac_smallloop_1\endcsname #1.#2.%
+{%
+ \XINT_FL_fac_addzeros #2.100000001!.{2.#1.}{#2}%
+}%
+\expandafter\def\csname XINT_FL_fac_smallloop_-2\endcsname #1.#2.%
+{%
+ \XINT_FL_fac_addzeros #2.100000002!.{3.#1.}{#2}%
+}%
+\expandafter\def\csname XINT_FL_fac_smallloop_-1\endcsname #1.#2.%
+{%
+ \XINT_FL_fac_addzeros #2.100000006!.{4.#1.}{#2}%
+}%
+\expandafter\def\csname XINT_FL_fac_smallloop_0\endcsname #1.#2.%
+{%
+ \XINT_FL_fac_addzeros #2.100000024!.{5.#1.}{#2}%
+}%
+\def\XINT_FL_fac_addzeros #1.%
+{%
+ \ifnum #1=\xint_c_viii \expandafter\XINT_FL_fac_addzeros_exit\fi
+ \expandafter\XINT_FL_fac_addzeros\the\numexpr #1-\xint_c_viii.100000000!%
+}%
+\def\XINT_FL_fac_addzeros_exit #1.#2.#3#4%
+ {\XINT_FL_fac_smallloop_loop #3#21\Z![-#4]}%
+\def\XINT_FL_fac_smallloop_loop #1.#2.%
+{%
+ \ifnum #1>#2 \expandafter\XINT_FL_fac_loop_exit\fi
+ \expandafter\XINT_FL_fac_smallloop_loop
+ \the\numexpr #1+\xint_c_iv\expandafter.%
+ \the\numexpr #2\expandafter.\romannumeral0\XINT_FL_fac_smallloop_mul #1!%
+}%
+\def\XINT_FL_fac_smallloop_mul #1!%
+{%
+ \expandafter\XINT_FL_fac_mul
+ \the\numexpr
+ \xint_c_x^viii+#1*(#1+\xint_c_i)*(#1+\xint_c_ii)*(#1+\xint_c_iii)!%
+}%[[
+\def\XINT_FL_fac_loop_exit #1!#2]#3{#3#2]}%
+\def\XINT_FL_fac_mul 1#1!%
+ {\expandafter\XINT_FL_fac_mul_a\the\numexpr\XINT_FL_fac_smallmul 10!{#1}}%
+\def\XINT_FL_fac_mul_a #1-#2%
+{%
+ \if#21\xint_afterfi{\expandafter\space\xint_gob_til_exclam}\else
+ \expandafter\space\fi #11\Z!%
+}%
+\def\XINT_FL_fac_minimulwc_a #1#2#3#4#5!#6#7#8#9%
+{%
+ \XINT_FL_fac_minimulwc_b {#1#2#3#4}{#5}{#6#7#8#9}%
+}%
+\def\XINT_FL_fac_minimulwc_b #1#2#3#4!#5%
+{%
+ \expandafter\XINT_FL_fac_minimulwc_c
+ \the\numexpr \xint_c_x^ix+#5+#2*#4.{{#1}{#2}{#3}{#4}}%
+}%
+\def\XINT_FL_fac_minimulwc_c 1#1#2#3#4#5#6.#7%
+{%
+ \expandafter\XINT_FL_fac_minimulwc_d {#1#2#3#4#5}#7{#6}%
+}%
+\def\XINT_FL_fac_minimulwc_d #1#2#3#4#5%
+{%
+ \expandafter\XINT_FL_fac_minimulwc_e
+ \the\numexpr \xint_c_x^ix+#1+#2*#5+#3*#4.{#2}{#4}%
+}%
+\def\XINT_FL_fac_minimulwc_e 1#1#2#3#4#5#6.#7#8#9%
+{%
+ 1#6#9\expandafter!%
+ \the\numexpr\expandafter\XINT_FL_fac_smallmul
+ \the\numexpr \xint_c_x^viii+#1#2#3#4#5+#7*#8!%
+}%
+\def\XINT_FL_fac_smallmul 1#1!#21#3!%
+{%
+ \xint_gob_til_Z #3\XINT_FL_fac_smallmul_end\Z
+ \XINT_FL_fac_minimulwc_a #2!#3!{#1}{#2}%
+}%
+\def\XINT_FL_fac_smallmul_end\Z\XINT_FL_fac_minimulwc_a #1!\Z!#2#3[#4]%
+{%
+ \ifnum #2=\xint_c_
+ \expandafter\xint_firstoftwo\else
+ \expandafter\xint_secondoftwo
+ \fi
+ {-2\relax[#4]}%
+ {1#2\expandafter!\expandafter-\expandafter1\expandafter
+ [\the\numexpr #4+\xint_c_viii]}%
+}%
+% \end{macrocode}
% \subsection{\csh{xintFloatSqrt}, \csh{XINTinFloatSqrt}}
% \lverb|1.08|
% \begin{macrocode}
@@ -24295,7 +24591,7 @@ $1$ or $-1$.
{%
\expandafter\XINT_flsqrt_big_j
\romannumeral0\xintiidivision
- {#1}{\romannumeral0\XINT_dbl_pos #2\R\R\R\R\R\R\R\Z \W\W\W\W\W\W\W }{#2}%
+ {#1}{\romannumeral0\XINT_dbl_pos #2\Z}{#2}%
}%
\def\XINT_flsqrt_big_j #1%
{%
@@ -24307,8 +24603,8 @@ $1$ or $-1$.
\def\XINT_flsqrt_big_k #1#2#3%
{%
\expandafter\XINT_flsqrt_big_l\expandafter
- {\romannumeral0\XINT_sub_pre {#3}{#1}}%
- {\romannumeral0\xintiiadd {#2}{\romannumeral0\XINT_sqr {#1}}}%
+ {\romannumeral0\xintiisub {#3}{#1}}%
+ {\romannumeral0\xintiiadd {#2}{\romannumeral0\XINT_sqr #1\Z}}%
}%
\def\XINT_flsqrt_big_l #1#2%
{%
@@ -24398,7 +24694,7 @@ $1$ or $-1$.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintseries}%
- [2015/09/12 v1.1c Expandable partial sums with xint package (jfB)]%
+ [2015/10/10 v1.2 Expandable partial sums with xint package (jfB)]%
% \end{macrocode}
% \subsection{\csh{xintSeries}}
% \lverb|&
@@ -24903,7 +25199,7 @@ $1$ or $-1$.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintcfrac}%
- [2015/09/12 v1.1c Expandable continued fractions with xint package (jfB)]%
+ [2015/10/10 v1.2 Expandable continued fractions with xint package (jfB)]%
% \end{macrocode}
% \subsection{\csh{xintCFrac}}
% \begin{macrocode}
@@ -25362,8 +25658,8 @@ $1$ or $-1$.
\expandafter\XINT_ctf_loop_c\expandafter
{\romannumeral0\XINT_mul_fork #2\Z #4\Z }%
{\romannumeral0\XINT_mul_fork #2\Z #3\Z }%
- {\romannumeral0\xintiiadd {\XINT_Mul {#2}{#6}}{\XINT_Mul {#1}{#4}}}%
- {\romannumeral0\xintiiadd {\XINT_Mul {#2}{#5}}{\XINT_Mul {#1}{#3}}}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\Z #6\Z}{\XINT_mul_fork #1\Z #4\Z}}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\Z #5\Z}{\XINT_mul_fork #1\Z #3\Z}}%
}%
\def\XINT_ctf_loop_c #1#2%
{%
@@ -25399,8 +25695,8 @@ $1$ or $-1$.
\def\XINT_icstf_loop_b #1.#2#3#4#5%
{%
\expandafter\XINT_icstf_loop_c\expandafter
- {\romannumeral0\xintiiadd {#5}{\XINT_Mul {#1}{#3}}}%
- {\romannumeral0\xintiiadd {#4}{\XINT_Mul {#1}{#2}}}%
+ {\romannumeral0\xintiiadd {#5}{\XINT_mul_fork #1\Z #3\Z}}%
+ {\romannumeral0\xintiiadd {#4}{\XINT_mul_fork #1\Z #2\Z}}%
{#2}{#3}%
}%
\def\XINT_icstf_loop_c #1#2%
@@ -25430,8 +25726,8 @@ $1$ or $-1$.
\expandafter\XINT_gctf_loop_c\expandafter
{\romannumeral0\XINT_mul_fork #2\Z #4\Z }%
{\romannumeral0\XINT_mul_fork #2\Z #3\Z }%
- {\romannumeral0\xintiiadd {\XINT_Mul {#2}{#6}}{\XINT_Mul {#1}{#4}}}%
- {\romannumeral0\xintiiadd {\XINT_Mul {#2}{#5}}{\XINT_Mul {#1}{#3}}}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\Z #6\Z}{\XINT_mul_fork #1\Z #4\Z}}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\Z #5\Z}{\XINT_mul_fork #1\Z #3\Z}}%
}%
\def\XINT_gctf_loop_c #1#2%
{%
@@ -25492,8 +25788,8 @@ $1$ or $-1$.
\def\XINT_igctf_loop_b #1.#2#3#4#5%
{%
\expandafter\XINT_igctf_loop_c\expandafter
- {\romannumeral0\xintiiadd {#5}{\XINT_Mul {#1}{#3}}}%
- {\romannumeral0\xintiiadd {#4}{\XINT_Mul {#1}{#2}}}%
+ {\romannumeral0\xintiiadd {#5}{\XINT_mul_fork #1\Z #3\Z}}%
+ {\romannumeral0\xintiiadd {#4}{\XINT_mul_fork #1\Z #2\Z}}%
{#2}{#3}%
}%
\def\XINT_igctf_loop_c #1#2%
@@ -25553,8 +25849,8 @@ $1$ or $-1$.
\expandafter\XINT_ctcv_loop_c\expandafter
{\romannumeral0\XINT_mul_fork #2\Z #4\Z }%
{\romannumeral0\XINT_mul_fork #2\Z #3\Z }%
- {\romannumeral0\xintiiadd {\XINT_Mul {#2}{#6}}{\XINT_Mul {#1}{#4}}}%
- {\romannumeral0\xintiiadd {\XINT_Mul {#2}{#5}}{\XINT_Mul {#1}{#3}}}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\Z #6\Z}{\XINT_mul_fork #1\Z #4\Z}}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\Z #5\Z}{\XINT_mul_fork #1\Z #3\Z}}%
}%
\def\XINT_ctcv_loop_c #1#2%
{%
@@ -25596,8 +25892,8 @@ $1$ or $-1$.
\def\XINT_icstcv_loop_b #1.#2#3#4#5%
{%
\expandafter\XINT_icstcv_loop_c\expandafter
- {\romannumeral0\xintiiadd {#5}{\XINT_Mul {#1}{#3}}}%
- {\romannumeral0\xintiiadd {#4}{\XINT_Mul {#1}{#2}}}%
+ {\romannumeral0\xintiiadd {#5}{\XINT_mul_fork #1\Z #3\Z}}%
+ {\romannumeral0\xintiiadd {#4}{\XINT_mul_fork #1\Z #2\Z}}%
{{#2}{#3}}%
}%
\def\XINT_icstcv_loop_c #1#2%
@@ -25633,8 +25929,8 @@ $1$ or $-1$.
\expandafter\XINT_gctcv_loop_c\expandafter
{\romannumeral0\XINT_mul_fork #2\Z #4\Z }%
{\romannumeral0\XINT_mul_fork #2\Z #3\Z }%
- {\romannumeral0\xintiiadd {\XINT_Mul {#2}{#6}}{\XINT_Mul {#1}{#4}}}%
- {\romannumeral0\xintiiadd {\XINT_Mul {#2}{#5}}{\XINT_Mul {#1}{#3}}}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\Z #6\Z}{\XINT_mul_fork #1\Z #4\Z}}%
+ {\romannumeral0\xintiiadd {\XINT_mul_fork #2\Z #5\Z}{\XINT_mul_fork #1\Z #3\Z}}%
}%
\def\XINT_gctcv_loop_c #1#2%
{%
@@ -25705,8 +26001,8 @@ $1$ or $-1$.
\def\XINT_igctcv_loop_b #1.#2#3#4#5%
{%
\expandafter\XINT_igctcv_loop_c\expandafter
- {\romannumeral0\xintiiadd {#5}{\XINT_Mul {#1}{#3}}}%
- {\romannumeral0\xintiiadd {#4}{\XINT_Mul {#1}{#2}}}%
+ {\romannumeral0\xintiiadd {#5}{\XINT_mul_fork #1\Z #3\Z}}%
+ {\romannumeral0\xintiiadd {#4}{\XINT_mul_fork #1\Z #2\Z}}%
{{#2}{#3}}%
}%
\def\XINT_igctcv_loop_c #1#2%
@@ -26029,6 +26325,32 @@ $1$ or $-1$.
% retrieving data expandably as \emph{names} of control sequences. Intermediate
% computation results are stored as control sequences |\.=a/b[n]|.
%
+% Release |1.2| |[2015/10/10]| has the following changes:
+% \begin{description}
+% \item[not anymore limited to 5000
+% digits:] |1.2| replaces chains of |\romannumeral-`0| used earlier to
+% gather digits by |\csname| governed expansions. The use of
+% |\csname.=A/B[N]\endcsname| storage has been part of the design from the
+% start, hence it was very natural and not too hard to gather the number
+% directly inside |\csname|. With the chains of |\romannumeral-`0| gone,
+% there is no more a limit at about 5000 (with the standard settings of the
+% maximal expansion depth at 10000) on the maximal number of digits for each
+% gathered number.
+% \item[faster gathering of digits:] the previous item and some other changes
+% have accelerated the building up of numbers.
+% \item[optional accelerated parsing:] the new functions |qint|, |qfrac|,
+% |qfloat| allow to skip entirely the digit by digit parsing and hand over
+% directly responsability to \csa{xintiNum}, \csa{xintRaw}, or
+% \csa{xintFloat} respectively.
+% \item[float factorial:] the factorial operator |!| maps to the new macro
+% \csa{xintFloatFac} inside \csa{xintfloatexpr}.
+% \item[isolated dot now illegal:] the decimal mark must have digits either
+% before or after it, an isolated |.| is now illegal input.
+% \item[more recognized tokens:] |\ht|, |\dp|, |\wd|, |\fontcharht|,
+% |\fontcharwd|, |\fontchardp| and |\fontcharit| are recognized and prefixed
+% with |\number| automatically.
+% \end{description}
+%
% Release |1.1| |[2014/10/28]| has made many extensions, some bug fixes, and
% some breaking changes:
% \begin{description}
@@ -26302,18 +26624,52 @@ $1$ or $-1$.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintexpr}%
- [2015/09/12 v1.1c Expandable expression parser (jfB)]%
+ [2015/10/10 v1.2 Expandable expression parser (jfB)]%
+\catcode`! 11
% \end{macrocode}
% \subsection{Locking and unlocking}
-% je dois réfléchir si je dois bloquer expansion après |unlock_a|, à
-% cause de nil.
-% \begin{macrocode}
-\def\xint_gob_til_! #1!{}% this ! has catcode 11
-\edef\XINT_expr_lockscan#1!{\noexpand\expandafter\space\noexpand\csname .=#1\endcsname }%
-\edef\XINT_expr_lockit #1{\noexpand\expandafter\space\noexpand\csname .=#1\endcsname }%
-\def\XINT_expr_inintpart #1!{\XINT_num{#1}}%
-\def\XINT_expr_infracpart #1e#2!{#1![\the\numexpr#2-\xintLength{#1}]!}%
-\def\XINT_expr_inexppart e#1!{![\the\numexpr #1]!}%
+% \lverb|Some renaming and modifications here with release 1.2 to switch from
+% using chains of \romannumeral-`0 in order to gather numbers, possibly
+% hexadecimals, to using a \csname governed expansion. In this way no more
+% limit at 5000 digits, and besides this is a logical move because the
+% \xintexpr parser is already based on \csname...\endcsname storage of numbers
+% as one token.
+%
+% The limitation at 5000 digits didn't worry me too much because it was not
+% very realistic to launch computations with thousands of digits... such
+% computations are still slow with 1.2 but less so now. Chains or
+% \romannumeral are still used for the gathering of function names and other
+% stuff which I have half-forgotten because the parser does many things.
+%
+% In the earlier versions we used the lockscan macro after a chain of
+% \romannumeral-`0 had ended gathering digits; this uses has been replaced by
+% direct processing inside a \csname...\endcsname and the macro is kept only
+% for matters of dummy variables.
+%
+% Currently, the parsing of hexadecimal numbers needs two nested
+% \csname...\endcsname, first to gather the letters (possibly with a hexadecimal
+% fractional part), and in a second stage to apply \xintHexToDec to do the
+% actual conversion. This should be faster than updating on the fly the number
+% (which would be hard for the fraction part...). The macro \xintHexToDec
+% could probably be made faster by using techniques similar as the ones v1.2
+% uses in xintcore.sty.|
+% \begin{macrocode}
+\def\xint_gob_til_! #1!{}% catcode 11 ! default in xintexpr.sty code.
+\edef\XINT_expr_lockscan#1!% not used for decimal numbers in xintexpr 1.2
+ {\noexpand\expandafter\space\noexpand\csname .=#1\endcsname }%
+\edef\XINT_expr_lockit
+ #1{\noexpand\expandafter\space\noexpand\csname .=#1\endcsname }%
+\def\XINT_expr_unlock_hex_in #1% expanded inside \csname..\endcsname
+ {\expandafter\XINT_expr_inhex\romannumeral-`0\XINT_expr_unlock#1;}%
+\def\XINT_expr_inhex #1.#2#3;% expanded inside \csname..\endcsname
+{%
+ \if#2>\xintHexToDec{#1}%
+ \else
+ \xintiiMul{\xintiiPow{625}{\xintLength{#3}}}{\xintHexToDec{#1#3}}%
+ [\the\numexpr-4*\xintLength{#3}]%
+ \fi
+}%
+%%%%%%%%%%%%
\def\XINT_expr_unlock {\expandafter\XINT_expr_unlock_a\string }%
\def\XINT_expr_unlock_a #1.={}%
\def\XINT_expr_unexpectedtoken {\xintError:ignored }%
@@ -26395,7 +26751,7 @@ $1$ or $-1$.
\def\xintiieval {\expandafter\XINT_iiexpr_wrap\romannumeral0\xintbareiieval }%
% \end{macrocode}
% \subsection{\csh{xintieval}, \csh{XINT_iexpr_wrap}}
-% \lverb|Optional argument since 1.1|
+% \lverb|Optional argument since 1.1.|
% \begin{macrocode}
\def\xintieval #1%
{\ifx [#1\expandafter\XINT_iexpr_withopt\else\expandafter\XINT_iexpr_noopt \fi #1}%
@@ -26592,16 +26948,23 @@ $1$ or $-1$.
#1%
}%
\def\XINT_expr_subexpr !#1\fi !{\expandafter\XINT_expr_getop\xint_gobble_iii }%
+% \end{macrocode}
+% \lverb|1.2 adds \ht, \dp, \wd and the eTeX font things.|
+% \begin{macrocode}
\def\XINT_expr_countetc #1%
{%
- \ifx\count#1\else\ifx#1\dimen\else\ifx#1\numexpr\else\ifx#1\dimexpr\else
- \ifx\skip#1\else\ifx\glueexpr#1\else\ifx\fontdimen#1\else
+ \ifx\count#1\else\ifx\dimen#1\else\ifx\numexpr#1\else\ifx\dimexpr#1\else
+ \ifx\skip#1\else\ifx\glueexpr#1\else\ifx\fontdimen#1\else\ifx\ht#1\else
+ \ifx\dp#1\else\ifx\wd#1\else\ifx\fontcharht#1\else\ifx\fontcharwd#1\else
+ \ifx\fontchardp#1\else\ifx\fontcharic#1\else
\XINT_expr_unpackvar
- \fi\fi\fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
\expandafter\XINT_expr_getnext\number #1%
}%
-\def\XINT_expr_unpackvar\fi\fi\fi\fi\fi\fi\fi\expandafter\XINT_expr_getnext\number #1%
- {\fi\fi\fi\fi\fi\fi\fi\expandafter\XINT_expr_getop\csname .=\number#1\endcsname }%
+\def\XINT_expr_unpackvar\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \expandafter\XINT_expr_getnext\number #1%
+ {\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \expandafter\XINT_expr_getop\csname .=\number#1\endcsname }%
\begingroup
\lccode`*=`#
\lowercase{\endgroup
@@ -26609,7 +26972,7 @@ $1$ or $-1$.
\if#1*\xint_dothis {\XINT_expr_scan_macropar *}\fi
\if#1[\xint_dothis {\xint_c_xviii ({}}\fi
\if#1+\xint_dothis \XINT_expr_getnext \fi
- \if#1.\xint_dothis {\XINT_expr_scandec_II\XINT_expr_infracpart}\fi
+ \if#1.\xint_dothis {\XINT_expr_startdec}\fi
\if#1-\xint_dothis -\fi
\if#1(\xint_dothis {\xint_c_xviii ({}}\fi
\xint_orthat {\XINT_expr_scan_nbr_or_func #1}%
@@ -26618,158 +26981,220 @@ $1$ or $-1$.
% \end{macrocode}
% \subsection{The integer or decimal number or hexa-decimal number or
% function name or variable name or special hacky things big parser}
+% \lverb|1.2 release has replaced chains of \romannumeral-`0 by \csname
+% governed expansion. Thus there is no more the limit at about 5000 digits for
+% parsed numbers.
+%
+% In order to avoid having to lock and unlock in succession to handle the
+% scientific part and adjust the exponent according to the number of digits of
+% the decimal part, the parsing of this decimal part counts on the fly the
+% number of digits it encounters.
+%
+% There is some slight annoyance with \xintiiexpr which should never be given
+% a [n] inside its \csname.=<digits>\endcsname storage of numbers (because its
+% arithmetic uses the ii macros which know nothing about the [N] notation).
+% Hence if the parser has only seen digits when hitting something else than
+% the dot or e (or E), it will not insert a [0]. Thus we very slightly
+% compromise the efficiency of \xintexpr and \xintfloatexpr in order to be
+% able to share the same code with \xintiiexpr.
+%
+% Indeed, the parser at this location is completely common to all, it does not
+% know if it is working inside \xintexpr or \xintiiexpr. On the other hand if
+% a dot or a e (or E) is met, then the (common) parser has no scrupules ending
+% this number with a [n], this will provoke an error later if that was within
+% an \xintiiexpr, as soon as an arithmetic macro is used.
+%
+% As the gathered numbers have no spaces, no pluses, no minuses, the only
+% remaining issue is with leading zeroes, which are discarded on the fly. The
+% hexadecimal numbers leading zeroes are stripped in a second stage by the
+% \xintHexToDec macro.
+%
+% With v1.2, \xinttheexpr . \relax does not work anymore (it did in earlier
+% releases). There must be digits either before or after the decimal mark. Thus
+% both \xinttheexpr 1.\relax and \xinttheexpr .1\relax are legal.|
% \begin{macrocode}
\catcode96 11 % `
\def\XINT_expr_scan_nbr_or_func #1% this #1 has necessarily here catcode 12
{%
\if "#1\xint_dothis \XINT_expr_scanhex_I\fi
\if `#1\xint_dothis {\XINT_expr_onlitteral_`}\fi
- \ifnum \xint_c_ix<1#1 \xint_dothis \XINT_expr_scandec_I\fi
+ \ifnum \xint_c_ix<1#1 \xint_dothis \XINT_expr_startint\fi
\xint_orthat \XINT_expr_scanfunc #1%
}%
\catcode96 12 % `
-\def\XINT_expr_scandec_I
-{%
- \expandafter\XINT_expr_getop\romannumeral-`0\expandafter
- \XINT_expr_lockscan\romannumeral0\expandafter\XINT_expr_inintpart
- \romannumeral-`0\XINT_expr_scanintpart_b
-}%
-\def\XINT_expr_scandec_II
+\def\XINT_expr_startint #1%
{%
- \expandafter\XINT_expr_getop\romannumeral-`0\expandafter
- \XINT_expr_lockscan\romannumeral0\expandafter\XINT_expr_inintpart
- \romannumeral-`0\XINT_expr_scanfracpart_b
+ \if #10\expandafter\XINT_expr_gobz_a\else\XINT_expr_scanint_a\fi #1%
}%
+\def\XINT_expr_scanint_a #1#2%
+ {\expandafter\XINT_expr_getop\csname.=#1%
+ \expandafter\XINT_expr_scanint_b\romannumeral-`0#2}%
+\def\XINT_expr_gobz_a #1%
+ {\expandafter\XINT_expr_getop\csname.=%
+ \expandafter\XINT_expr_gobz_scanint_b\romannumeral-`0#1}%
+\def\XINT_expr_startdec #1%
+ {\expandafter\XINT_expr_getop\csname.=%
+ \expandafter\XINT_expr_scandec_a\romannumeral-`0#1}%
% \end{macrocode}
-% \subsubsection{Integral part}
-% \begin{macrocode}
-\def\XINT_expr_scanintpart_a #1%
-{% careful that ! has catcode letter here
- \ifcat \relax #1\xint_dothis{!!#1}\fi % stops the scan
- \if e#1\xint_dothis{\expandafter\XINT_expr_inexppart
- \romannumeral-`0\XINT_expr_scanexppart_a e}\fi
- \if E#1\xint_dothis{\expandafter\XINT_expr_inexppart
- \romannumeral-`0\XINT_expr_scanexppart_a e}\fi
-% \end{macrocode}
-% \lverb|\if @#1\xint_dothis{!*#1}\fi % tacit multiplication later|
+% \subsubsection{Integral part (skipping zeroes)}
+% \lverb|Sub-expressions are recognized as startaing with catcode 11
+% exclamation mark, which is treated together with variable names composed of
+% letters below, hence induces a tacit multiplication if encountered while
+% gathering a number.
%
-% \lverb|\if _#1\xint_dothis{!*#1}\fi % tacit multiplication for variables|
+% 1.2 has modified the code to give highest priority to digits, the impact is
+% non-negligeable. I don't think the doubled \string is a serious penalty.|
% \begin{macrocode}
- \ifcat a#1\xint_dothis{!!*#1}\fi % includes subexpressions (#1=! letter)
- \xint_orthat {\expandafter\XINT_expr_scanintpart_aa\string #1}%
+\def\XINT_expr_scanint_b #1%
+{%
+ \ifcat \relax #1\expandafter\XINT_expr_scanint_endbycs\expandafter #1\fi
+ \ifnum\xint_c_ix<1\string#1 \else\expandafter\XINT_expr_scanint_c\fi
+ \string#1\XINT_expr_scanint_d
+}%
+\def\XINT_expr_scanint_d #1%
+{%
+ \expandafter\XINT_expr_scanint_b\romannumeral-`0#1%
+}%
+\def\XINT_expr_scanint_endbycs#1#2\XINT_expr_scanint_d{\endcsname #1}%
+\def\XINT_expr_scanint_c\string #1\XINT_expr_scanint_d
+{%
+ \if e#1\xint_dothis{[\the\numexpr0\XINT_expr_scanexp_a +}\fi
+ \if E#1\xint_dothis{[\the\numexpr0\XINT_expr_scanexp_a +}\fi
+ \ifcat a#1\xint_dothis{\endcsname*#1}\fi
+ \if .#1\xint_dothis{\XINT_expr_startdec_a .}\fi
+ \xint_orthat {\expandafter\endcsname \string#1}%
+}%
+\def\XINT_expr_startdec_a .#1%
+{%
+ \expandafter\XINT_expr_scandec_a\romannumeral-`0#1%
+}%
+\def\XINT_expr_scandec_a #1%
+{%
+ \if .#1\xint_dothis{\endcsname..}\fi
+ \xint_orthat {\XINT_expr_scandec_b 0.#1}%
+}%
+\def\XINT_expr_gobz_scanint_b #1%
+{%
+ \ifcat \relax #1\expandafter\XINT_expr_gobz_scanint_endbycs\expandafter #1\fi
+ \ifnum\xint_c_x<1\string#1 \else\expandafter\XINT_expr_gobz_scanint_c\fi
+ \string#1\XINT_expr_scanint_d
}%
-\def\XINT_expr_scanintpart_aa #1%
+\def\XINT_expr_gobz_scanint_endbycs#1#2\XINT_expr_scanint_d{0\endcsname #1}%
+\def\XINT_expr_gobz_scanint_c\string #1\XINT_expr_scanint_d
{%
- \if .#1\xint_dothis\XINT_expr_scandec_transition\fi
- \ifnum \xint_c_ix<1#1 \xint_dothis\XINT_expr_scanintpart_b\fi
- \xint_orthat {!!}#1%
+ \if e#1\xint_dothis{0[\the\numexpr0\XINT_expr_scanexp_a +}\fi
+ \if E#1\xint_dothis{0[\the\numexpr0\XINT_expr_scanexp_a +}\fi
+ \ifcat a#1\xint_dothis{0\endcsname*#1}\fi
+ \if .#1\xint_dothis{\XINT_expr_gobz_startdec_a .}\fi
+ \if 0#1\xint_dothis\XINT_expr_gobz_scanint_d\fi
+ \xint_orthat {0\expandafter\endcsname \string#1}%
}%
-\def\XINT_expr_scanintpart_b #1#2%
+\def\XINT_expr_gobz_scanint_d #1%
{%
- \expandafter #1\romannumeral-`0\expandafter
- \XINT_expr_scanintpart_a\romannumeral-`0#2%
+ \expandafter\XINT_expr_gobz_scanint_b\romannumeral-`0#1%
}%
-\def\XINT_expr_scandec_transition .#1%
+\def\XINT_expr_gobz_startdec_a .#1%
{%
- \expandafter\XINT_expr_scandec_trans_a\romannumeral-`0#1%
+ \expandafter\XINT_expr_gobz_scandec_a\romannumeral-`0#1%
}%
-\def\XINT_expr_scandec_trans_a #1%
+\def\XINT_expr_gobz_scandec_a #1%
{%
- \if .#1\xint_dothis{!!..}\fi
- \xint_orthat {\expandafter\XINT_expr_infracpart
- \romannumeral-`0\XINT_expr_scanfracpart_a #1}%
+ \if .#1\xint_dothis{0\endcsname..}\fi
+ \xint_orthat {\XINT_expr_gobz_scandec_b 0.#1}%
}%
% \end{macrocode}
% \subsubsection{Fractional part}
+% \lverb|Annoying duplication of code to allow 0. as input.|
% \begin{macrocode}
-\def\XINT_expr_scanfracpart_a #1%
+\def\XINT_expr_scandec_b #1.#2%
{%
- \ifcat \relax #1\xint_dothis{e!#1}\fi % stops the scan
- \if e#1\xint_dothis{\XINT_expr_scanexppart_a e}\fi
- \if E#1\xint_dothis{\XINT_expr_scanexppart_a e}\fi
- \ifcat a#1\xint_dothis{e!*#1}\fi % and also the case of subexpressions (!)
- \xint_orthat {\expandafter\XINT_expr_scanfracpart_aa\string #1}%
+ \ifcat \relax #2\expandafter\XINT_expr_scandec_endbycs\expandafter#2\fi
+ \ifnum\xint_c_ix<1\string#2 \else\expandafter\XINT_expr_scandec_c\fi
+ \string#2\expandafter\XINT_expr_scandec_d\the\numexpr #1-\xint_c_i.%
}%
-\def\XINT_expr_scanfracpart_aa #1%
+\def\XINT_expr_scandec_endbycs #1#2\XINT_expr_scandec_d
+ \the\numexpr#3-\xint_c_i.{[#3]\endcsname #1}%
+\def\XINT_expr_scandec_d #1.#2%
{%
- \ifnum \xint_c_ix<1#1
- \expandafter\XINT_expr_scanfracpart_b
- \else
- \xint_afterfi {e!}%
- \fi
- #1%
+ \expandafter\XINT_expr_scandec_b
+ \the\numexpr #1\expandafter.\romannumeral-`0#2%
}%
-\def\XINT_expr_scanfracpart_b #1#2%
+\def\XINT_expr_scandec_c\string #1#2\the\numexpr#3-\xint_c_i.%
{%
- \expandafter #1\romannumeral-`0\expandafter
- \XINT_expr_scanfracpart_a\romannumeral-`0#2%
+ \if e#1\xint_dothis{[\the\numexpr#3\XINT_expr_scanexp_a +}\fi
+ \if E#1\xint_dothis{[\the\numexpr#3\XINT_expr_scanexp_a +}\fi
+ \ifcat a#1\xint_dothis{[#3]\endcsname *#1}\fi
+ \xint_orthat {[#3]\expandafter\endcsname \string#1}%
+}%
+\def\XINT_expr_gobz_scandec_b 0.#1%
+{%
+ \ifcat \relax #1\expandafter\XINT_expr_gobz_scandec_endbycs\expandafter#1\fi
+ \ifnum\xint_c_ix<1\string#1 \else\expandafter\XINT_expr_gobz_scandec_c\fi
+ \string#1\expandafter\XINT_expr_scandec_d\the\numexpr\xint_c_mone.%
+}%
+\def\XINT_expr_gobz_scandec_endbycs #1#2\xint_c_mone.{0[0]\endcsname #1}%
+\def\XINT_expr_gobz_scandec_c\string #1#2\xint_c_mone.%
+{%
+ \if e#1\xint_dothis{0[\the\numexpr0\XINT_expr_scanexp_a +}\fi
+ \if E#1\xint_dothis{0[\the\numexpr0\XINT_expr_scanexp_a +}\fi
+ \ifcat a#1\xint_dothis{0[0]\endcsname *#1}\fi
+ \xint_orthat {0[0]\expandafter\endcsname \string#1}%
}%
% \end{macrocode}
% \subsubsection{Scientific notation}
+% \lverb|Some pluses and minuses are allowed at the start of the scientific
+% part, however not later, and no parenthesis.|
% \begin{macrocode}
-\def\XINT_expr_scanexppart_a #1#2%
+\def\XINT_expr_scanexp_a #1#2%
{%
- \expandafter #1\romannumeral-`0\expandafter
- \XINT_expr_scanexppart_b\romannumeral-`0#2%
+ #1\expandafter\XINT_expr_scanexp_b\romannumeral-`0#2%
}%
-\def\XINT_expr_scanexppart_b #1%
+\def\XINT_expr_scanexp_b #1%
{%
- \ifcat \relax #1\xint_dothis{0!#1}\fi % stops the scan (incorrect syntax)
- \ifcat a#1\xint_dothis{0!*#1}\fi % idem
- \if +#1\xint_dothis {\XINT_expr_scanexppart_a +}\fi
- \if -#1\xint_dothis {\XINT_expr_scanexppart_a -}\fi
- \xint_orthat {\expandafter\XINT_expr_scanexppart_c\string #1}%
+ \ifcat \relax #1\expandafter\XINT_expr_scanexp_endbycs\expandafter #1\fi
+ \ifnum\xint_c_ix<1\string#1 \else\expandafter\XINT_expr_scanexp_c\fi
+ \string#1\XINT_expr_scanexp_d
}%
-\def\XINT_expr_scanexppart_c #1%
+\def\XINT_expr_scanexpr_endbycs#1#2\XINT_expr_scanexp_d {]\endcsname #1}%
+\def\XINT_expr_scanexp_d #1%
{%
- \ifnum \xint_c_ix<1#1
- \expandafter\XINT_expr_scanexppart_d
- \else
- \expandafter !%
- \fi
- #1%
+ \expandafter\XINT_expr_scanexp_bb\romannumeral-`0#1%
}%
-\def\XINT_expr_scanexppart_d #1#2%
+\def\XINT_expr_scanexp_c\string #1\XINT_expr_scanexp_d
{%
- \expandafter #1\romannumeral-`0\expandafter
- \XINT_expr_scanexppart_e\romannumeral-`0#2%
+ \ifcat a#1\xint_dothis {]\endcsname *#1}\fi
+ \if +#1\xint_dothis {\XINT_expr_scanexp_a +}\fi
+ \if -#1\xint_dothis {\XINT_expr_scanexp_a -}\fi
+ \xint_orthat {]\expandafter\endcsname\string #1}%
}%
-\def\XINT_expr_scanexppart_e #1%
+\def\XINT_expr_scanexp_bb #1%
{%
- \ifcat \relax #1\xint_dothis{!#1}\fi % stops the scan
- \ifcat a#1\xint_dothis{!*#1}\fi % idem
- \xint_orthat {\expandafter\XINT_expr_scanexppart_f\string #1}%
+ \ifcat \relax #1\expandafter\XINT_expr_scanexp_endbycs_b\expandafter #1\fi
+ \ifnum\xint_c_ix<1\string#1 \else\expandafter\XINT_expr_scanexp_cb\fi
+ \string#1\XINT_expr_scanexp_db
}%
-\def\XINT_expr_scanexppart_f #1%
+\def\XINT_expr_scanexp_endbycs_b#1#2\XINT_expr_scanexp_db {]\endcsname #1}%
+\def\XINT_expr_scanexp_db #1%
{%
- \ifnum \xint_c_ix<1#1
- \expandafter\XINT_expr_scanexppart_d
- \else
- \expandafter !%
- \fi
- #1%
+ \expandafter\XINT_expr_scanexp_bb\romannumeral-`0#1%
+}%
+\def\XINT_expr_scanexp_cb\string #1\XINT_expr_scanexp_db
+{%
+ \ifcat a#1\xint_dothis {]\endcsname *#1}\fi
+ \xint_orthat {]\expandafter\endcsname\string #1}%
}%
% \end{macrocode}
% \subsubsection{Hexadecimal numbers}
% \begin{macrocode}
-\def\XINT_expr_scanhex_I #1%
-{%
- \expandafter\XINT_expr_getop\romannumeral-`0\expandafter
- \XINT_expr_lockscan\expandafter\XINT_expr_inhex
- \romannumeral-`0\XINT_expr_scanhexI_a
-}%
-\def\XINT_expr_inhex #1.#2#3;% expanded inside \csname..\endcsname
+\def\XINT_expr_scanhex_I #1% #1="
{%
- \if#2I\xintHexToDec{#1}%
- \else
- \xintiiMul{\xintiiPow{625}{\xintLength{#3}}}{\xintHexToDec{#1#3}}%
- [\the\numexpr-4*\xintLength{#3}]%
- \fi
+ \expandafter\XINT_expr_getop\csname.=\expandafter
+ \XINT_expr_unlock_hex_in\csname.=\XINT_expr_scanhexI_a
}%
\def\XINT_expr_scanhexI_a #1%
{%
- \ifcat #1\relax\xint_dothis{.I;!#1}\fi
- \ifx !#1\xint_dothis{.I;!*!}\fi % tacit multiplication
+ \ifcat #1\relax\xint_dothis{.>\endcsname\endcsname #1}\fi
+ \ifx !#1\xint_dothis{.>\endcsname\endcsname*!}\fi % tacit multiplication
\xint_orthat {\expandafter\XINT_expr_scanhexI_aa\string #1}%
}%
\def\XINT_expr_scanhexI_aa #1%
@@ -26787,24 +27212,23 @@ $1$ or $-1$.
\expandafter\xint_secondoftwo
\fi
{\expandafter\XINT_expr_scanhex_transition}%
- {\xint_afterfi {.I;!}}%
+ {\xint_afterfi {.>\endcsname\endcsname}}%
\fi
#1%
}%
\def\XINT_expr_scanhexI_b #1#2%
{%
- \expandafter #1\romannumeral-`0\expandafter
- \XINT_expr_scanhexI_a\romannumeral-`0#2%
+ #1\expandafter\XINT_expr_scanhexI_a\romannumeral-`0#2%
}%
\def\XINT_expr_scanhex_transition .#1%
{%
- \expandafter.\expandafter.\romannumeral-`0\expandafter
+ \expandafter.\expandafter.\expandafter
\XINT_expr_scanhexII_a\romannumeral-`0#1%
}%
\def\XINT_expr_scanhexII_a #1%
{%
- \ifcat #1\relax\xint_dothis{;!#1}\fi
- \ifx !#1\xint_dothis{;!*!}\fi % tacit multiplication
+ \ifcat #1\relax\xint_dothis{\endcsname\endcsname#1}\fi
+ \ifx !#1\xint_dothis{\endcsname\endcsname*!}\fi % tacit multiplication
\xint_orthat {\expandafter\XINT_expr_scanhexII_aa\string #1}%
}%
\def\XINT_expr_scanhexII_aa #1%
@@ -26816,14 +27240,13 @@ $1$ or $-1$.
0\else1\fi\else0\fi\else1\fi\else0\fi 1%
\expandafter\XINT_expr_scanhexII_b
\else
- \xint_afterfi {;!}%
+ \xint_afterfi {\endcsname\endcsname}%
\fi
#1%
}%
\def\XINT_expr_scanhexII_b #1#2%
{%
- \expandafter #1\romannumeral-`0\expandafter
- \XINT_expr_scanhexII_a\romannumeral-`0#2%
+ #1\expandafter\XINT_expr_scanhexII_a\romannumeral-`0#2%
}%
% \end{macrocode}
% \subsubsection{Function and variable names}
@@ -27684,22 +28107,25 @@ $1$ or $-1$.
}%
% \end{macrocode}
% \subsection{! as postfix factorial operator}
-% \lverb|As of 2014/11/07, not yet a float version of factorial. I must do it!|
+% \lverb|Float version was at last done 2015/10/06. As xint does not have yet
+% exp/log, Stirling is no go.|
% \begin{macrocode}
\let\XINT_expr_precedence_! \xint_c_x
\def\XINT_expr_op_! #1{\expandafter\XINT_expr_getop
\csname .=\xintFac{\XINT_expr_unlock #1}\endcsname }%
-\let\XINT_flexpr_op_!\XINT_expr_op_!
+\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
- \csname .=\xintiFac{\XINT_expr_unlock #1}\endcsname }%
+ \csname .=\xintiiFac{\XINT_expr_unlock #1}\endcsname }%
% \end{macrocode}
% \subsection{The A/B[N] mechanism}
% \lverb|Releases earlier than 1.1 required the use of braces around A/B[N]
-% input. The [N] is now implemented directly. *BUT* uses a delimited macro!
+% input. The [N] is now implemented directly. *BUT* this uses a delimited macro!
% thus N is not allowed to be itself an expression (I could add it...).
-% \xintE, \xintiiE, and \XINTinFloatE all put #2 in a \numexpr. BUT ATTENTION
-% TO CRAZYNESS OF NUMEXPR: \the\numexpr 3 + 7 9 \relax !! Hence we have to do
-% the job ourselves.|
+% \xintE, \xintiiE, and \XINTinFloatE all put #2 in a \numexpr. But attention
+% to the fact that \numexpr stops at spaces separating digits:
+% \the\numexpr 3 + 7 9\relax gives 109\relax !! Hence we have to be
+% careful.|
% \begin{macrocode}
\catcode`[ 11
\catcode`* 11
@@ -27742,7 +28168,7 @@ $1$ or $-1$.
% all high punctuation ?, !, :, ;.
%
% It is not recommended to overwrite single Latin letters which are
-% pre-defined to serve as dummy variables. Variable names may contains
+% pre-defined to serve as dummy variables. Variable names may contain
% letters, digits, underscores, and must not start with a digit.|
% \begin{macrocode}
\catcode`: 12
@@ -27848,7 +28274,7 @@ $1$ or $-1$.
}%
\expandafter\def\csname XINT_expr_onlitteral_`\endcsname #1#2#3({\xint_c_xviii `{#2}}%
% \end{macrocode}
-% \subsection{The bool, togl, protect, unknown, and break "functions"}
+% \subsection{The bool, togl, protect, unknown, and break ``functions''}
% \lverb|bool, togl and protect use delimited macros. Only unknown and break
% are true functions with a more flexible parsing of the opening and closing
% parentheses, which may possibly arise from expansion itself.|
@@ -27859,12 +28285,24 @@ $1$ or $-1$.
{\expandafter\XINT_expr_getop\csname .=\xintToggle{#1}\endcsname }%
\def\XINT_expr_onlitteral_protect #1)%
{\expandafter\XINT_expr_getop\csname .=\detokenize{#1}\endcsname }%
-\def\XINT_expr_func_unknown #1#2#3{\expandafter #1\expandafter #2\csname .=0\endcsname }%
+\def\XINT_expr_func_unknown #1#2#3%
+ {\expandafter #1\expandafter #2\csname .=0\endcsname }%
\def\XINT_expr_func_break #1#2#3%
-{\expandafter #1\expandafter #2\csname.=?\romannumeral-`0\XINT_expr_unlock #3\endcsname }%
+ {\expandafter #1\expandafter #2\csname.=?\romannumeral-`0\XINT_expr_unlock #3\endcsname }%
\let\XINT_flexpr_func_break \XINT_expr_func_break
\let\XINT_iiexpr_func_break \XINT_expr_func_break
% \end{macrocode}
+% \subsection{The qint, qfrac, qfloat ``functions''}
+% \lverb|New with 1.2. Allows the user to hand over quickly a big number to the
+% parser, spaces not immediately removed but should be harmless in general.|
+% \begin{macrocode}
+\def\XINT_expr_onlitteral_qint #1)%
+ {\expandafter\XINT_expr_getop\csname .=\xintiNum{#1}\endcsname }%
+\def\XINT_expr_onlitteral_qfrac #1)%
+ {\expandafter\XINT_expr_getop\csname .=\xintRaw{#1}\endcsname }%
+\def\XINT_expr_onlitteral_qfloat #1)%
+ {\expandafter\XINT_expr_getop\csname .=\XINTinFloatdigits{#1}\endcsname }%
+% \end{macrocode}
% \subsection{seq and the implementation of dummy variables}
% \lverb|All of seq, add, mul, rseq, etc... (actually all of the extensive
% changes from xintexpr 1.09n to 1.1) was done around June 15-25th 2014, but the
@@ -27921,9 +28359,9 @@ $1$ or $-1$.
\def\XINT_expr_onlitteral_seq_e #1#2{\XINT_expr_onlitteral_seq_d {#1}{#2)}}%
% \end{macrocode}
% \subsubsection{\csh{XINT_isbalanced_a} for \csh{XINT_expr_onlitteral_seq_a}}
-%\lverb|Expands to \m@ne in case a closing ) had no opening ( matching it, to
-% \@ne if opening ) had no closing ) matching it, to \z@ if expression was
-% balanced.|
+% \lverb|Expands to \xint_c_mone in case a closing ) had no opening ( matching
+% it, to \@ne if opening ) had no closing ) matching it, to \z@ if expression
+% was balanced.|
% \begin{macrocode}
% use as \XINT_isbalanced_a \relax #1(\xint_bye)\xint_bye
\def\XINT_isbalanced_a #1({\XINT_isbalanced_b #1)\xint_bye }%
@@ -27932,7 +28370,7 @@ $1$ or $-1$.
% \end{macrocode}
% \lverb|if #2 is not \xint_bye, a ) was found, but there was no (. Hence error -> -1|
% \begin{macrocode}
-\def\XINT_isbalanced_error #1)\xint_bye {\m@ne}%
+\def\XINT_isbalanced_error #1)\xint_bye {\xint_c_mone}%
% \end{macrocode}
% \lverb|#2 was \xint_bye, was there a ) in original #1?|
% \begin{macrocode}
@@ -28978,10 +29416,11 @@ $1$ or $-1$.
\romannumeral-`0\expandafter\XINT_xptwo_getab_b
\romannumeral-`0####2!{####1}{~xint#1}{xint#1}}%
}%
-}%
+}% cela aurait-il un sens d'ajouter Raw et iNum (à cause de qint, qfrac,
+ % 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,Fac,iFac,Bool,Toggle}\do
+ Odd,Even,iiOdd,iiEven,Opp,iiOpp,iiifZero,Fac,iiFac,Bool,Toggle}\do
{\toks0
\expandafter{\the\toks0%
\expandafter\let\csname xint#1NE\expandafter\endcsname\csname xint#1\expandafter
@@ -28989,6 +29428,13 @@ $1$ or $-1$.
\expandafter\XINT_NEfork_one\romannumeral-`0####1!{~xint#1}{xint#1}{}{}}%
}%
}%
+\toks0
+ \expandafter{\the\toks0
+ \let\XINTinFloatFacNE\XINTinFloatFac
+ \def\XINTinFloatFac ##1{%
+ \expandafter\XINT_NEfork_one
+ \romannumeral-`0##1!{~XINTinFloatFac}{XINTinFloatFac}{}{}}%
+ }%
\xintFor #1 in {Add,Sub,Mul,Div,Power,E,Mod,SeqA::csv}\do
{\toks0
\expandafter{\the\toks0%
@@ -29189,12 +29635,41 @@ $1$ or $-1$.
\def\mymacroaux #1#2{#2}%
%
\parbox[t]{10cm}{Total number of code lines:
- \dtt{\the\numexpr
- \xintListWithSep+{\xintApply\mymacro\storedlinecounts}\relax }. Each
- package starts
- with circa \dtt{50} lines dealing with catcodes, package identification
- and reloading management, also for Plain \TeX\strut. Version
- {\xintbndlversion} of {\xintbndldate}.\par}
+ \dtt{\the\numexpr
+ \xintListWithSep+{\xintApply\mymacro\storedlinecounts}\relax }.
+ Among those, release 1.2 has about 3000 lines starting with either
+ \{\% or \}\%.% en fait 3013 mais je devrais automatiser.
+
+ Each package starts with circa \dtt{50} lines dealing with catcodes,
+ package identification and reloading management, also for Plain
+ \TeX\strut. Version {\xintbndlversion} of {\xintbndldate}.\par
+}
+
+% il faut que je patche doc.sty pour faire ça automatiquement:
+%
+% TEMP$ grep -c -e "^{%" *sty
+% xint.sty:170
+% xintbinhex.sty:69
+% xintcfrac.sty:183
+% xintcore.sty:296
+% xintexpr.sty:133
+% xintfrac.sty:415
+% xintgcd.sty:59
+% xintkernel.sty:7
+% xintseries.sty:48
+% xinttools.sty:112
+%
+% TEMP$ grep -c -e "^}%" *sty
+% xint.sty:170
+% xintbinhex.sty:69
+% xintcfrac.sty:183
+% xintcore.sty:296
+% xintexpr.sty:163
+% xintfrac.sty:415
+% xintgcd.sty:61
+% xintkernel.sty:8
+% xintseries.sty:48
+% xinttools.sty:112
\CharacterTable
{Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
@@ -29211,7 +29686,7 @@ $1$ or $-1$.
Right bracket \] Circumflex \^ Underscore \_
Grave accent \` Left brace \{ Vertical bar \|
Right brace \} Tilde \~}
-\CheckSum {25543}
+\CheckSum {26711}%
\makeatletter\check@checksum\makeatother
\Finale
%% End of file xint.dtx