From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/bnumexpr/README | 126 +++ macros/latex/contrib/bnumexpr/bnumexpr.dtx | 1388 ++++++++++++++++++++++++++++ macros/latex/contrib/bnumexpr/bnumexpr.ins | 56 ++ macros/latex/contrib/bnumexpr/bnumexpr.pdf | Bin 0 -> 88010 bytes 4 files changed, 1570 insertions(+) create mode 100644 macros/latex/contrib/bnumexpr/README create mode 100644 macros/latex/contrib/bnumexpr/bnumexpr.dtx create mode 100644 macros/latex/contrib/bnumexpr/bnumexpr.ins create mode 100644 macros/latex/contrib/bnumexpr/bnumexpr.pdf (limited to 'macros/latex/contrib/bnumexpr') diff --git a/macros/latex/contrib/bnumexpr/README b/macros/latex/contrib/bnumexpr/README new file mode 100644 index 0000000000..a8f5c0341f --- /dev/null +++ b/macros/latex/contrib/bnumexpr/README @@ -0,0 +1,126 @@ +Source: bnumexpr.dtx +Version: v1.2e, 2019/01/08 (doc: 2019/01/08) +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 +, -, *, / 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: + + \bnumeval{( 92_874_927_979^5 - 31_9792_7979^6 ) / 30!} + + The above expands (in two steps) to `-4006240736596543944035189` + (the `/` does rounded division to match the `\numexpr` behaviour). + +The expression parser is scaled-down from the \xinttheiiexpr...\relax +parser as provided by package xintexpr[1]: it does not handle +hexadecimal input, boolean operators, dummy or user defined variables, +functions, etc... + +By default, the package loads xintcore[2] (release 1.3d is then +required) but it is possible via option _custom_ and macro +\bnumexprsetup to map the operators to macros of one's own choice. It is +the responsability of the user to load the packages providing these +custom macros. + +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 tailored +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. + + +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-2019 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 + +[1] http://www.ctan.org/pkg/xint + +[2] http://www.ctan.org/pkg/xint diff --git a/macros/latex/contrib/bnumexpr/bnumexpr.dtx b/macros/latex/contrib/bnumexpr/bnumexpr.dtx new file mode 100644 index 0000000000..085380f942 --- /dev/null +++ b/macros/latex/contrib/bnumexpr/bnumexpr.dtx @@ -0,0 +1,1388 @@ +% -*- coding: iso-latin-1; time-stamp-format: "%02d-%02m-%:y at %02H:%02M:%02S %Z" -*- +%<*dtx> +\def\bnedtxtimestamp {Time-stamp: <08-01-2019 at 13:04:43 CET>} +\iffalse +% +%<*drv> +%% --------------------------------------------------------------- +\def\bnedocdate {2019/01/08}% package bnumexpr documentation date +\def\bnepackdate{2019/01/08}% package bnumexpr date +\def\bneversion {1.2e} % package bnumexpr version +% +%<*readme>-------------------------------------------------------- + +| Source: bnumexpr.dtx +| Version: v1.2e, 2019/01/08 (doc: 2019/01/08) +| 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 `+`, `-`, `*`, `/` 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: + + \bnumeval{( 92_874_927_979^5 - 31_9792_7979^6 ) / 30!} + + The above expands (in two steps) to `-4006240736596543944035189` + (the `/` does rounded division to match the `\numexpr` behaviour). + +The expression parser is scaled-down from the `\xinttheiiexpr...\relax` +parser as provided by package xintexpr[^1]: it does not handle +hexadecimal input, boolean operators, dummy or user defined variables, +functions, etc... + +By default, the package loads xintcore[^1] (release 1.3d is then +required) but it is possible via option _custom_ and macro +`\bnumexprsetup` to map the operators to macros of one's own choice. It +is the responsability of the user to load the packages providing these +custom macros. + +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 tailored +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-2019 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-2019 by Jean-Francois Burnol +%% +% +%<*changes>------------------------------------------------------- +\item[1.2e (2019/01/08)] + Fixes a documentation glitch (extra braces when mentioning |\the\numexpr| or + |\thebnumexpr|). + +\item[1.2d (2019/01/07)] + \begin{itemize} + \item requires \xintcorename |1.3d| or later (if not using option |custom|). + \item adds |\bnumeval|\marg{expression} user interface. + \end{itemize} + +\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 |\.=| 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} + +\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}% utilisé avant pour urlcolor +%\colorlet{smallverbcolor}{RoyalPurple}% \colorlet{jfverbcolor}{yellow!5} +\colorlet{smallverbcolor}{NavyBlue}% +\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=SkyBlue,% +linkcolor=PineGreen,% +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$$} + \def\bneshoweval #1% + {|\bnumeval{#1}|$$\color{digitscolor}\bnumeval{#1}$$} +\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|\meta{expression}|\relax| which is +analogous to |\the\numexpr|\meta{expression}|\relax|, with these extensions: +\begin{itemize} +\item it allows arbitrarily big integers, +\item it computes powers (with either |**| or |^| as infix operator), +\item it computes factorials (with |!| as postfix operator), +\item it has an operator |//| for floored division and |/:| for the + associated modulo, +\item the space character can be used to separate in the source blocks of +digits for better readability of long numbers, +\item since |1.2b| the underscore |_| may also be used as visual digit + separator, +\item comma separated expressions are allowed. +\end{itemize} +It expands completely, but in two steps (whereas +|\the\numexpr|\meta{expression}|\relax| expands in one step only, and +|\numexpr| by itself is not expandable). + +|1.2d| adds a |\bnumeval|\marg{expression} interface. The |\bnumeval| macro +also expands completely in two steps. + +Examples: + +\noindent\bneshow {1 208 637 867 * (2 187 917 891 + 3 109 197 072)}% +\bneshoweval {(13_8089_1090-300_1890_2902)*(1083_1908_3901-109_8290_3890)}% +\bneshow{(92_874_927_979**5-31_9792_7979**6)/30!}% +\bneshoweval {30!/20!/21/22/23/24/25/(26*27*28*29)}% +\bneshow {13^50//12^50, 13^50/:12^50}% +\bneshoweval {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}% +\bneshoweval {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 \bneshoweval{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.3d| 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} + +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\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} +% |v1.2c| forgot to identify itself as such |:(|. Fixed (of course) at |v1.2d|. +% \begin{macrocode} +\NeedsTeXFormat{LaTeX2e}% +\ProvidesPackage{bnumexpr}[2019/01/08 v1.2e 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|. |v1.2d| requires (by +% default) |xintcore 1.3d|. +% \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}[2019/01/06]% xintcore 1.3d + \bnumexprsetup{add=\xintiiAdd, sub=\xintiiSub, mul=\xintiiMul, + divround=\xintiiDivRound, div=\xintiiDivFloor, + mod=\xintiiMod, pow=\xintiiPow, fac=\xintiiFac}% +\fi +% \end{macrocode} +% \subsection{\csh{bnumexpr}, \csh{thebnumexpr}, \csh{bnethe}, \csh{bnumeval}} +% 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. +% +% Attention |v1.2d| gives new meaning to |\bnumeval|, the former meaning is +% now named |\bnumexpro|. The leading space in |\BNE_wrap| is removed at it +% served to nothing. +% \begin{macrocode} +\def\bnumexpr {\romannumeral0\bnumexpro }% +\def\bnumexpro{\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\bnumeval#1% + {\romannumeral-`0\expandafter\BNE_unlock\romannumeral0\BNE_eval#1\relax}% +\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 . +% 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 |^|). +% +% |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_ + {% 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_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_- + {% 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 {881} +\makeatletter\check@checksum\makeatother +\Finale +%% End of file xint.dtx diff --git a/macros/latex/contrib/bnumexpr/bnumexpr.ins b/macros/latex/contrib/bnumexpr/bnumexpr.ins new file mode 100644 index 0000000000..90da59a83d --- /dev/null +++ b/macros/latex/contrib/bnumexpr/bnumexpr.ins @@ -0,0 +1,56 @@ +%% +%% This is file `bnumexpr.ins', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% bnumexpr.dtx (with options: `ins') +%% +%% IMPORTANT NOTICE: +%% +%% For the copyright see the source file. +%% +%% Any modified versions of this file must be renamed +%% with new filenames distinct from bnumexpr.ins. +%% +%% For distribution of the original source see the terms +%% for copying and modification in the file bnumexpr.dtx. +%% +%% This generated file may be distributed as long as the +%% original source files, as listed above, are part of the +%% same distribution. (The sources need not necessarily be +%% in the same archive or directory.) +%% --------------------------------------------------------------- +%% The bnumexpr package: Expressions with big integers +%% Copyright (C) 2014-2019 by Jean-Francois Burnol +%% +%% 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 +\endinput +%% +%% End of file `bnumexpr.ins'. diff --git a/macros/latex/contrib/bnumexpr/bnumexpr.pdf b/macros/latex/contrib/bnumexpr/bnumexpr.pdf new file mode 100644 index 0000000000..5d8bf66573 Binary files /dev/null and b/macros/latex/contrib/bnumexpr/bnumexpr.pdf differ -- cgit v1.2.3