% -*- coding: iso-latin-1; time-stamp-format: "%02d-%02m-%:y at %02H:%02M:%02S %Z" -*-
%<*dtx>
\def\bnedtxtimestamp  {Time-stamp: <05-12-2017 at 15:54:19 CET>}
\iffalse
%</dtx>
%<*drv>
%% ---------------------------------------------------------------
\def\bnedocdate {2017/12/05}% package bnumexpr documentation date
\def\bnepackdate{2017/12/05}% package bnumexpr date
\def\bneversion {1.2c}      % package bnumexpr version
%</drv>
%<*readme>--------------------------------------------------------

| Source:  bnumexpr.dtx
| Version: v1.2c, 2017/12/05 (doc: 2017/12/05)
| Author:  Jean-Francois Burnol
| Info:    Expressions with big integers
| License: LPPL 1.3c

README: [Usage], [Installation], [License]
==========================================

Usage
-----

The package `bnumexpr` allows _expandable_ computations with big
integers and the four infix operators `+`, `-`, `*`, `/` (which does
rounded integer division) familiar from the `\numexpr` e-TeX parser.

Besides extending the scope to arbitrarily big numbers (and having a
more complete syntax, for example `-(1)` is legal input), it adds the
(by default) floored division operator `//`, and its associated modulo
`/:`, the power operator `^` (or equivalently `**`), and the factorial
post-fix operator `!`. The space character as well as the underscore
character `_` both may serve to optionally separate digits in long
numbers, for better readability of the input.

For example:

    \thebnumexpr ( 92_874_927_979^5 - 31_9792_7979^6 ) / 30!\relax

expands (in two steps) to `-4006240736596543944035189`.

The `\relax` ending token is mandatory and will be removed as a
result of the evaluation.

The expression parser is scaled-down from the `\xinttheiiexpr...\relax`
parser as provided by package xintexpr[^1]: it does not handle boolean
operators, dummy or user defined variables, functions, etc...

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.

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]: <http://www.ctan.org/pkg/xint>

Installation
------------

Obtain `bnumexpr.dtx` (and possibly, `bnumexpr.ins` and the `README`)
from CTAN:

> <http://www.ctan.org/pkg/bnumexpr>

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-2017 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

>   <http://www.latex-project.org/lppl/lppl-1-3c.txt>

| 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>--------------------------------------------------------
%<*!readme>
%% ---------------------------------------------------------------
%% The bnumexpr package: Expressions with big integers
%% Copyright (C) 2014-2017 by Jean-Francois Burnol
%%
%</!readme>
%<*changes>-------------------------------------------------------
\item[1.2c (2017/12/05)] \textbf{Breaking changes:}
  \begin{itemize}
  \item requires \xintcorename |1.2p| or later (if not using option |custom|).
  \item |divtrunc| key of |\bnumexprsetup| is renamed to |div|.
  \item the |//| and |/:| operators are now by default associated to the
    \emph{floored} division. This is to keep in sync with the change of
    \xintcorename at |1.2p|.
  \item for backwards compatibility, one
    may add to existing document:\newline
    \string\bnumexprsetup\{div=\string\xintiiDivTrunc,
    mod=\string\xintiiModTrunc\}
  \end{itemize}

\item[1.2b (2017/07/09)]
  \begin{itemize}
  \item the |_| may be used to separate visually blocks of digits in long
    numbers.
  \end{itemize}

