% -*- coding: iso-latin-1; time-stamp-format: "%02d-%02m-%:y at %02H:%02M:%02S %Z" -*- %<*dtx> \def\bnedtxtimestamp {Time-stamp: <14-10-2015 at 16:24:00 CEST>} \iffalse % %<*drv> %% --------------------------------------------------------------- \def\bnedocdate {2015/10/14} % package bnumexpr documentation date \def\bnepackdate{2015/10/14} % package bnumexpr date \def\bneversion {1.2a} % package bnumexpr version % %<*readme>-------------------------------------------------------- | Source: bnumexpr.dtx | Version: v1.2a, 2015/10/14 (doc: 2015/10/14) | Author: Jean-Francois Burnol | Info: Expressions with big integers | License: LPPL 1.3c or later README: [Usage], [Installation], [License] ========================================== Usage ----- The package `bnumexpr` allows _expandable_ computations with big integers, the four infix operators `+`, `-`, `*`, `/` (which does rounded division), the power operators `^` or `**`, the factorial `!`, the truncated division `//`, and its associated modulo `/:`. For example: \thebnumexpr (92874927979^5-3197927979^6)/30!\relax outputs `-4006240736596543944035189`. The `\relax` ending token is mandatory and will be removed as a result of the evaluation. The expression parser is scaled-down from `\xinttheiiexpr...\relax` from package xintexpr[^1], it does not handle boolean operators, conditional branching, variables and recognizes no functions. By default the underlying arithmetic macros are the ones provided by package xintcore[^1] (its release 1.2 is required). bnumexpr has only one option _custom_ which says to not load xintcore, and a command `\bnumexprsetup` to inform the package which macros to use if not those from xintcore. This is a breaking release: some options and commands from `v1.1` are not defined anymore (as `\bnumexprsetup` provides a new interface), and documents which used them will need updating. Notice that the possibility not to use the xintcore macros might be removed in the future: perhaps a future release will maintain during computations a private internal representation (especially taylored either for the xintcore macros or new ones which would be included within `bnumexpr.sty` itself) and the constraints this implies may render optional use of other macros impossible. [^1]: Installation ------------ Obtain `bnumexpr.dtx` (and possibly, `bnumexpr.ins` and the `README`) from CTAN: > Both `"tex bnumexpr.ins"` and `"tex bnumexpr.dtx"` extract from `bnumexpr.dtx` the following files: `bnumexpr.sty` : this is the style file. `README.md` : reconstitutes this README. `bnumexprchanges.tex` : lists changes from the initial version. `bnumexpr.tex` : can be used to generate the documentation: : - with latex+dvipdfmx: `"latex bnumexpr.tex"` (thrice) then `"dvipdfmx bnumexpr.dvi"`. : Ignore dvipdfmx warnings, but if the pdf file has problems with fonts (possibly from an old dvipdfmx), use then rather pdflatex. : - with pdflatex: `"pdflatex bnumexpr.tex"` (thrice). : In both cases files `README.md` and `bnumexprchanges.tex` must be present in the same repertory. without `bnumexpr.tex`: : `"pdflatex bnumexpr.dtx"` (thrice) extracts all files and simultaneously generates the pdf documentation. Finishing the installation: bnumexpr.sty --> TDS:tex/latex/bnumexpr/ bnumexpr.dtx --> TDS:source/latex/bnumexpr/ bnumexpr.ins --> TDS:source/latex/bnumexpr/ bnumexpr.pdf --> TDS:doc/latex/bnumexpr/ README --> TDS:doc/latex/bnumexpr/ Files `bnumexpr.tex`, `bnumexprchanges.tex`, `README.md` may be discarded. License ------- Copyright (C) 2014-2015 by Jean-Francois Burnol | This Work may be distributed and/or modified under the | conditions of the LaTeX Project Public License 1.3c. | This version of this license is in > | and version 1.3 or later is part of all distributions of | LaTeX version 2005/12/01 or later. This Work has the LPPL maintenance status "author-maintained". The Author and Maintainer of this Work is Jean-Francois Burnol. This Work consists of the main source file `bnumexpr.dtx` and the derived files bnumexpr.sty, bnumexpr.pdf, bnumexpr.ins, bnumexpr.tex, bnumexprchanges.tex, README.md %-------------------------------------------------------- %<*!readme> %% --------------------------------------------------------------- %% The bnumexpr package: Expressions with big integers %% Copyright (C) 2014-2015 by Jean-Francois Burnol %% % %<*changes>------------------------------------------------------- \item[1.2a (2015/10/14)] \begin{itemize} \item requires \xintcorename |1.2| or later (if not using option |custom|). \item additions to the syntax: factorial |!|, truncated division |//|, its associated modulo |/:| and |**| as alternative to |^|. \item all options removed except |custom|. \item new command |\bnumexprsetup| which replaces the commands such as |\bnumexprusesbigintcalc|. \item the parser is no more limited to numbers with at most 5000 digits. \end{itemize} \item[1.1b (2014/10/28)] \begin{itemize} \item README converted to |markdown/pandoc| syntax, \item the package now loads only |xintcore|, which belongs to |xint| bundle version |1.1| and extracts from the earlier |xint| package the core arithmetic operations as used by |bnumexpr|. \end{itemize} \item[1.1a (2014/09/22)] \begin{itemize} \item added |l3bigint| option to use experimental \LaTeX3 package of the same name, \item added Changes and Readme sections to the documentation, \item better |\BNE_protect| mechanism for use of |\bnumexpr...\relax| inside an |\edef| (without |\bnethe|). Previous one, inherited from |xintexpr.sty 1.09n|, assumed that the |\.=| dummy control sequence encapsulating the computation result had |\relax| meaning. But removing this assumption was only a matter of letting |\BNE_protect| protect two, not one, tokens. This will be backported to next version of \xintexprname, naturally (done with |xintexpr.sty 1.1|). \end{itemize} \item[1.1 (2014/09/21)] First release. This is down-scaled from the (development version of) \xintexprname. Motivation came the previous day from a chat with \textsc{Joseph Wright} over big int status in \LaTeX3. The |\bnumexpr...\relax| parser can be used on top of big int macros of one's choice. Functionalities limited to the basic operations. I leave the power operator |^| as an option. %------------------------------------------------------- %<*drv>----------------------------------------------------------- %% latex bnumexpr.tex (thrice) && dvipdfmx bnumexpr.dvi %% to produce bnumexpr.pdf %% %% or pdflatex bnumexpr.tex (no need to change \Withdvipdfmx toggle, %% pdf engine will be detected automatically) %% \NeedsTeXFormat{LaTeX2e} \ProvidesFile{bnumexpr.tex}% [\bnepackdate\space v\bneversion\space driver file for % bnumexpr documentation (jfB)]% \PassOptionsToClass{a4paper,fontsize=11pt}{scrdoc} \chardef\Withdvipdfmx 1 % \chardef\NoSourceCode 0 % replace 0 by 1 for not including source code \input bnumexpr.dtx %%% Local Variables: %%% mode: latex %%% End: %----------------------------------------------------------- %<*ins>----------------------------------------------------------- %% tex bnumexpr.ins will extract bnumexpr.sty from bnumexpr.dtx %% \input docstrip.tex \askforoverwritefalse \generate{\nopreamble\nopostamble \file{README.md}{\from{bnumexpr.dtx}{readme}} \usepreamble\defaultpreamble \usepostamble\defaultpostamble \file{bnumexprchanges.tex}{\from{bnumexpr.dtx}{changes}} \file{bnumexpr.tex}{\from{bnumexpr.dtx}{drv}} \file{bnumexpr.sty}{\from{bnumexpr.dtx}{package}}} \catcode32=13\relax% active space \let =\space% \Msg{************************************************************************} \Msg{*} \Msg{* To finish the installation you have to move the following} \Msg{* files into a directory searched by TeX:} \Msg{*} \Msg{* bnumexpr.sty} \Msg{*} \Msg{* To produce the documentation run latex thrice on bnumexpr.tex} \Msg{* then dvipdfmx on bnumexpr.dvi. (ignore the dvipdfmx warnings)} \Msg{*} \Msg{* Happy TeXing!} \Msg{*} \Msg{************************************************************************} \endbatchfile %----------------------------------------------------------- %<*dtx> \fi % end of \iffalse block around generated files \chardef\noetex 0 \ifx\numexpr\undefined \chardef\noetex 1 \fi \ifnum\noetex=1 \chardef\extractfiles 0 % extract files, then stop \else \ifx\ProvidesFile\undefined \chardef\extractfiles 0 % no LaTeX2e; etex, ... on bnumexpr.dtx \else % latex/pdflatex on bnumexpr.tex or on bnumexpr.dtx \ifx\Withdvipdfmx\undefined % latex run is on bnumexpr.dtx, we will extract all files \chardef\extractfiles 1 % 1 = extract and typeset, 2=only typeset \chardef\Withdvipdfmx 0 % 0 = pdflatex or latex+dvips, 1 = dvipdfmx \chardef\NoSourceCode 0 % 0 = include source code, 1 = do not \NeedsTeXFormat{LaTeX2e}% \PassOptionsToClass{a4paper,fontsize=11pt}{scrdoc}% \else % latex run is on bnumexpr.tex, \chardef\extractfiles 2 % no extractions \fi \ProvidesFile{bnumexpr.dtx}[bundle source (\bnedtxtimestamp)]% \fi \fi \ifnum\extractfiles<2 % extract files \def\MessageDeFin{\newlinechar10 \let\Msg\message \Msg{^^J}% \Msg{********************************************************************^^J}% \Msg{*^^J}% \Msg{* To finish the installation you have to move the following^^J}% \Msg{* files into a directory searched by TeX:^^J}% \Msg{*^^J}% \Msg{*\space\space\space\space bnumexpr.sty^^J}% \Msg{*^^J}% \Msg{* To produce the documentation run latex thrice on bnumexpr.tex^^J}% \Msg{* then dvipdfmx on bnumexpr.dvi. (ignore the dvipdfmx warnings)^^J}% \Msg{*^^J}% \Msg{* Happy TeXing!^^J}% \Msg{*^^J}% \Msg{********************************************************************^^J}% }% \begingroup \input docstrip.tex \askforoverwritefalse \generate{\nopreamble\nopostamble \file{README.md}{\from{bnumexpr.dtx}{readme}} \usepreamble\defaultpreamble \usepostamble\defaultpostamble \file{bnumexprchanges.tex}{\from{bnumexpr.dtx}{changes}} \file{bnumexpr.ins}{\from{bnumexpr.dtx}{ins}} \file{bnumexpr.tex}{\from{bnumexpr.dtx}{drv}} \file{bnumexpr.sty}{\from{bnumexpr.dtx}{package}}} \endgroup \fi % end of file extraction \ifnum\extractfiles=0 % direct tex/etex/xetex on bnumexpr.dtx, files now extracted, stop \MessageDeFin\expandafter\end \fi % no use of docstrip to extract files if latex compilation was on bnumexpr.tex \ifdefined\MessageDeFin\AtEndDocument{\MessageDeFin}\fi %------------------------------------------------------------------------------- \documentclass {scrdoc} \ifnum\NoSourceCode=1 \OnlyDescription\fi \usepackage{ifpdf} \ifpdf\chardef\Withdvipdfmx 0 \fi \makeatletter \ifnum\Withdvipdfmx=1 \@for\@tempa:=hyperref,bookmark,graphicx,xcolor,pict2e\do {\PassOptionsToPackage{dvipdfmx}\@tempa} % \PassOptionsToPackage{dvipdfm}{geometry} \PassOptionsToPackage{bookmarks=true}{hyperref} \PassOptionsToPackage{dvipdfmx-outline-open}{hyperref} \PassOptionsToPackage{dvipdfmx-outline-open}{bookmark} % \def\pgfsysdriver{pgfsys-dvipdfm.def} \else \PassOptionsToPackage{bookmarks=true}{hyperref} \fi \makeatother \pagestyle{headings} \makeatletter \def\buggysectionmark #1{% KOMA 3.12 as released to CTAN December 2013 \if@twoside\expandafter\markboth\else\expandafter\markright\fi {\MakeMarkcase{\ifnumbered{section}{\sectionmarkformat\fi}{}#1}}{}} \ifx\buggysectionmark\sectionmark \def\sectionmark #1{% \if@twoside\expandafter\markboth\else\expandafter\markright\fi {\MakeMarkcase{\ifnumbered{section}{\sectionmarkformat}{}#1}}{}} \fi \makeatother \usepackage[T1]{fontenc} \usepackage[latin1]{inputenc} \usepackage[hscale=0.66,vscale=0.75]{geometry} % requires newtxtt 1.05 or later \usepackage[zerostyle=a,scaled=0.95,straightquotes]{newtxtt} \renewcommand\familydefault\ttdefault \usepackage[noendash]{mathastext} \renewcommand\familydefault\sfdefault \usepackage{graphicx} \usepackage[dvipsnames]{xcolor} \definecolor{joli}{RGB}{225,95,0} \definecolor{JOLI}{RGB}{225,95,0} \definecolor{BLUE}{RGB}{0,0,255} \definecolor{niceone}{RGB}{38,128,192} \colorlet{smallverbcolor}{RoyalPurple}% \colorlet{jfverbcolor}{yellow!5} \colorlet{softwrapcolor}{blue} \colorlet{digitscolor}{OrangeRed} % transféré de xint-manual.tex (maintenant dans xint.dtx) \DeclareFontFamily{U}{MdSymbolC}{} \DeclareFontShape {U}{MdSymbolC}{m}{n}{<-> MdSymbolC-Regular}{} \makeatletter \newbox\cdbx@SoftWrapIcon \def\cdbx@SetSoftWrapBox{% \setbox\cdbx@SoftWrapIcon\hb@xt@\z@ {\hb@xt@\fontdimen2\font {\hss{\color{softwrapcolor}\usefont{U}{MdSymbolC}{m}{n}\char"97}\hss}% \hss}% } \makeatother \usepackage[english]{babel} \usepackage[pdfencoding=pdfdoc]{hyperref} \hypersetup{% %linktoc=all,% breaklinks=true,% colorlinks=true,% urlcolor=niceone,% linkcolor=blue,% pdfauthor={Jean-Fran\c cois Burnol},% pdftitle={The bnumexpr package},% pdfsubject={Arithmetic with TeX},% pdfkeywords={Expansion, arithmetic, TeX},% pdfstartview=FitH,% pdfpagemode=UseOutlines} \usepackage{bookmark} %---- \verb, and verbatim like `environments'. \MicroFont et \MacroFont \makeatletter \def\MicroFont {\ttfamily\cdbx@SetSoftWrapBox\color{smallverbcolor}} %\def\MicroFont {\ttfamily \color[named]{OrangeRed}\cdbx@SetSoftWrapBox } % \MacroFont est utilisé par macrocode, mais sa définition est figée dans % \macro@font au \begin{document} \def\MacroFont {\ttfamily \baselineskip12pt\relax } %--- November 4, 2014 making quotes straight. (maintenu pour *) % % there is no hook in \macrocode after \dospecials etc. Thus I will need to % take the risk that some future evolution of doc.sty (or perhaps scrdoc) % invalidates the following. % % Actually, I should not at all rely on the doc class, I should do it all by % myself. \def\macrocode{\macro@code \frenchspacing \@vobeyspaces \makestarlowast % \makequotesstraight (obsolète) \xmacro@code } %--- lower * symbol in text \def\lowast{\raisebox{-.25\height}{*}} \catcode`* \active \def\makestarlowast {\let*\lowast\catcode`\*\active}% \catcode`* 12 %------------obsolete------------ %--- straight quotes, added (finally...) Nov 4, 2014 % \begingroup\makeatletter % \catcode`\'\active % \catcode`\`\active % \@firstofone {\endgroup % \def\makequotesstraight {% textcomp package has been loaded by newtxtt % \let`\textasciigrave % \let'\textquotesingle % \catcode39\active % \catcode96\active }% % } %------------ % Tentative, mardi 09 septembre 2014 à 22:41:28 % Modifié mardi 13 octobre 2015 à 15:24:00 pour utilisable en % argument, et en particulier dans un \footnote{}. Mais utilise % \scantokens et macro délimitée maintenant. %\def\jf@makeletter #1{\catcode`#111\relax } \def\verb #1% {% \relax\leavevmode\null \begingroup \MicroFont \catcode`_ 11 \catcode`! 11 \catcode`: 11 \catcode`< 11 \catcode`> 11 % \scantokens will have a result of inserting a space after cs's. % hence the need to have the catcodes of things like _ right. % I also need < for > for one occasion in code comments % naturally won't work in footnotes though. % this code is truly not satisfying, but enough for my needs here. \def\@jfverb ##1#1{\let\do\@makeother \dospecials \makestarlowast %\let\do\do@noligs \verbatim@nolig@list % not needed here \@vobeyspaces\everyeof{\noexpand}% \expandafter\@@jfverb\scantokens{##1}\relax}% \@jfverb }% % Pour v1.2 je laisse tomber les colorbox. À la place je change la couleur % du texte. J'utilise le violet de xint. (mis dans \Microfont) % \def\@@@jfverb #1{\ifcat\noexpand#1$% $ % \endgroup\else % % \penalty\z@ % \discretionary{\copy\cdbx@SoftWrapIcon}{}{}% % % \colorbox{jfverbcolor}{\strut #1}% unfortunately, impacts pdf size % #1% % \expandafter\@@@jfverb\fi } \def\@@jfverb #1{\ifcat\noexpand#1\relax\endgroup\else \discretionary{\copy\cdbx@SoftWrapIcon}{}{}% #1\expandafter\@@jfverb\fi } \makeatother % mardi 13 octobre 2015 à 15:32:51 % le | n'est pas encore actif ici! \catcode`| \active \def\bneshow #1% {|\thebnumexpr#1\relax|$$\color{digitscolor}\thebnumexpr#1\relax$$} \catcode`| 12 \DeclareRobustCommand\csa [1]{{\char92\detokenize{#1}}} \newcommand\csh[1]{\texorpdfstring{\csa{#1}}{\textbackslash\detokenize{#1}}} \usepackage{xspace} \def\bnumname {\href{http://www.ctan.org/pkg/bnumexpr}{bnumexpr}\xspace }% \def\bnumnameimp {\texorpdfstring {\hyperref[sec:bnumexprcode]{{\color{smallverbcolor}\ttzfamily bnumexpr}}} {bnumexpr}% \xspace }% \def\xintname {\href{http://www.ctan.org/pkg/xint}{xint}\xspace }% \def\xintcorename {\href{http://www.ctan.org/pkg/xint}{xintcore}\xspace }% \def\xintexprname {\href{http://www.ctan.org/pkg/xint}{xintexpr}\xspace }% \frenchspacing \usepackage{bnumexpr} \usepackage{etoc} \usepackage{framed} \makeatletter\let\check@percent\relax\makeatother \begin{document} \thispagestyle{empty} \ttzfamily \pdfbookmark[1]{Title page}{TOP} {% \normalfont\Large\parindent0pt \parfillskip 0pt\relax \leftskip 2cm plus 1fil \rightskip 2cm plus 1fil The \bnumname package\par } {\centering \textsc{Jean-François Burnol}\par \footnotesize jfbu (at) free (dot) fr\par Package version: \bneversion\ (\bnepackdate); documentation date: \bnedocdate.\par {From source file \texttt{bnumexpr.dtx}. \bnedtxtimestamp.}\par } \etocsetnexttocdepth{section} \tableofcontents \section{Examples} \label{sec:bnumexpr} Package \bnumname provides |\thebnumexpr...\relax| which is analogous to |\the\numexpr...\relax|, while allowing arbitrarily big integers, powers, factorials, truncated division, modulo, and comma separated expressions. Examples: \noindent\bneshow {1208637867168*(2187917891279+3109197072870)}% \bneshow {(1380891090-30018902902)*(108319083901-10982903890)}% \bneshow {30!/20!/21/22/23/24/25/(26*27*28*29)}% \bneshow {13^50//12^50, 13^50/:12^50}% \bneshow {13^50/12^50, 12^50}% \bneshow {(1^10+2^10+3^10+4^10+5^10+6^10+7^10+8^10+9^10)^3}% \bneshow {100!/36^100}% \section{Differences from \csh{numexpr}} Apart from the extension to big integers (i.e. exceeding the \TeX{} limit at \number"7FFFFFFF), and the added operators, there are a number of important differences between |\bnumexpr| and |\numexpr|: \begin{enumerate} \item one must use either |\thebnumexpr| or |\bnethe\bnumexpr| to get a printable result, as |\bnumexpr...\relax| expands to a private format, \item one may embed directly (without |\bnethe|) a |\bnumexpr...\relax| in another one (or in a |\xintexpr...\relax|), but not in a |\numexpr...\relax|; on the other hand a |\numexpr...\relax| does not need to be prefixed by |\the| or |\number| inside |\bnethe\bnumexpr| or |\thebnumexpr|, \item contrarily to |\numexpr|, the |\bnumexpr| parser stops only after having found (and swallowed) a mandatory ending |\relax| token, \item in particular spaces between digits do not stop |\bnumexpr|, in contrast with |\numexpr|: |\the\numexpr 3 5+79\relax| expands (in one step) to \expandafter|\the\numexpr 3 5+79\relax| |\thebnumexpr 3 5+79\relax| expands (in two steps) to \expandafter\expandafter\expandafter|\thebnumexpr 3 5+79\relax| \item one may do |\edef\tmp{\bnumexpr 1+2\relax}|, and then either use |\tmp| in another |\bnumexpr...\relax|, or print it via |\bnethe\tmp|. The computation is done at the time of the |\edef| (and two expansion steps suffice). This is again in contrast with |\numexpr...\relax| which, without |\the| (or |\number| or |\romannumeral|) as prefix would not expand inside an |\edef|, \item tacit multiplication applies in front of parenthesized sub-expressions, or sub |\bnumexpr...\relax| (or |\numexpr...\relax|), or in front of a |\count| or |\dimen| register. \item expressions may be comma separated. On input, spaces are ignored, naturally, and on output the values are comma separated with a space after each comma. \item |\bnumexpr -(1+1)\relax| is legal contrarily to |\numexpr -(1+1)\relax| which raises an error. \end{enumerate} An important thing to keep in mind is that if one has a calculation whose result is a small integer, acceptable by \TeX{} in |\ifnum| or count assignments, this integer produced by |\thebnumexpr| is not self-delimiting, contrarily to a |\numexpr...\relax| construct: the situation is exactly as with a |\the\numexpr...\relax|, thus one may need to terminate the number to avoid premature expansion of following tokens; for example with the |\space| token. The parser |\bnumexpr| is a scaled-down version of parser |\xintiiexpr| from package \xintexprname. It lacks in particular boolean operators, square roots and other functions, variables, hexadecimal inputs, etc... it may be slightly faster when handling complicated expressions as it does not have to check so many things. I recall from the documentation of \xintexprname that there is a potential impact on the memory of \TeX{} (the string pool, the hash table) because each intermediate number is stored as a dummy control sequence name during processing. After thousands of evaluations with numbers having hundreds of digits parts of the \TeX{} memory will become saturated and end the \verb?latex|pdflatex? run (but the problem can in theory be avoided through the use of a ``bigger'' |pdfetex| compiled with enlarged memory parameters). Anyhow, computations with thousands of digits take time, and this is probably a more stringent constraint. If the same expression needs to be evaluated again and again tens of thousands of times, it may be necessary to drop use of \bnumname and either use directly the macros from package \xintcorename, or apply |\xintNewIIExpr| from package \xintexprname to first construct the possibly very complicated nested macro. The \eTeX{} extensions are required (this is the default on all modern installations for \verb?latex|pdflatex? and also for \verb?xelatex|lualatex?). \section{Printing big numbers} \LaTeX{} will not split long numbers at the end of lines. I personally often use helper macros (not in the package) of the following type: \begin{verbatim} \def\allowsplits #1{\ifx #1\relax \else #1\hskip 0pt plus 1pt\relax \expandafter\allowsplits\fi}% \def\printnumber #1{\expandafter\allowsplits \romannumeral-`0#1\relax }% % \printnumber thus first ``fully'' expands its argument. \end{verbatim} \def\allowsplits #1{\ifx #1\relax \else #1\hskip 0pt plus 1pt\relax \expandafter\allowsplits\fi}% \def\printnumber #1{\expandafter\allowsplits \romannumeral-`0#1\relax }% \noindent|\thebnumexpr 1000!\relax=|\phantom{0}{\color{digitscolor}\printnumber{\thebnumexpr 1000!\relax}}\par \section{Expression syntax} It is the expected one with infix operators and parentheses, the recognized operators being |+|, |-|, |*|, |/| (rounded division), |^| (power), |**| (power), |//| (truncated division), |/:| (modulo) and |!| (factorial). Different computations may be separated by commas. The whole expression is handled token by token, any component (digit, operator, parenthesis... even the ending |\relax|) may arise on the spot from macro expansions. The precedence rules are the expected ones. Notice though that in case of equal precedence the operations are left-associative, hence:\newline \bneshow{2^3^4, (2^3)^4, 2^(3^4)} The three operators |/|, |//|, |/:| are at the same level of precedence as the multiplication |*|. The modulo |/:| is associated with truncated division |//|. The factorial postfix |!| has highest precedence. The minus signs inherit the precedence level of the previously encountered infix operators. \section{Option custom, \csh{bnumexprsetup}}\label{sec:options} Package \bnumname needs that some big integer engine provides the macros doing the actual computations. By default, it loads package \xintcorename (a subset of \href{http://www.ctan.org/pkg/xint}{xint}; version |1.2| is required) and uses \csa{bnumexprsetup} in the following way: \begin{verbatim} \usepackage{xintcore} \bnumexprsetup{add=\xintiiAdd, sub=\xintiiSub, mul=\xintiiMul, divround=\xintiiDivRound, divtrunc=\xintiiDivTrunc, mod=\xintiiMod, pow=\xintiiPow, fac=\xintiiFac} \end{verbatim} The keys given to \csa{bnumexprsetup} must be lowercased. If using \csa{bnumexprsetup}, it is not necessary to specify all keys, for example one can do |\bnumexprsetup{mul=\MyFasterMul}|, and only multiplication will be changed. Naturally it is up to the user to load the appropriate package for the alternative macros. As per the macros which are the key values, they must have the following properties: \begin{enumerate} \item they must be completely expandable (in the sense of an |\edef| or a |\csname...\endcsname|.) \item they must fully expand their arguments first (in the sense of |\romannumeral-`0|.) \item they must output a number with no leading zeros, at most one minus sign and no plus sign. \end{enumerate} The first two items are truly mandatory, the last one may be not obeyed if the extra key |opp| is used with \csa{bnumexprsetup} to specify a suitable macro for the opposite of a number. This macro will be presented not with a braced argument but directly with a sequence of digits (either as gathered by the parser which skips leading zeros, or as produced by the other arithmetic macros and then there could be a minus, or even a plus if macros others than the ones from \xintcorename have been used). Thus, |opp| could identify a plus sign |+| upfront and then act adequately.\footnote{see \csa{BNE_Op_opp} in the code for the default.} The sole package option is |custom|: it tells \bnumname not to load \xintcorename. \section{Readme} \begingroup \makeatletter\def\x{\baselineskip10pt \ttfamily\settowidth\dimen@{X}% %\parindent \dimexpr.5\linewidth-34\dimen@\relax \parindent\z@ \let\do\do@noligs\verbatim@nolig@list \let\do\@makeother\dospecials \makestarlowast %\def\par{\leavevmode\null\@@par\penalty\interlinepenalty}% \def\par{\leavevmode\null\@@par\pagebreak[1]}% \@vobeyspaces\obeylines \noindent\kern\parindent\input README.md \endgroup }\x \section{Changes} %\small \begin{description} \input bnumexprchanges.tex \end{description} \StopEventually{\end{document}\endinput} \newgeometry{hscale=0.75,vscale=0.75}% ATTENTION \newgeometry fait % un reset de vscale si on ne le % précise pas ici !!! \MakePercentIgnore % % \catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11 % \let\relax % \def<*package>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 } % %<*package> % % \section{Package \bnumnameimp implementation} % \label{sec:bnumexprcode} % % \localtableofcontents \bigskip % % Comments are sparse. Error handling by the parser is kept to a minimum; if % something goes wrong, the offensive token gets discarded, and some undefined % control sequence attempts to trigger writing to the log of some sort of % informative message. It is recommended to set |\errorcontextlines| to at % least |2| for more meaningful context. % % \subsection{Package identification and catcode setup} % \begin{macrocode} \NeedsTeXFormat{LaTeX2e}% \ProvidesPackage{bnumexpr}[2015/10/14 v1.2a Expressions with big integers (jfB)]% \edef\BNErestorecatcodes {\catcode`\noexpand\!\the\catcode`\! \catcode`\noexpand\?\the\catcode`\? \catcode`\noexpand\_\the\catcode`\_ \catcode`\noexpand\:\the\catcode`\: \catcode`\noexpand\(\the\catcode`\( \catcode`\noexpand\)\the\catcode`\) \catcode`\noexpand\*\the\catcode`\* \catcode`\noexpand\,\the\catcode`\,\relax }% \catcode`\! 11 \catcode`\? 11 \catcode`\_ 11 \catcode`\: 11 \catcode`\, 12 \catcode`\* 12 \catcode`\( 12 % \end{macrocode} % \subsection{Some helper macros and constants from xint} % These macros from xint should not change, hence overwriting them here should % not be cause for alarm. I opted against renaming everything with |\BNE_| % prefix rather than |\xint_|. The |\xint_dothis|/|\xint_orthat| thing is a new % style I have adopted for expandably forking. The least probable branches % should be specified first, for better efficiency. See examples of uses in the % present code. % \begin{macrocode} \chardef\xint_c_ 0 \chardef\xint_c_i 1 \chardef\xint_c_ii 2 \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 \long\def\xint_gobble_i #1{}% \long\def\xint_gobble_iii #1#2#3{}% \long\def\xint_firstofone #1{#1}% \long\def\xint_firstoftwo #1#2{#1}% \long\def\xint_secondoftwo #1#2{#2}% \long\def\xint_firstofthree #1#2#3{#1}% \long\def\xint_secondofthree #1#2#3{#2}% \long\def\xint_thirdofthree #1#2#3{#3}% \def\xint_gob_til_! #1!{}% this ! has catcode 11 \def\xint_UDsignfork #1-#2#3\krof {#2}% \long\def\xint_afterfi #1#2\fi {\fi #1}% \long\def\xint_dothis #1#2\xint_orthat #3{\fi #1}% \let\xint_orthat \xint_firstofone \def\xint_zapspaces #1 #2{#1#2\xint_zapspaces }% % \end{macrocode} % \subsection{\csh{bnumexprsetup}} % New with |v1.2a|. Replaces removed |\bnumexprUsesbigintcalc| etc... % \begin{macrocode} \catcode`! 3 \def\bnumexprsetup #1{\BNE_parsekeys #1,=!,}% \def\BNE_parsekeys #1=#2#3,{\ifx!#2\expandafter\BNE_parsedone\fi \expandafter \let\csname BNE_Op_\xint_zapspaces #1 \xint_gobble_i\endcsname=#2\BNE_parsekeys }% \catcode`! 11 \def\BNE_parsedone #1\BNE_parsekeys {}% % \end{macrocode} % \subsection{Package options} % \begin{macrocode} \def\BNE_tmpa {0}% \DeclareOption {custom}{\def\BNE_tmpa {1}}% \ProcessOptions\relax \if0\BNE_tmpa % Default is to load xintcore.sty \RequirePackage{xintcore}[2015/10/10]% \bnumexprsetup{add=\xintiiAdd, sub=\xintiiSub, mul=\xintiiMul, divround=\xintiiDivRound, divtrunc=\xintiiDivTrunc, mod=\xintiiMod, pow=\xintiiPow, fac=\xintiiFac}% \fi % \end{macrocode} % \subsection{\csh{bnumexpr}, \csh{bnethe}, \csh{thebnumexpr}, \dots} % In the full |\xintexpr|, the final unlocking may involve post-treatment of % the comma separated values, hence there are |_print| macros to handle the % possibly comma separated values. Here we may just identify |_print| with % |_unlock|. % % With |v1.2a| the gathering of numbers happens directly inside % |\csname...\endcsname|. There is no more a ``locking'' macro. % \begin{macrocode} \def\bnumexpr {\romannumeral0\bnumeval }% \def\bnumeval {\expandafter\BNE_wrap\romannumeral0\BNE_eval }% \def\BNE_eval {\expandafter\BNE_until_end_a\romannumeral-`0\BNE_getnext }% \def\BNE_wrap { !\BNE_usethe\BNE_protect\BNE_unlock }% \protected\def\BNE_usethe\BNE_protect {\BNE:missing_bnethe!}% \def\BNE_protect\BNE_unlock {\noexpand\BNE_protect\noexpand\BNE_unlock\noexpand }% \let\BNE_done\space \def\thebnumexpr {\romannumeral-`0\expandafter\BNE_unlock\romannumeral0\BNE_eval }% \def\bnethe #1{\romannumeral-`0\expandafter\xint_gobble_iii\romannumeral-`0#1}% \def\BNE_unlock {\expandafter\BNE_unlock_a\string }% \def\BNE_unlock_a #1.={}% % \end{macrocode} % \subsection{\csh{BNE_getnext}} % The getnext scans forward to find a number: after expansion of what comes % next, an opening parenthesis signals a parenthesized sub-expression, a |!| % with catcode 11 signals there was there a sub |\bnumexpr...\relax| (now % evaluated), a minus sign is treated as a prefix operator inheriting its % precedence level from the previous operator, a plus sign is swallowed, a % |\count| or |\dimen| will get fetched to |\number| (in case of a count % variable, this provides a full locked number but |\count0 1| for example is % like |1231| if |\count0|'s value is |123|); a digit triggers the % number scanner. With |v1.2a| the gathering of digits happens directly inside % |\csname .=...\endcsname|. Leading zeroes are trimmed directly. % The flow then proceeds with |\BNE_getop| which looks for the next operator % or possibly the end of the expression. Note: |\bnumexpr\relax| is % illegal. % % Extended in v1.2a to recognize |\ht|, etc... % \begin{macrocode} \def\BNE_getnext #1% {% \expandafter\BNE_getnext_a\romannumeral-`0#1% }% \def\BNE_getnext_a #1% {% \xint_gob_til_! #1\BNE_gn_foundexpr !% this ! has catcode 11 \ifcat\relax#1% \count or \numexpr etc... token or count, dimen, skip cs \expandafter\BNE_gn_countetc \else \expandafter\expandafter\expandafter\BNE_gn_fork\expandafter\string \fi #1% }% \def\BNE_gn_foundexpr !#1\fi !{\expandafter\BNE_getop\xint_gobble_iii }% \def\BNE_gn_countetc #1% {% \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 \BNE_gn_unpackvar \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \expandafter\BNE_getnext\number #1% }% \def\BNE_gn_unpackvar\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \expandafter\BNE_getnext\number #1% {% \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \expandafter\BNE_getop\csname .=\number#1\endcsname }% % \end{macrocode} % This is quite simplified here compared to |\xintexpr|, for various reasons: we % have dropped the |\xintNewExpr| thing, and we can treat the |(| directly as we % don't have to get back to check if we are in an |\xintexpr|, % |\xintfloatexpr|, etc.. % \begin{macrocode} \def\BNE_gn_fork #1{% \if#1+\xint_dothis \BNE_getnext\fi \if#1-\xint_dothis -\fi \if#1(\xint_dothis \BNE_oparen \fi \xint_orthat {\BNE_scan_number #1}% }% % \end{macrocode} % \subsection{Parsing an integer} % We gather a string of digits, plus and minus prefixes have already been % swallowed. There might be some leading string of zeros which will have to be % removed. In the full |\xintexpr| the situation is more involved as it % has to recognize and accept decimal numbers, numbers in scientific notation, % also hexadecimal numbers, function names, variable names\dots % \begin{macrocode} \def\BNE_scan_number #1% this #1 has necessarily here catcode 12 {% \ifnum \xint_c_ix<1#1 \else\expandafter\BNE_notadigit\fi \BNE_scan_nbr #1% }% \def\BNE_notadigit\BNE_scan_nbr #1{\BNE:not_a_digit!\BNE_getnext }% % \end{macrocode} % Scanning for a number. We gather it directly inside csname. earlier % version did a chain of romannumeral. No limit on number of digits % anymore from the maximal expansion depth. We only have to be careful % about leading zeros. % % If we hit against some catcode eleven |!|, this means there was a % sub |\bnumexpr..\relax|. We then apply tacit multiplication. % \begin{macrocode} \def\BNE_scan_nbr #1% {% the #1 here is a catcode 12 digit \if#10\expandafter\BNE_scan_nbr_gobzeroes \else \expandafter\BNE_scan_nbr_start \fi #1% }% \def\BNE_scan_nbr_start #1#2% {% \expandafter\BNE_getop\csname.=#1% \expandafter\BNE_scanint_b\romannumeral-`0#2% }% \def\BNE_scan_nbr_gobzeroes #1% {% \expandafter\BNE_getop\csname.=% \expandafter\BNE_gobz_scanint_b\romannumeral-`0#1% }% \def\BNE_scanint_b #1% {% \ifcat \relax #1\expandafter\BNE_scanint_endbycs\expandafter #1\fi \ifnum\xint_c_ix<1\string#1 \else\expandafter\BNE_scanint_c\fi \string#1\BNE_scanint_d }% \def\BNE_scanint_endbycs#1#2\BNE_scanint_d{\endcsname #1}% \def\BNE_scanint_c\string #1\BNE_scanint_d {% \ifcat a#1\xint_dothis{\endcsname*}\fi % tacit multiplication \xint_orthat {\expandafter\endcsname \string}#1% }% \def\BNE_scanint_d #1% {% \expandafter\BNE_scanint_b\romannumeral-`0#1% }% \def\BNE_gobz_scanint_b #1% {% \ifcat \relax #1\expandafter\BNE_gobz_scanint_endbycs\expandafter #1\fi \ifnum\xint_c_x<1\string#1 \else\expandafter\BNE_gobz_scanint_c\fi \string#1\BNE_scanint_d }% \def\BNE_gobz_scanint_endbycs#1#2\BNE_scanint_d{0\endcsname #1}% \def\BNE_gobz_scanint_c\string #1\BNE_scanint_d {% \ifcat a#1\xint_dothis{0\endcsname*#1}\fi % tacit multiplication \if 0#1\xint_dothis\BNE_gobz_scanint_d\fi \xint_orthat {0\expandafter\endcsname \string#1}% }% \def\BNE_gobz_scanint_d #1% {% \expandafter\BNE_gobz_scanint_b\romannumeral-`0#1% }% % \end{macrocode} % \begin{macrocode} % \end{macrocode} % \subsection{\csh{BNE_getop}} % This finds the next infix operator or closing parenthesis or expression end. % It then leaves in the token flow . % The stops expansion and ultimately gives back control to a % |\BNE_until_| command. The code here is derived from more involved % context where the actual macro associated to the operator may vary, % depending if we are in |\xintexpr|, |\xintfloatexpr| or |\xintiiexpr|. Here % things are simpler but I have kept the general scheme, thus the actual macro % to be used for the is not decided immediately. % % |v1.2a| adds a technique for allowing two-letters operators, for % |//|, |/:| and |**|. % \begin{macrocode} \def\BNE_getop #1#2% this #1 is the current locked computed value {% \expandafter\BNE_getop_a\expandafter #1\romannumeral-`0#2% }% \catcode`* 11 \def\BNE_getop_a #1#2% {% if a control sequence is found, must be \relax, or possibly register or % variable if tacit multiplication is allowed \ifx \relax #2\xint_dothis\xint_firstofthree\fi % tacit multiplications: \ifcat \relax #2\xint_dothis\xint_secondofthree\fi \if (#2\xint_dothis \xint_secondofthree\fi \ifx !#2\xint_dothis \xint_secondofthree\fi \xint_orthat \xint_thirdofthree {\BNE_foundend #1}% {\BNE_precedence_* *#1#2}% tacit multiplication {\BNE_scanop_a #2#1}% }% \catcode`* 12 \def\BNE_foundend {\xint_c_ \relax }% \relax is only a place-holder here. \def\BNE_scanop_a #1#2#3% {\expandafter\BNE_scanop_b\expandafter #1\expandafter #2\romannumeral-`0#3}% \def\BNE_scanop_b #1#2#3% {% \ifcat#3\relax\xint_dothis{\BNE_foundop #1#2#3}\fi \ifcsname BNE_itself_#1#3\endcsname \xint_dothis {\expandafter\BNE_foundop\csname BNE_itself_#1#3\endcsname #2}\fi \xint_orthat {\BNE_foundop #1#2#3}% }% \def\BNE_foundop #1% {% \ifcsname BNE_precedence_#1\endcsname \csname BNE_precedence_#1\expandafter\endcsname \expandafter #1% \else \BNE_notanoperator {#1}\expandafter\BNE_getop \fi }% \def\BNE_notanoperator #1{\BNE:not_an_operator! \xint_gobble_i {#1}}% % \end{macrocode} % \subsection{Until macros for global expression and parenthesized sub-ones} % The minus sign as prefix is treated here. % \begin{macrocode} \catcode`) 11 \def\BNE_tmpa #1{% \def\BNE_until_end_a ##1% {% \xint_UDsignfork ##1{\expandafter\BNE_until_end_a\romannumeral-`0#1}% -{\BNE_until_end_b ##1}% \krof }% }\expandafter\BNE_tmpa\csname BNE_op_-vi\endcsname \def\BNE_until_end_b #1#2% {% \ifcase #1\expandafter\BNE_done \or \xint_afterfi{\BNE:extra_)_?\expandafter \BNE_until_end_a\romannumeral-`0\BNE_getop }% \else \xint_afterfi{\expandafter\BNE_until_end_a \romannumeral-`0\csname BNE_op_#2\endcsname }% \fi }% \catcode`( 11 \def\BNE_op_( {\expandafter\BNE_until_)_a\romannumeral-`0\BNE_getnext }% \let\BNE_oparen\BNE_op_( \catcode`( 12 \def\BNE_tmpa #1{% \def\BNE_until_)_a ##1{\xint_UDsignfork ##1{\expandafter \BNE_until_)_a\romannumeral-`0#1}% -{\BNE_until_)_b ##1}% \krof }% }\expandafter\BNE_tmpa\csname BNE_op_-vi\endcsname \def \BNE_until_)_b #1#2% {% \ifcase #1\expandafter \BNE_missing_)_? % missing ) ? \or\expandafter \BNE_getop % found closing ) \else \xint_afterfi {\expandafter \BNE_until_)_a\romannumeral-`0\csname BNE_op_#2\endcsname }% \fi }% \def\BNE_missing_)_? {\BNE:missing_)_inserted \xint_c_ \BNE_done }% \let\BNE_precedence_) \xint_c_i \let\BNE_op_) \BNE_getop \catcode`) 12 % \end{macrocode} % \subsection{The arithmetic operators.} % This is where the infix operators are mapped to actual macros. These macros % must ``f-expand'' their arguments, and know how to handle then big integers % having no leading zeros and at most a minus sign. % % |v1.2a| adds |//| for truncated division, |/:| for modulo operations % and |**| for powers (synonym to |^|). % \begin{macrocode} \def\BNE_tmpc #1#2#3#4#5#6#7% {% \def #1##1% \BNE_op_ {% keep value, get next number and operator, then do until \expandafter #2\expandafter ##1\romannumeral-`0\expandafter\BNE_getnext }% \def #2##1##2% \BNE_until__a {\xint_UDsignfork ##2{\expandafter #2\expandafter ##1\romannumeral-`0#4}% -{#3##1##2}% \krof }% \def #3##1##2##3##4% \BNE_until__b {% either execute next operation now, or first do next (possibly unary) \ifnum ##2>#5% \xint_afterfi {\expandafter #2\expandafter ##1\romannumeral-`0% \csname BNE_op_##3\endcsname {##4}}% \else \xint_afterfi {\expandafter ##2\expandafter ##3% \csname .=#6{\BNE_unlock ##1}{\BNE_unlock ##4}\endcsname }% \fi }% \let #7#5% }% \def\BNE_tmpb #1#2#3% {% \expandafter\BNE_tmpc \csname BNE_op_#1\expandafter\endcsname \csname BNE_until_#1_a\expandafter\endcsname \csname BNE_until_#1_b\expandafter\endcsname \csname BNE_op_-#2\expandafter\endcsname \csname xint_c_#2\expandafter\endcsname \csname #3\expandafter\endcsname \csname BNE_precedence_#1\endcsname }% \BNE_tmpb +{vi}{BNE_Op_add}% \BNE_tmpb -{vi}{BNE_Op_sub}% \BNE_tmpb *{vii}{BNE_Op_mul}% \BNE_tmpb /{vii}{BNE_Op_divround}% \BNE_tmpb ^{viii}{BNE_Op_pow}% \expandafter\def\csname BNE_itself_**\endcsname {^}% shortcut for alias \expandafter\def\csname BNE_itself_//\endcsname {//}% \expandafter\def\csname BNE_itself_/:\endcsname {/:}% \BNE_tmpb {//}{vii}{BNE_Op_divtrunc}% \BNE_tmpb {/:}{vii}{BNE_Op_mod}% % \end{macrocode} % \subsection{! as postfix factorial operator} % New with |v1.2a|. % \begin{macrocode} \let\BNE_precedence_! \xint_c_x \def\BNE_op_! #1% {\expandafter\BNE_getop\csname .=\BNE_Op_fac{\BNE_unlock #1}\endcsname }% % \end{macrocode} % \subsection{The minus as prefix operator of variable precedence level} % It inherits the level of precedence of the previous operator. % \begin{macrocode} \def\BNE_tmpa #1% {% \expandafter\BNE_tmpb \csname BNE_op_-#1\expandafter\endcsname \csname BNE_until_-#1_a\expandafter\endcsname \csname BNE_until_-#1_b\expandafter\endcsname \csname xint_c_#1\endcsname }% \def\BNE_tmpb #1#2#3#4% {% \def #1% \BNE_op_- {% get next number+operator then switch to _until macro \expandafter #2\romannumeral-`0\BNE_getnext }% \def #2##1% \BNE_until_-_a {\xint_UDsignfork ##1{\expandafter #2\romannumeral-`0#1}% -{#3##1}% \krof }% \def #3##1##2##3% \BNE_until_-_b {% \ifnum ##1>#4% \xint_afterfi {\expandafter #2\romannumeral-`0% \csname BNE_op_##2\endcsname {##3}}% \else \xint_afterfi {\expandafter ##1\expandafter ##2% \csname .=\expandafter\BNE_Op_opp \romannumeral-`0\BNE_unlock ##3\endcsname }% \fi }% }% \BNE_tmpa {vi}% \BNE_tmpa {vii}% \BNE_tmpa {viii}% \def\BNE_Op_opp #1{\if-#1\else\if0#10\else-#1\fi\fi }% % \end{macrocode} % \subsection{The comma may separate expressions.} % It suffices to treat the comma as a binary operator of precedence |ii|. We % insert a space after the comma. The current code in |\xintexpr| does not do % it at this stage, but only later during the final unlocking, as there is % anyhow need for some processing for final formatting and was considered to % be as well the opportunity to insert the space. Here, let's do it % immediately. These spaces are not an issue when |\bnumexpr| is % identified as a sub-expression in |\xintexpr|, for example in: % |\xinttheiiexpr lcm(\bnumexpr 175-12,123+34,56*31\relax)\relax| (this % example requires package |xintgcd|). % \begin{macrocode} \catcode`, 11 \def\BNE_op_, #1% {% \expandafter \BNE_until_,_a\expandafter #1\romannumeral-`0\BNE_getnext }% \def\BNE_tmpa #1{% #1 = \BNE_op_-vi \def\BNE_until_,_a ##1##2% {% \xint_UDsignfork ##2{\expandafter \BNE_until_,_a\expandafter ##1\romannumeral-`0#1}% -{\BNE_until_,_b ##1##2}% \krof }% }\expandafter\BNE_tmpa\csname BNE_op_-vi\endcsname \def\BNE_until_,_b #1#2#3#4% {% \ifnum #2>\xint_c_ii \xint_afterfi {\expandafter \BNE_until_,_a \expandafter #1\romannumeral-`0% \csname BNE_op_#3\endcsname {#4}}% \else \xint_afterfi {\expandafter #2\expandafter #3% \csname .=\BNE_unlock #1, \BNE_unlock #4\endcsname }% \fi }% \let \BNE_precedence_, \xint_c_ii % \end{macrocode} % \subsection{Cleanup} % \begin{macrocode} \let\BNE_tmpa\relax \let\BNE_tmpb\relax \let\BNE_tmpc\relax \BNErestorecatcodes % \end{macrocode} % \MakePercentComment % %<*dtx> \DeleteShortVerb{\|} \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 Lower-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 Digits \0\1\2\3\4\5\6\7\8\9 Exclamation \! Double quote \" Hash (number) \# Dollar \$ Percent \% Ampersand \& Acute accent \' Left paren \( Right paren \) Asterisk \* Plus \+ Comma \, Minus \- Point \. Solidus \/ Colon \: Semicolon \; Less than \< Equals \= Greater than \> Question mark \? Commercial at \@ Left bracket \[ Backslash \\ Right bracket \] Circumflex \^ Underscore \_ Grave accent \` Left brace \{ Vertical bar \| Right brace \} Tilde \~} \CheckSum {861} \makeatletter\check@checksum\makeatother \Finale %% End of file xint.dtx