\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 |\.=<digits>| 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.
%</changes>-------------------------------------------------------
%<*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:
%</drv>-----------------------------------------------------------
%<*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
%</ins>-----------------------------------------------------------
%<*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 }%
\def\xintbinhexname
   {\href{http://www.ctan.org/pkg/xint}{xintbinhex}\xspace }%


% \centeredline: OUR OWN LITTLE MACRO FOR CENTERING LINES
% =======================================================

% 7 mars 2013
% -----------
%
% This macro allows to conveniently center a line inside a paragraph and still
% allow use therein of \verb or other macros changing catcodes.
% A proposito, the \LaTeX \centerline uses \hsize and not \linewidth !
% (which in my humble opinion is bad)

% Actually my \centeredline works nicely in list environments.

% \ignorespaces ajouté le 9 juin 2013.

% Note: \centeredline creates a group

\makeatletter
\newcommand*\centeredline {%
      \ifhmode \\\relax
        \def\centeredline@{\hss\egroup\hskip\z@skip\ignorespaces }%
      \else
        \def\centeredline@{\hss\egroup }%
      \fi
      \afterassignment\@centeredline
      \let\next=}
\def\@centeredline
    {\hbox to \linewidth \bgroup \hss \bgroup \aftergroup\centeredline@ }


\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, floored division, modulo, and comma separated expressions.
Examples:

\noindent\bneshow {1_208_637_867_168*(2_187_917_891_279+3_109_197_072_870)}%
\bneshow {(13_8089_1090-300_1890_2902)*(1083_1908_3901-109_8290_3890)}%
\bneshow{(92_874_927_979**5-31_9792_7979**6)/30!}%
\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 (using
  |\number| as prefix to |\bnumexpr| would only serve to trigger the expansion
  to the \bnumname private format, hence will raise a \TeX\ error),

\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 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,

\item |\numexpr 2\cnta\relax| is illegal (with |\cnta| a |\count|-variable.)
  But |\bnumexpr 2\cnta\relax| is perfectly legal and will do the tacit
  multiplication,
% \newcount\cnta
% \cnta 1111
% \thebnumexpr 2\cnta\relax

\item more generally, tacit multiplication applies in front of parenthesized
  sub-expressions, or sub |\bnumexpr...\relax| (or |\numexpr...\relax|),

\item the underscore |_| is accepted within the digits composing a number and
  is silently ignored by |\bnumexpr|,

\item |\numexpr| accepts \TeX\ syntax for hexadecimal input |"EF| (or octal
  input |'377|), but currently |\bnumexpr| does not. This could possibly be
  added in future%
%
\footnote{It is only a matter of copying pasting relevant code from
  \xintexprname, so depends upon user demands addressed to the author |;-)|.}
%
  (hexadecimal prefix |"| is part of the recognized
  |\xintiiexpr| syntax from \xintexprname if \xintbinhexname is loaded.) In
  the meantime, one may encapsulate such inputs (obeying \TeX's bound on
  numbers) into a sub |\numexpr...\relax|.
\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.

The documentation of \xintexprname explains that there is an
impact on the memory of \TeX{} (the string pool, the hash table) as 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 can become saturated and end the
\verb?latex|pdflatex? run, but the problem can be avoided via enlarged memory
parameters for |pdftex|, as made possible by modern TeX installations.
Anyhow, computations with thousands of digits take time, and this is probably
a more stringent constraint.

If the same operations need to be repeated again and again tens of thousands
of times on varying (big) numbers, the memory problem mentioned above may be
avoided by using nested macros rather than |\bnumexpr| or |\xintexpr|
expressions. Utility |\xintNewIIExpr| from package \xintexprname can be used
to construct the possibly very complicated nested macro from a given
expression with the needed operators and usual {\catcode`# 12 |#1, #2, #3,
  ...|} placeholders.

% je voulais dire qu'une telle macro pouvait être préparée séparément, mais il
% faudrait expliquer qu'il faut récupérer son \meaning, et j'ai le problème de
% mes \romannumeral`&&@ maintenant... note 2015/10/27. Donc je laisse tomber.

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), |//| (by default floored division),
|/:| (the associated modulo) and |!| (factorial).%
%
\footnote{Releases |1.2b| and earlier associated in the default configuration
  truncated division to |//|. This was changed at |1.2c| to stay in sync with
  \xintcorename |1.2p|. For backwards compatibility, one may add to existing
  document \string\bnumexprsetup\{div=\string\xintiiDivTrunc,
  mod=\string\xintiiModTrunc\}.}

The modulo |/:| is by default associated with the floored division |//|, but
using |\bnumexprsetup{mod=...}| it can, like the other operators, be remapped
to any macro of one's choice.

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.

There is currently no user interface to change precedence levels. The
three operators |/|, |//|, |/:| are at the same level of precedence as the
multiplication |*|. The factorial postfix |!| has highest precedence. The
minus signs inherit the precedence level of the previously encountered infix
operators.

In case of equal precedence the operations are left-associative,
hence:\newline \bneshow{2^3^4, (2^3)^4, 2^(3^4)}

The underscore |_| can be used to separate digits in long numbers, for
readability of the input.

\section{Options}

The sole package option is |custom|: it tells \bnumname not to load
package \xintcorename.

\section{\csh{bnumexprsetup}}

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.2p| is required) and uses \csa{bnumexprsetup} in the following
way:
\begin{verbatim}
    \usepackage{xintcore}
    \bnumexprsetup{add=\xintiiAdd, sub=\xintiiSub, mul=\xintiiMul,
                   divround=\xintiiDivRound, div=\xintiiDivFloor,
                   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.}

Macro |\bnumexprsetup| can be used multiple times in the same document, thus
allowing to switch math engines or to remap operators to some other arithmetic
macros of the same math engine. Its effect obeys the local scope.

\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</dtx>\relax
% \def<*package>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 }
%</dtx>
%<*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}[2017/07/09 v1.2b 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
\long\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
\long\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}
% |v1.2c| replaces former key |divtrunc| by |div|.
%    \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}[2017/12/04]%
    \bnumexprsetup{add=\xintiiAdd, sub=\xintiiSub, mul=\xintiiMul,
                   divround=\xintiiDivRound, div=\xintiiDivFloor,
                   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
{%
    \if    _#1\xint_dothis{\expandafter\BNE_scanint_d\xint_gobble_i}\fi
    \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
{%
    \if    _#1\xint_dothis\BNE_gobz_scanint_d\fi
    \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 <precedence> <operator> <locked number>.
% The <precedence> stops expansion and ultimately gives back control to a
% |\BNE_until_<op>| 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 <operator> 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 |^|).
%
% |v1.2c| has |//| and |/:| per default associated to floored division.
%    \begin{macrocode}
\def\BNE_tmpc #1#2#3#4#5#6#7%
{%
  \def #1##1% \BNE_op_<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_<op>_a
  {\xint_UDsignfork
    ##2{\expandafter #2\expandafter ##1\romannumeral-`0#4}%
      -{#3##1##2}%
   \krof }%
  \def #3##1##2##3##4% \BNE_until_<op>_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_div}%
\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_-<level>
    {%  get next number+operator then switch to _until macro
        \expandafter #2\romannumeral-`0\BNE_getnext
    }%
    \def #2##1% \BNE_until_-<level>_a
    {\xint_UDsignfork
        ##1{\expandafter #2\romannumeral-`0#1}%
          -{#3##1}%
     \krof }%
    \def #3##1##2##3% \BNE_until_-<level>_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
%</package>
%<*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 {873}
\makeatletter\check@checksum\makeatother
\Finale
%% End of file xint.dtx
