diff options
author | Karl Berry <karl@freefriends.org> | 2007-09-16 00:07:34 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2007-09-16 00:07:34 +0000 |
commit | d85f248e3b38ea0ecda38c5340e3cadd08d65346 (patch) | |
tree | 52e17f32b395006895b3917bc7729c7ac1514ae3 /Master/texmf-dist/source/latex/oberdiek/intcalc.dtx | |
parent | 2389552f283181e0d8c610037712ade989112da3 (diff) |
oberdiek update (14sep07)
git-svn-id: svn://tug.org/texlive/trunk@4947 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/oberdiek/intcalc.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/oberdiek/intcalc.dtx | 3701 |
1 files changed, 3701 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/oberdiek/intcalc.dtx b/Master/texmf-dist/source/latex/oberdiek/intcalc.dtx new file mode 100644 index 00000000000..2cef807d937 --- /dev/null +++ b/Master/texmf-dist/source/latex/oberdiek/intcalc.dtx @@ -0,0 +1,3701 @@ +% \iffalse meta-comment +% +% Copyright (C) 2007 by Heiko Oberdiek <oberdiek@uni-freiburg.de> +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either +% version 1.3 of this license or (at your option) any later +% version. The latest version of this license is in +% http://www.latex-project.org/lppl.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 "maintained". +% +% This Current Maintainer of this work is Heiko Oberdiek. +% +% This work consists of the main source file intcalc.dtx +% and the derived files +% intcalc.sty, intcalc.pdf, intcalc.ins, intcalc.drv, +% intcalc-test1.tex, intcalc-test2.tex, intcalc-test3.tex, +% intcalc-test4.tex. +% +% Distribution: +% CTAN:macros/latex/contrib/oberdiek/intcalc.dtx +% CTAN:macros/latex/contrib/oberdiek/intcalc.pdf +% +% Unpacking: +% (a) If intcalc.ins is present: +% tex intcalc.ins +% (b) Without intcalc.ins: +% tex intcalc.dtx +% (c) If you insist on using LaTeX +% latex \let\install=y\input{intcalc.dtx} +% (quote the arguments according to the demands of your shell) +% +% Documentation: +% (a) If intcalc.drv is present: +% latex intcalc.drv +% (b) Without intcalc.drv: +% latex intcalc.dtx; ... +% The class ltxdoc loads the configuration file ltxdoc.cfg +% if available. Here you can specify further options, e.g. +% use A4 as paper format: +% \PassOptionsToClass{a4paper}{article} +% +% Programm calls to get the documentation (example): +% pdflatex intcalc.dtx +% makeindex -s gind.ist intcalc.idx +% pdflatex intcalc.dtx +% makeindex -s gind.ist intcalc.idx +% pdflatex intcalc.dtx +% +% Installation: +% TDS:tex/generic/oberdiek/intcalc.sty +% TDS:doc/latex/oberdiek/intcalc.pdf +% TDS:doc/latex/oberdiek/intcalc-test1.tex +% TDS:doc/latex/oberdiek/intcalc-test2.tex +% TDS:doc/latex/oberdiek/intcalc-test3.tex +% TDS:doc/latex/oberdiek/intcalc-test4.tex +% TDS:source/latex/oberdiek/intcalc.dtx +% +%<*ignore> +\begingroup + \def\x{LaTeX2e}% +\expandafter\endgroup +\ifcase 0\ifx\install y1\fi\expandafter + \ifx\csname processbatchFile\endcsname\relax\else1\fi + \ifx\fmtname\x\else 1\fi\relax +\else\csname fi\endcsname +%</ignore> +%<*install> +\input docstrip.tex +\Msg{************************************************************************} +\Msg{* Installation} +\Msg{* Package: intcalc 2007/09/09 v1.0 Expandable integer calculations (HO)} +\Msg{************************************************************************} + +\keepsilent +\askforoverwritefalse + +\preamble + +This is a generated file. + +Copyright (C) 2007 by Heiko Oberdiek <oberdiek@uni-freiburg.de> + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3 of this license or (at your option) any later +version. The latest version of this license is in + http://www.latex-project.org/lppl.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 "maintained". + +This Current Maintainer of this work is Heiko Oberdiek. + +This work consists of the main source file intcalc.dtx +and the derived files + intcalc.sty, intcalc.pdf, intcalc.ins, intcalc.drv, + intcalc-test1.tex, intcalc-test2.tex, intcalc-test3.tex, + intcalc-test4.tex. + +\endpreamble + +\generate{% + \file{intcalc.ins}{\from{intcalc.dtx}{install}}% + \file{intcalc.drv}{\from{intcalc.dtx}{driver}}% + \usedir{tex/generic/oberdiek}% + \file{intcalc.sty}{\from{intcalc.dtx}{package}}% + \usedir{doc/latex/oberdiek}% + \file{intcalc-test1.tex}{\from{intcalc.dtx}{test1}}% + \file{intcalc-test2.tex}{\from{intcalc.dtx}{test2,etex}}% + \file{intcalc-test3.tex}{\from{intcalc.dtx}{test3,noetex}}% + \file{intcalc-test4.tex}{\from{intcalc.dtx}{test4,etex}}% +} + +\obeyspaces +\Msg{************************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* file into a directory searched by TeX:} +\Msg{*} +\Msg{* intcalc.sty} +\Msg{*} +\Msg{* To produce the documentation run the file `intcalc.drv'} +\Msg{* through LaTeX.} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*} +\Msg{************************************************************************} + +\endbatchfile +%</install> +%<*ignore> +\fi +%</ignore> +%<*driver> +\NeedsTeXFormat{LaTeX2e} +\ProvidesFile{intcalc.drv}% + [2007/09/09 v1.0 Expandable integer calculations (HO)]% +\documentclass{ltxdoc} +\usepackage{holtxdoc} +\usepackage{wasysym} +\let\iint\relax +\let\iiint\relax +\usepackage[fleqn]{amsmath} + +\DeclareMathOperator{\opInv}{Inv} +\DeclareMathOperator{\opAbs}{Abs} +\DeclareMathOperator{\opSgn}{Sgn} +\DeclareMathOperator{\opMin}{Min} +\DeclareMathOperator{\opMax}{Max} +\DeclareMathOperator{\opCmp}{Cmp} +\DeclareMathOperator{\opInc}{Inc} +\DeclareMathOperator{\opDec}{Dec} +\DeclareMathOperator{\opAdd}{Add} +\DeclareMathOperator{\opSub}{Sub} +\DeclareMathOperator{\opShl}{Shl} +\DeclareMathOperator{\opShr}{Shr} +\DeclareMathOperator{\opMul}{Mul} +\DeclareMathOperator{\opSqr}{Sqr} +\DeclareMathOperator{\opFac}{Fac} +\DeclareMathOperator{\opPow}{Pow} +\DeclareMathOperator{\opDiv}{Div} +\DeclareMathOperator{\opMod}{Mod} +\DeclareMathOperator{\opInt}{Int} +\DeclareMathOperator{\opOdd}{ifodd} + +\newcommand*{\Def}{% + \ensuremath{% + \mathrel{\mathop{:}}=% + }% +} +\newcommand*{\op}[1]{% + \textsf{#1}% +} +\begin{document} + \DocInput{intcalc.dtx}% +\end{document} +%</driver> +% \fi +% +% \CheckSum{2665} +% +% \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 \~} +% +% \GetFileInfo{intcalc.drv} +% +% \title{The \xpackage{intcalc} package} +% \date{2007/09/09 v1.0} +% \author{Heiko Oberdiek\\\xemail{oberdiek@uni-freiburg.de}} +% +% \maketitle +% +% \begin{abstract} +% This package provides expandable arithmetic operations +% with integers. +% \end{abstract} +% +% \tableofcontents +% +% \section{Documentation} +% +% \subsection{Introduction} +% +% Package \xpackage{intcalc} defines arithmetic operations +% that deal with integers. Integers mean numbers in \TeX. +% The same restrictions apply, the range is limited to +% [-2147483647, 2147483647]. +% +% The operations have the form of macros that take one or +% two integers as parameter and return the integer result. +% The macro name is a three letter operation name prefixed +% by the package name, e.g. \cs{intcalcAdd}{10}{43} returns +% |53|. +% +% The macros are fully expandable, exactly two expansion +% steps generate the result. Therefore the operations +% may be used nearly everywhere in \TeX, even inside +% \cs{number}, \cs{csname}, file names, or other +% expandable contexts. +% +% The package contains two implementations of the operations. +% If \eTeX\ is detected then the macros are implemented +% using its features (\cs{numexpr}). Otherwise the slower +% implementation without \eTeX's help is choosen. +% +% \subsection{Conditions} +% +% \subsubsection{Preconditions} +% +% \begin{itemize} +% \item +% Arguments can be anything that \TeX\ interprets as ``number''. +% Examples: plain numbers, count or length register, macros +% that expands to a number. +% \item +% The arguments are limited to the range +% -2147483647 until 2147483647. These numbers belong to the range. +% Note that some operations +% have additionals restrictions to the range. +% \item +% The argument may be expressions that \cs{numexpr} +% understands if \eTeX\ is available. +% \item +% The resulting number must fit in the allowed range. +% \end{itemize} +% +% \subsubsection{Postconditions} +% +% Additional properties of the macros apart from calculating +% a correct result (of course \smiley): +% \begin{itemize} +% \item +% The macros are fully expandable. Thus they can +% be used inside \cs{edef}, \cs{csname}, after \cs{number}, +% for example. +% \item +% Furthermore exactly two expansion steps calculate the result. +% \item +% The number consists of one optional minus sign and one to +% ten digits. The first digit is larger than zero for +% numbers that consists of more than one digit. +% +% In short, the number format is exactly the same as +% \cs{number} generates. And the tokens (minus sign, digits) +% have catcode 12 (other). +% \item +% Call by value is simulated. First the arguments are +% converted to numbers. Then these numbers are used +% in the calculations. +% +% Remember that arguments +% may contain expensive macros or \eTeX\ expressions. +% This strategy avoids multiple evaluations of such +% arguments. +% \end{itemize} +% +% \subsection{Error handling} +% +% There are two kinds of errors if a precondition is violated: +% Some errors are detected by the macros, example: division by zero. +% In this cases an undefined control sequence is called and causes +% a TeX error message, example: \cs{IntCalcError:DivisionByZero}. +% The name of the control sequence contains +% the reason for the error. The \TeX\ error may be ignored. +% Then the operation returns zero as result. +% Because the macros are supposed to work in expandible contexts. +% An traditional error message, however, is not expandable and +% would break these contexts. +% +% If a number exceeds the range of -2147483647 until 2147483647, then +% \TeX\ throws an error ``Number too big'' and recovers by +% using biggest allowed value. +% Example for the negative number -3000000000 is replaced +% by -2147483647. +% +% \subsection{Operations} +% +% Some definition equations below use the function $\opInt$ +% that converts a real number to an integer. The number +% is truncated that means rounding to zero: +% \begin{gather*} +% \opInt(x) \Def +% \begin{cases} +% \lfloor x\rfloor & \text{if $x\geq0$}\\ +% \lceil x\rceil & \text{otherwise} +% \end{cases} +% \end{gather*} +% +% \subsubsection{\op{Inv}, \op{Abs}, \op{Sgn}} +% +% \begin{declcs}{intcalcInv} \M{x} +% \end{declcs} +% Macro \cs{intcalcInv} switches the sign. +% \begin{gather*} +% \opInv(x) \Def -x +% \end{gather*} +% +% \begin{declcs}{intcalcAbs} \M{x} +% \end{declcs} +% Macro \cs{intcalcAbs} returns the absolute value +% of integer \meta{x}. +% \begin{gather*} +% \opAbs(x) \Def \vert x\vert +% \end{gather*} +% +% \begin{declcs}{intcalcSgn} \M{x} +% \end{declcs} +% Macro \cs{intcalcSgn} encodes the sign of \meta{x} as number. +% \begin{gather*} +% \opSgn(x) \Def +% \begin{cases} +% -1& \text{if $x<0$}\\ +% 0& \text{if $x=0$}\\ +% 1& \text{if $x>0$} +% \end{cases} +% \end{gather*} +% These return values can easily be distinguished by \cs{ifcase}: +%\begin{quote} +%\begin{verbatim} +%\ifcase\intcalcSgn{<x>} +% $x=0$ +%\or +% $x>0$ +%\else +% $x<0$ +%\fi +%\end{verbatim} +%\end{quote} +% +% \subsubsection{\op{Min}, \op{Max}, \op{Cmp}} +% +% \begin{declcs}{intcalcMin} \M{x} \M{y} +% \end{declcs} +% Macro \cs{intcalcMin} returns the smaller of the two integers. +% \begin{gather*} +% \opMin(x,y) \Def +% \begin{cases} +% x & \text{if $x<y$}\\ +% y & \text{otherwise} +% \end{cases} +% \end{gather*} +% +% \begin{declcs}{intcalcMax} \M{x} \M{y} +% \end{declcs} +% Macro \cs{intcalcMax} returns the larger of the two integers. +% \begin{gather*} +% \opMax(x,y) \Def +% \begin{cases} +% x & \text{if $x>y$}\\ +% y & \text{otherwise} +% \end{cases} +% \end{gather*} +% +% \begin{declcs}{intcalcCmp} \M{x} \M{y} +% \end{declcs} +% Macro \cs{intcalcCmp} encodes the comparison result as number: +% \begin{gather*} +% \opCmp(x,y) \Def +% \begin{cases} +% -1 & \text{if $x<y$}\\ +% 0 & \text{if $x=y$}\\ +% 1 & \text{if $x>y$} +% \end{cases} +% \end{gather*} +% These values can be distinguished by \cs{ifcase}: +%\begin{quote} +%\begin{verbatim} +%\ifcase\intcalcCmp{<x>}{<y>} +% $x=y$ +%\or +% $x>y$ +%\else +% $x<y$ +%\fi +%\end{verbatim} +%\end{quote} +% +% \subsubsection{\op{Inc}, \op{Dec}, \op{Add}, \op{Sub}} +% +% \begin{declcs}{intcalcInc} \M{x} +% \end{declcs} +% Macro \cs{intcalcInc} increments \meta{x} by one. +% \begin{gather*} +% \opInc(x) \Def x + 1 +% \end{gather*} +% +% \begin{declcs}{intcalcDec} \M{x} +% \end{declcs} +% Macro \cs{intcalcDec} decrements \meta{x} by one. +% \begin{gather*} +% \opDec(x) \Def x - 1 +% \end{gather*} +% +% \begin{declcs}{intcalcAdd} \M{x} \M{y} +% \end{declcs} +% Macro \cs{intcalcAdd} adds the two numbers. +% \begin{gather*} +% \opAdd(x, y) \Def x + y +% \end{gather*} +% +% \begin{declcs}{intcalcSub} \M{x} \M{y} +% \end{declcs} +% Macro \cs{intcalcSub} calculates the difference. +% \begin{gather*} +% \opSub(x, y) \Def x - y +% \end{gather*} +% +% \subsubsection{\op{Shl}, \op{Shr}} +% +% \begin{declcs}{intcalcShl} \M{x} +% \end{declcs} +% Macro \cs{intcalcShl} implements shifting to the left that +% means the number is multiplied by two. Overflow is possible. +% Negative values are not permitted. +% \begin{gather*} +% \opShl(x) \Def x*2\qquad\text{for $x\geq0$} +% \end{gather*} +% +% \begin{declcs}{intcalcShr} \M{x} +% \end{declcs} +% Macro \cs{intcalcShr} implements shifting to the right. +% That is equivalent to an integer division by two. +% Negative values are not permitted. +% \begin{gather*} +% \opShr(x) \Def \opInt(x/2)\qquad\text{for $x\geq0$} +% \end{gather*} +% +% \subsubsection{\op{Mul}, \op{Sqr}, \op{Fac}, \op{Pow}} +% +% \begin{declcs}{intcalcMul} \M{x} \M{y} +% \end{declcs} +% Macro \cs{intcalcMul} calculates the product of +% \meta{x} and \meta{y}. +% \begin{gather*} +% \opMul(x,y) \Def x*y +% \end{gather*} +% +% \begin{declcs}{intcalcSqr} \M{x} +% \end{declcs} +% Macro \cs{intcalcSqr} returns the square product. +% \begin{gather*} +% \opSqr(x) \Def x^2 +% \end{gather*} +% +% \begin{declcs}{intcalcFac} \M{x} +% \end{declcs} +% Macro \cs{intcalcFac} returns the factorial of \meta{x}. +% Negative numbers are not permitted. +% \begin{gather*} +% \opFac(x) \Def x!\qquad\text{for $x\geq0$} +% \end{gather*} +% ($0! = 1$) +% +% \begin{declcs}{intcalcPow} M{x} M{y} +% \end{declcs} +% Macro \cs{intcalcPow} calculates the value of \meta{x} to the +% power of \meta{y}. The error ``division by zero'' is thrown +% if \meta{x} is zero and \meta{y} is negative. +% permitted: +% \begin{gather*} +% \opPow(x,y) \Def +% \opInt(x^y)\qquad\text{for $x\neq0$ or $y\geq0$} +% \end{gather*} +% ($0^0 = 1$) +% +% \subsubsection{\op{Div}, \op{Mul}} +% +% \begin{declcs}{intcalcDiv} \M{x} \M{y} +% \end{declcs} +% Macro \cs{intcalcDiv} performs an integer division. +% Argument \meta{y} must not be zero. +% \begin{gather*} +% \opDiv(x,y) \Def \opInt(x/y)\qquad\text{for $y\neq0$} +% \end{gather*} +% +% \begin{declcs}{intcalcMod} \M{x} \M{y} +% \end{declcs} +% Macro \cs{intcalcMod} gets the remainder of the integer +% division. The sign follows the divisor \meta{y}. +% Argument \meta{y} must not be zero. +% \begin{gather*} +% \opMod(x,y) \Def x\mathrel{\%}y\qquad\text{for $y\neq0$} +% \end{gather*} +% The result ranges: +% \begin{gather*} +% -\vert y\vert < \opMod(x,y) \leq 0\qquad\text{for $y<0$}\\ +% 0 \leq \opMod(x,y) < y\qquad\text{for $y\geq0$} +% \end{gather*} +% +% \StopEventually{ +% } +% +% \section{Implementation} +% +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \subsection{Reload check and package identification} +% Reload check, especially if the package is not used with \LaTeX. +% \begin{macrocode} +\begingroup + \catcode44 12 % , + \catcode45 12 % - + \catcode46 12 % . + \catcode58 12 % : + \catcode64 11 % @ + \expandafter\let\expandafter\x\csname ver@intcalc.sty\endcsname + \ifcase 0% + \ifx\x\relax % plain + \else + \ifx\x\empty % LaTeX + \else + 1% + \fi + \fi + \else + \expandafter\ifx\csname PackageInfo\endcsname\relax + \def\x#1#2{% + \immediate\write-1{Package #1 Info: #2.}% + }% + \else + \def\x#1#2{\PackageInfo{#1}{#2, stopped}}% + \fi + \x{intcalc}{The package is already loaded}% + \endgroup + \expandafter\endinput + \fi +\endgroup +% \end{macrocode} +% Package identification: +% \begin{macrocode} +\begingroup + \catcode40 12 % ( + \catcode41 12 % ) + \catcode44 12 % , + \catcode45 12 % - + \catcode46 12 % . + \catcode47 12 % / + \catcode58 12 % : + \catcode64 11 % @ + \expandafter\ifx\csname ProvidesPackage\endcsname\relax + \def\x#1#2#3[#4]{\endgroup + \immediate\write-1{Package: #3 #4}% + \xdef#1{#4}% + }% + \else + \def\x#1#2[#3]{\endgroup + #2[{#3}]% + \ifx#1\relax + \xdef#1{#3}% + \fi + }% + \fi +\expandafter\x\csname ver@intcalc.sty\endcsname +\ProvidesPackage{intcalc}% + [2007/09/09 v1.0 Expandable integer calculations (HO)] +% \end{macrocode} +% +% \subsection{Catcodes} +% +% \begin{macrocode} +\expandafter\edef\csname IntCalc@AtEnd\endcsname{% + \catcode64 \the\catcode64\relax +} +\catcode64 11 % @ +\def\TMP@EnsureCode#1#2{% + \edef\IntCalc@AtEnd{% + \IntCalc@AtEnd + \catcode#1 \the\catcode#1\relax + }% + \catcode#1 #2\relax +} +\TMP@EnsureCode{33}{12}% ! +\TMP@EnsureCode{40}{12}% ( +\TMP@EnsureCode{41}{12}% ) +\TMP@EnsureCode{42}{12}% * +\TMP@EnsureCode{43}{12}% + +\TMP@EnsureCode{45}{12}% - +\TMP@EnsureCode{47}{12}% / +\TMP@EnsureCode{58}{11}% : (letter!) +\TMP@EnsureCode{60}{12}% < +\TMP@EnsureCode{61}{12}% = +\TMP@EnsureCode{62}{12}% > +\TMP@EnsureCode{63}{14}% ? (comment!) +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname IntCalc@TestMode\endcsname\relax +\else + \catcode63=9 % ? (ignore) +\fi +? \let\IntCalc@@TestMode\IntCalc@TestMode +% \end{macrocode} +% +% \subsection{Macros independent of \eTeX} +% +% \begin{macro}{\IntCalc@Space} +% \begin{macrocode} +\def\IntCalc@Space{ } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Abs}, \op{Sgn}} +% +% \begin{macro}{\IntCalc@Abs} +% \begin{macrocode} +\def\IntCalc@Abs#1#2!{% + \ifx#1-% + #2% + \else + #1#2% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IntCalc@Sgn} +% \begin{macrocode} +\def\IntCalc@Sgn#1#2!{% + \ifx#1-% + -1% + \else + \ifx#10% + 0% + \else + 1% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Min}, \op{Max}, \op{Cmp}} +% +% \begin{macro}{\IntCalc@Min} +% \begin{macrocode} +\def\IntCalc@Min#1!#2!{% + \ifnum#1<#2 % + #1% + \else + #2% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IntCalc@Max} +% \begin{macrocode} +\def\IntCalc@Max#1!#2!{% + \ifnum#1>#2 % + #1% + \else + #2% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IntCalc@Cmp} +% \begin{macrocode} +\def\IntCalc@Cmp#1!#2!{% + \ifnum#1=#2 % + 0% + \else + \ifnum#1<#2 % + -% + \fi + 1% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Fac}} +% +% \begin{macro}{\IntCalc@Fac} +% It does not make much sense to calculate the +% faculty by an general algorithm. The allowed +% range of arguments is too low because of the +% limited integer domain. +% \begin{macrocode} +\def\IntCalc@Fac#1!{% + \ifcase#1 1% 0! + \or 1% 1! + \or 2% 2! + \or 6% 3! + \or 24% 4! + \or 120% 5! + \or 720% 6! + \or 5040% 7! + \or 40320% 8! + \or 362880% 9! + \or 3628800% 10! + \or 39916800% 11! + \or 479001600% 12! + \else + \ifnum#1<\z@ + 0\IntCalcError:FacNegative% + \else + 0\IntCalcError:FacOverflow% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Implementation based on \eTeX} +% +% Only \cs{numexpr} is used from \eTeX. +% \begin{macrocode} +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname numexpr\endcsname\relax +\else +% \end{macrocode} +% +% \subsubsection{\op{Inv}, \op{Abs}, \op{Sgn}} +% +% \begin{macro}{\intcalcInv} +% \begin{macrocode} + \def\intcalcInv#1{% + \number-\the\numexpr#1\relax\IntCalc@Space + }% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcAbs} +% \begin{macrocode} + \def\intcalcAbs#1{% + \number\expandafter\IntCalc@Abs\the\numexpr#1! % + }% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcSgn} +% \begin{macrocode} + \def\intcalcSgn#1{% + \number\expandafter\IntCalc@Sgn\the\numexpr#1! % + }% +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Min}, \op{Max}, \op{Cmp}} +% +% \begin{macro}{\intcalcMin} +% \begin{macrocode} + \def\intcalcMin#1#2{% + \number\expandafter\IntCalc@Min + \the\numexpr#1\expandafter!% + \the\numexpr#2! % + }% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcMax} +% \begin{macrocode} + \def\intcalcMax#1#2{% + \number\expandafter\IntCalc@Max + \the\numexpr#1\expandafter!% + \the\numexpr#2! % + }% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcCmp} +% \begin{macrocode} + \def\intcalcCmp#1#2{% + \number\expandafter\IntCalc@Cmp + \the\numexpr#1\expandafter!\the\numexpr#2! % + }% +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Inc}, \op{Dec}} +% +% \begin{macro}{\intcalcInc} +% \begin{macrocode} + \def\intcalcInc#1{% + \the\numexpr#1+1\relax + }% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcDec} +% \begin{macrocode} + \def\intcalcDec#1{% + \the\numexpr#1-1\relax + }% +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Add}, \op{Sub}} +% +% \begin{macro}{\intcalcAdd} +% \begin{macrocode} + \def\intcalcAdd#1#2{% + \the\numexpr#1+(#2)\relax + }% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcSub} +% \begin{macrocode} + \def\intcalcSub#1#2{% + \the\numexpr#1-(#2)\relax + }% +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Shl}, \op{Shr}} +% +% \begin{macro}{\intcalcShl} +% \begin{macrocode} + \def\intcalcShl#1{% + \number\expandafter\IntCalc@Shl\the\numexpr#1! % + }% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Shl} +% \begin{macrocode} + \def\IntCalc@Shl#1#2!{% + \ifx#1-% + 0\IntCalcError:ShlNegativeNumber% + \else + \the\numexpr#1#2*2\relax + \fi + }% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcShr} +% \begin{macrocode} + \def\intcalcShr#1{% + \number\expandafter\IntCalc@Shr\the\numexpr#1! % + }% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Shr} +% \begin{macrocode} + \def\IntCalc@Shr#1#2!{% + \ifx#1-% + 0\IntCalcError:ShrNegativeNumber% + \else + \ifodd#1#2 % + \the\numexpr(#1#2-1)/2\relax + \else + \the\numexpr#1#2/2\relax + \fi + \fi + }% +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Mul}, \op{Sqr}, \op{Fac}} +% +% \begin{macro}{\intcalcMul} +% \begin{macrocode} + \def\intcalcMul#1#2{% + \the\numexpr(#1)*(#2)\relax + }% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcSqr} +% \begin{macrocode} + \def\intcalcSqr#1{% + \number\expandafter\IntCalc@Sqr\the\numexpr#1! % + }% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Sqr} +% \begin{macrocode} + \def\IntCalc@Sqr#1!{% + \the\numexpr#1*#1\relax + }% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcFac} +% \begin{macrocode} + \def\intcalcFac#1{% + \number\expandafter\IntCalc@Fac\the\numexpr#1! % + }% +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Pow}} +% +% \begin{macro}{\intcalcPow} +% \begin{macrocode} + \def\intcalcPow#1#2{% + \number\expandafter\IntCalc@Pow + \the\numexpr#1\expandafter!% + \the\numexpr#2! % + }% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Pow} +% \begin{macrocode} + \def\IntCalc@Pow#1#2!#3#4!{% + \ifcase#3#4 % power = 0 + 1% + \or % power = 1 + #1#2% + \or % power = 2 + \the\numexpr#1#2*#1#2\relax + \else + \ifcase#1#2 % basis = 0, power <> 0 + 0% + \ifx#3-% power < 0 + 0\IntCalcError:DivisionByZero% + \fi + \or + 1% basis = 1 + \else + \ifnum#1#2=\m@ne % basis = -1 + \ifodd#3#4 % + -% + \fi + 1% + \else % |basis| > 1 + \ifx#3-% power < 0 + 0% + \else % power > 2 + \IntCalc@PowRec#1#2!#3#4!1!% + \fi + \fi + \fi + \fi + }% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@PowRec} +%\begin{quote} +%\begin{verbatim} +%Pow(b, p) { +% PowRec(b, p, 1) +%} +%PowRec(b, p, r) { +% if p == 1 then +% return r +% else +% ifodd p then +% return PowRec(b*b, (p-1)/2, r*b) % p div 2 = (p-1)/2 +% else +% return PowRec(b*b, (p-1)/2, r) +% fi +% fi +%} +%\end{verbatim} +%\end{quote} +% \begin{macrocode} + \def\IntCalc@PowRec#1!#2!#3!{% + \ifnum#2=\@ne + \the\numexpr#1*#3\relax + \else + \ifodd#2 % + \expandafter\IntCalc@PowRec + \the\numexpr#1*#1\expandafter!% + \the\numexpr(#2-1)/2\expandafter!% + \the\numexpr#1*#3\expandafter\expandafter\expandafter!% + \else + \expandafter\IntCalc@PowRec + \the\numexpr#1*#1\expandafter!% + \the\numexpr(#2-1)/2\expandafter!% + \number#3\expandafter\expandafter\expandafter!% + \fi + \fi + }% +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Div}, \op{Mod}} +% +% \TeX's \cs{divide} truncates, +% \eTeX's \cs{numexpr} rounds the result of a division. +% The rounding method is called ``Symmetric Arithmetic Rounding'' +% or ``Round-Half-Up'' (``Kaufm\"annisches Runden'' in German): +% \begin{quote} +% | 1 = 3 divide 2 = 1.5 = numexpr 3/2 = 2|\\ +% |-1 = -3 divide 2 = -1.5 = numexpr -3/2 = -2| +% \end{quote} +% Macro \cs{intcalcDiv} follows \TeX\ and truncates. +% The calculation is done by the following formula: +% \begin{gather} +% \opDiv(X,Y) = (X - (Y-1)/2)/Y\qquad\text{for $X, Y > 0$} +% \end{gather} +% The operator `/' is \cs{numexpr}'s division. +% \begin{macro}{\intcalcDiv} +% \begin{macrocode} + \def\intcalcDiv#1#2{% + \number\expandafter\IntCalc@Div + \the\numexpr#1\expandafter!% + \the\numexpr#2! % + }% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Div} +% \begin{macrocode} + \def\IntCalc@Div#1!#2!{% + \ifcase#2 % + 0\IntCalcError:DivisionByZero% + \else + \ifcase#1 % + 0% + \else + \expandafter\IntCalc@@Div + \romannumeral 0% + \ifnum#1<\z@ + \expandafter-\number-#1% + \else + \expandafter+\number#1% + \fi + \expandafter!% + \romannumeral 0% + \ifnum#2<\z@ + \expandafter-\number-#2% + \else + \expandafter+\number#2% + \fi + !% + \fi + \fi + }% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@@Div} +% \begin{macrocode} + \def\IntCalc@@Div#1#2!#3#4!{% + #1#3% + \the\numexpr(#2-(#4-1)/2)/#4\relax + }% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcMod} +% \begin{macrocode} + \def\intcalcMod#1#2{% + \number\expandafter\IntCalc@Mod + \the\numexpr#1\expandafter!% + \the\numexpr#2! % + }% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Mod} +% \begin{macrocode} + \def\IntCalc@Mod#1!#2!{% + \ifcase#2 % + 0\IntCalcError:DivisionByZero% + \else + \ifcase#1 % + 0% + \else + \expandafter\IntCalc@@Mod + \romannumeral 0% + \ifnum#1<\z@ + \expandafter-\number-#1% + \else + \expandafter+\number#1% + \fi + \expandafter!% + \romannumeral 0% + \ifnum#2<\z@ + \expandafter-\number-#2% + \else + \expandafter+\number#2% + \fi + !% + \fi + \fi + }% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@@Mod} +% \begin{macrocode} + \def\IntCalc@@Mod#1#2!#3#4!{% + \if#3+% + \if#1+% + \the\numexpr#2-\IntCalc@@Div+#2!+#4!*#4\relax + \else + \expandafter\IntCalc@ModX + \the\numexpr-#2+\IntCalc@@Div+#2!+#4!*#4!#4!% + \fi + \else + -% + \if#1+% + \expandafter\IntCalc@ModX + \the\numexpr-#2+\IntCalc@@Div+#2!+#4!*#4!#4!% + \else + \the\numexpr#2-\IntCalc@@Div+#2!+#4!*#4\relax + \fi + \fi + }% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@ModX} +% \begin{macrocode} + \def\IntCalc@ModX#1!#2!{% + \ifcase#1 % + 0% + \else + \the\numexpr#1+#2\relax + \fi + }% +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} + \IntCalc@AtEnd + \expandafter\endinput +\fi +% \end{macrocode} +% +% \subsection{Implementation without \eTeX} +% +% \subsubsection{\op{Inv}, \op{Abs}, \op{Sgn}} +% +% \begin{macro}{\intcalcInv} +% \begin{macrocode} +\def\intcalcInv#1{% + \number\expandafter\IntCalc@Inv\number-#1! % +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Inv} +% \begin{macrocode} +\def\IntCalc@Inv#1!{#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcAbs} +% \begin{macrocode} +\def\intcalcAbs#1{% + \number\expandafter\IntCalc@Abs\number#1! % +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcSgn} +% \begin{macrocode} +\def\intcalcSgn#1{% + \number\expandafter\IntCalc@Sgn\number#1! % +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Min}, \op{Max}, \op{Cmp}} +% +% \begin{macro}{\intcalcMin} +% \begin{macrocode} +\def\intcalcMin#1#2{% + \number\expandafter\IntCalc@Min + \number\number#1\expandafter!\number#2! % +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcMax} +% \begin{macrocode} +\def\intcalcMax#1#2{% + \number\expandafter\IntCalc@Max + \number\number#1\expandafter!\number#2! % +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcCmp} +% \begin{macrocode} +\def\intcalcCmp#1#2{% + \number\expandafter\IntCalc@Cmp + \number\number#1\expandafter!\number#2! % +}% +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Inc}, \op{Dec}} +% +% \begin{macro}{\intcalcInc} +% \begin{macrocode} +\def\intcalcInc#1{% + \number\expandafter\IntCalc@IncSwitch\number#1! % +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@IncSwitch} +% \begin{macrocode} +\def\IntCalc@IncSwitch#1#2!{% + \ifx#1-% + -% + \csname IntCalc@Empty% + \IntCalc@Dec#2!% + \else + \csname IntCalc@Empty% + \IntCalc@Inc#1#2!% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\intcalcDec} +% \begin{macrocode} +\def\intcalcDec#1{% + \number\expandafter\IntCalc@DecSwitch\number#1! % +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@DecSwitch} +% \begin{macrocode} +\def\IntCalc@DecSwitch#1#2!{% + \ifx#1-% + -% + \csname IntCalc@Empty% + \expandafter\IntCalc@Inc#2!% + \else + \ifx#10% + -1% + \else + \csname IntCalc@Empty% + \IntCalc@Dec#1#2!% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IntCalc@Inc} +% \begin{macrocode} +\def\IntCalc@Inc#1#2{% + \ifx#2!% + \csname IntCalc@IncDigit#1\endcsname1% + \else + \csname IntCalc@IncDigit#1% + \expandafter\IntCalc@Inc\expandafter#2% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@IncDigit[0-8]} +% \begin{macrocode} +\def\IntCalc@Temp#1#2{% + \expandafter\def\csname IntCalc@IncDigit#1\endcsname##1{% + \endcsname + 0% + \ifcase##1 % + #1% + \else + #2% + \fi + }% +} +\IntCalc@Temp 01 +\IntCalc@Temp 12 +\IntCalc@Temp 23 +\IntCalc@Temp 34 +\IntCalc@Temp 45 +\IntCalc@Temp 56 +\IntCalc@Temp 67 +\IntCalc@Temp 78 +\IntCalc@Temp 89 +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@IncDigit9} +% \begin{macrocode} +\expandafter\def\csname IntCalc@IncDigit9\endcsname#1{% + \expandafter\endcsname + \ifcase#1 % + 09% + \else + 10% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IntCalc@Dec} +% \begin{macrocode} +\def\IntCalc@Dec#1#2{% + \ifx#2!% + \csname IntCalc@DecDigit#1\endcsname1% + \else + \csname IntCalc@DecDigit#1% + \expandafter\IntCalc@Dec\expandafter#2% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@DecDigit[1-9]} +% \begin{macrocode} +\def\IntCalc@Temp#1#2{% + \expandafter\def\csname IntCalc@DecDigit#1\endcsname##1{% + \endcsname + 0% + \ifcase##1 % + #1% + \else + #2% + \fi + }% +} +\IntCalc@Temp 98 +\IntCalc@Temp 87 +\IntCalc@Temp 76 +\IntCalc@Temp 65 +\IntCalc@Temp 54 +\IntCalc@Temp 43 +\IntCalc@Temp 32 +\IntCalc@Temp 21 +\IntCalc@Temp 10 +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@DecDigit0} +% \begin{macrocode} +\expandafter\def\csname IntCalc@DecDigit0\endcsname#1{% + \expandafter\endcsname + \ifcase#1 % + 00% + \else + 19% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Add}, \op{Sub}} +% +% \begin{macro}{\intcalcAdd} +% \begin{macrocode} +\def\intcalcAdd#1#2{% + \number + \expandafter\IntCalc@AddSwitch + \number\number#1\expandafter!% + \number#2!% + \IntCalc@Space +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\intcalcSub} +% \begin{macrocode} +\def\intcalcSub#1#2{% + \number + \expandafter\IntCalc@AddSwitch + \number\number#1\expandafter!% + \number-\number#2!% + \IntCalc@Space +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IntCalc@AddSwitch} +% Decision table for \cs{IntCalc@AddSwitch}. +% By using less than zero operations, the sign +% of negative numbers can be removed by a simple \cs{IntCalc@Gobble} +% instead of the more expensive |\number-|. +% \begin{quote} +% \begin{tabular}[t]{@{}|l|l|l|l|l|@{}} +% \hline +% $x<0$ & $y<0$ & $ x< y$ & $-$ & $\opAdd(-x,-y)$\\ +% \cline{3-3}\cline{5-5} +% & & else & & $\opAdd(-y,-x)$\\ +% \cline{2-5} +% & else & $-x> y$ & $-$ & $\opSub(-x, y)$\\ +% \cline{3-5} +% & & else & $+$ & $\opSub( y,-x)$\\ +% \hline +% else & $y<0$ & $ x>-y$ & $+$ & $\opSub( x,-y)$\\ +% \cline{3-5} +% & & else & $-$ & $\opSub(-y, x)$\\ +% \cline{2-5} +% & else & $ x> y$ & $+$ & $\opAdd( x, y)$\\ +% \cline{3-3}\cline{5-5} +% & & else & & $\opAdd( y, x)$\\ +% \hline +% \end{tabular} +% \end{quote} +% \begin{macrocode} +\def\IntCalc@AddSwitch#1!#2!{% + \ifnum#1<\z@ + \ifnum#2<\z@ + -% + \ifnum#1<#2 % + \expandafter\IntCalc@Add\number-#1\expandafter!% + \IntCalc@Gobble#2!% + \else + \expandafter\IntCalc@Add\number-#2\expandafter!% + \IntCalc@Gobble#1!% + \fi + \else + \ifnum-#1>#2 % + -% + \expandafter\IntCalc@Sub\IntCalc@Gobble#1!#2!% + \else + \expandafter\IntCalc@Sub\number#2\expandafter!% + \IntCalc@Gobble#1!% + \fi + \fi + \else + \ifnum#2<\z@ + \ifnum#1>-#2 % + \expandafter\IntCalc@Sub\number#1\expandafter!% + \IntCalc@Gobble#2!% + \else + -% + \expandafter\IntCalc@Sub\IntCalc@Gobble#2!#1!% + \fi + \else + \ifnum#1>#2 % + \IntCalc@Add#1!#2!% + \else + \IntCalc@Add#2!#1!% + \fi + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Add} +% \begin{macrocode} +\def\IntCalc@Add#1!#2!{% + \ifcase#2 % + #1% + \else + \IntCalc@@Add#1!#2!000000000\IntCalc@Space + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Sub} +% \begin{macrocode} +\def\IntCalc@Sub#1!#2!{% + \ifnum#1=#2 % + 0% + \else + \IntCalc@@Sub#1!#2!000000000\IntCalc@Space + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@@Add} +% \begin{macrocode} +\def\IntCalc@@Add#1!#2#3!{% + \ifx\IntCalc@Empty#3\IntCalc@Empty + \@ReturnAfterElseFi{% + \IntCalc@@@Add!!#1!#2% + }% + \else + \@ReturnAfterFi{% + \IntCalc@@Add#1!#3!#2% + }% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@@Sub} +% \begin{macrocode} +\def\IntCalc@@Sub#1!#2#3!{% + \ifx\IntCalc@Empty#3\IntCalc@Empty + \@ReturnAfterElseFi{% + \IntCalc@@@Sub!!#1!#2% + }% + \else + \@ReturnAfterFi{% + \IntCalc@@Sub#1!#3!#2% + }% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IntCalc@@@Add} +% \begin{macrocode} +\def\IntCalc@@@Add#1!#2!#3#4!#5{% + \ifx\IntCalc@Empty#4\IntCalc@Empty + \csname IntCalc@Empty% + \@ReturnAfterElseFi{% + \IntCalc@ProcessAdd#1#3!#5#2% + }% + \else + \@ReturnAfterFi{% + \IntCalc@@@Add#1#3!#5#2!#4!% + }% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@@@Sub} +% \begin{macrocode} +\def\IntCalc@@@Sub#1!#2!#3#4!#5{% + \ifx\IntCalc@Empty#4\IntCalc@Empty + \csname IntCalc@Gobble% + \@ReturnAfterElseFi{% + \IntCalc@ProcessSub#1#3!#5#2% + }% + \else + \@ReturnAfterFi{% + \IntCalc@@@Sub#1#3!#5#2!#4!% + }% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IntCalc@ProcessAdd} +% \begin{macrocode} +\def\IntCalc@ProcessAdd#1#2!#3#4{% + \ifx\IntCalc@Empty#2\IntCalc@Empty + \csname IntCalc@AddDigit#1\endcsname#3% + \romannumeral0#4% + \else + \csname IntCalc@AddDigit#1\csname IntCalc@DigitCarry#3% + \@ReturnAfterFi{% + \IntCalc@ProcessAdd#2!#4% + }% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@ProcessSub} +% \begin{macrocode} +\def\IntCalc@ProcessSub#1#2!#3#4{% + \ifx\IntCalc@Empty#2\IntCalc@Empty + \csname IntCalc@SubDigit#1\endcsname#3% + \romannumeral0#4% + \else + \csname IntCalc@SubDigit#1\csname IntCalc@DigitCarry#3% + \@ReturnAfterFi{% + \IntCalc@ProcessSub#2!#4% + }% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@DigitCarry[0-9]} +% \begin{macrocode} +\def\IntCalc@Temp#1#2{% + \expandafter\def\csname IntCalc@DigitCarry#1\endcsname##1{% + \ifcase##1 % + \endcsname#1% + \else + \endcsname#2% + \fi + }% +} +\IntCalc@Temp 01 +\IntCalc@Temp 12 +\IntCalc@Temp 23 +\IntCalc@Temp 34 +\IntCalc@Temp 45 +\IntCalc@Temp 56 +\IntCalc@Temp 67 +\IntCalc@Temp 78 +\IntCalc@Temp 89 +\IntCalc@Temp 9{{10}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IntCalc@AddDigit0} +% \begin{macrocode} +\expandafter\def\csname IntCalc@AddDigit0\endcsname#1{% + \ifnum#1>9 % + \endcsname10% + \else + \endcsname0#1% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@AddDigit[1-9]} +% \begin{macrocode} +\def\IntCalc@Temp#1#2#3{% + \expandafter\def\csname IntCalc@AddDigit#1\endcsname##1{% + \ifnum##1>#2 % + \endcsname 1% + \else + \endcsname 0% + \fi + \ifcase##1 #1% 0 + #3% + \else #1% 10 + \fi + }% +} +\IntCalc@Temp 18{% + \or 2% 1 + \or 3% 2 + \or 4% 3 + \or 5% 4 + \or 6% 5 + \or 7% 6 + \or 8% 7 + \or 9% 8 + \or 0% 9 +}% +\IntCalc@Temp 27{% + \or 3% 1 + \or 4% 2 + \or 5% 3 + \or 6% 4 + \or 7% 5 + \or 8% 6 + \or 9% 7 + \or 0% 8 + \or 1% 9 +}% +\IntCalc@Temp 36{% + \or 4% 1 + \or 5% 2 + \or 6% 3 + \or 7% 4 + \or 8% 5 + \or 9% 6 + \or 0% 7 + \or 1% 8 + \or 2% 9 +}% +\IntCalc@Temp 45{% + \or 5% 1 + \or 6% 2 + \or 7% 3 + \or 8% 4 + \or 9% 5 + \or 0% 6 + \or 1% 7 + \or 2% 8 + \or 3% 9 +}% +\IntCalc@Temp 54{% + \or 6% 1 + \or 7% 2 + \or 8% 3 + \or 9% 4 + \or 0% 5 + \or 1% 6 + \or 2% 7 + \or 3% 8 + \or 4% 9 +}% +\IntCalc@Temp 63{% + \or 7% 1 + \or 8% 2 + \or 9% 3 + \or 0% 4 + \or 1% 5 + \or 2% 6 + \or 3% 7 + \or 4% 8 + \or 5% 9 +}% +\IntCalc@Temp 72{% + \or 8% 1 + \or 9% 2 + \or 0% 3 + \or 1% 4 + \or 2% 5 + \or 3% 6 + \or 4% 7 + \or 5% 8 + \or 6% 9 +}% +\IntCalc@Temp 81{% + \or 9% 1 + \or 0% 2 + \or 1% 3 + \or 2% 4 + \or 3% 5 + \or 4% 6 + \or 5% 7 + \or 6% 8 + \or 7% 9 +}% +\IntCalc@Temp 90{% + \or 0% 1 + \or 1% 2 + \or 2% 3 + \or 3% 4 + \or 4% 5 + \or 5% 6 + \or 6% 7 + \or 7% 8 + \or 8% 9 +}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IntCalc@SubDigit[0-9]} +% \begin{macrocode} +\def\IntCalc@Temp#1#2{% + \expandafter\def\csname IntCalc@SubDigit#1\endcsname##1{% + \ifnum##1>#1 % + \endcsname 1% + \else + \endcsname 0% + \fi + \ifcase##1 #1% 0 + #2% + \else #1% 10 + \fi + }% +} +\IntCalc@Temp 0{% + \or 9% 1 + \or 8% 2 + \or 7% 3 + \or 6% 4 + \or 5% 5 + \or 4% 6 + \or 3% 7 + \or 2% 8 + \or 1% 9 +} +\IntCalc@Temp 1{% + \or 0% 1 + \or 9% 2 + \or 8% 3 + \or 7% 4 + \or 6% 5 + \or 5% 6 + \or 4% 7 + \or 3% 8 + \or 2% 9 +} +\IntCalc@Temp 2{% + \or 1% 1 + \or 0% 2 + \or 9% 3 + \or 8% 4 + \or 7% 5 + \or 6% 6 + \or 5% 7 + \or 4% 8 + \or 3% 9 +} +\IntCalc@Temp 3{% + \or 2% 1 + \or 1% 2 + \or 0% 3 + \or 9% 4 + \or 8% 5 + \or 7% 6 + \or 6% 7 + \or 5% 8 + \or 4% 9 +} +\IntCalc@Temp 4{% + \or 3% 1 + \or 2% 2 + \or 1% 3 + \or 0% 4 + \or 9% 5 + \or 8% 6 + \or 7% 7 + \or 6% 8 + \or 5% 9 +} +\IntCalc@Temp 5{% + \or 4% 1 + \or 3% 2 + \or 2% 3 + \or 1% 4 + \or 0% 5 + \or 9% 6 + \or 8% 7 + \or 7% 8 + \or 6% 9 +} +\IntCalc@Temp 6{% + \or 5% 1 + \or 4% 2 + \or 3% 3 + \or 2% 4 + \or 1% 5 + \or 0% 6 + \or 9% 7 + \or 8% 8 + \or 7% 9 +} +\IntCalc@Temp 7{% + \or 6% 1 + \or 5% 2 + \or 4% 3 + \or 3% 4 + \or 2% 5 + \or 1% 6 + \or 0% 7 + \or 9% 8 + \or 8% 9 +} +\IntCalc@Temp 8{% + \or 7% 1 + \or 6% 2 + \or 5% 3 + \or 4% 4 + \or 3% 5 + \or 2% 6 + \or 1% 7 + \or 0% 8 + \or 9% 9 +} +\IntCalc@Temp 9{% + \or 8% 1 + \or 7% 2 + \or 6% 3 + \or 5% 4 + \or 4% 5 + \or 3% 6 + \or 2% 7 + \or 1% 8 + \or 0% 9 +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Shl}, \op{Shr}} +% +% \begin{macro}{\intcalcShl} +% \begin{macrocode} +\def\intcalcShl#1{% + \number\expandafter\IntCalc@ShlSwitch\number#1! % +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@ShlSwitch} +% \begin{macrocode} +\def\IntCalc@ShlSwitch#1!{% + \ifnum#1<\z@ + 0\IntCalcError:ShlNegativeNumber% + \else + \csname IntCalc@Empty% + \IntCalc@Shl#1!% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCal@ShlDigit} +% \begin{macrocode} +\def\IntCalc@Shl#1#2{% + \ifx#2!% + \csname IntCalc@ShlDigit#1\endcsname0% + \else + \csname IntCalc@ShlDigit#1% + \@ReturnAfterFi{% + \IntCalc@Shl#2% + }% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@ShlDigit0} +% \begin{macrocode} +\expandafter\def\csname IntCalc@ShlDigit0\endcsname{% + \endcsname0% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@ShlDigit[1-9]} +% \begin{macrocode} +\def\IntCalc@Temp#1#2#3#4#5{% + \expandafter\def\csname IntCalc@ShlDigit#1\endcsname##1{% + \expandafter\endcsname + \ifcase##1 % + #2#3% + \else + #4#5% + \fi + }% +} +\IntCalc@Temp 10203 +\IntCalc@Temp 20405 +\IntCalc@Temp 30607 +\IntCalc@Temp 40809 +\IntCalc@Temp 51011 +\IntCalc@Temp 61213 +\IntCalc@Temp 71415 +\IntCalc@Temp 81617 +\IntCalc@Temp 91819 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcShr} +% \begin{macrocode} +\def\intcalcShr#1{% + \number\expandafter\IntCalc@ShrSwitch\number#1! % +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@ShrSwitch} +% \begin{macrocode} +\def\IntCalc@ShrSwitch#1!{% + \ifnum#1<\z@ + 0\IntCalcError:ShrNegativeNumber% + \else + \IntCalc@Shr#1!% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Shr} +% \begin{macrocode} +\def\IntCalc@Shr#1#2{% + \IntCalc@ShrDigit#1!% + \ifx#2!% + \else + \@ReturnAfterFi{% + \ifodd#1 % + \@ReturnAfterElseFi{% + \IntCalc@Shr{1#2}% + }% + \else + \expandafter\IntCalc@Shr\expandafter#2% + \fi + }% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +\def\IntCalc@ShrDigit#1!{% + \ifcase#1 0% 0 + \or 0% 1 + \or 1% 2 + \or 1% 3 + \or 2% 4 + \or 2% 5 + \or 3% 6 + \or 3% 7 + \or 4% 8 + \or 4% 9 + \or 5% 10 + \or 5% 11 + \or 6% 12 + \or 6% 13 + \or 7% 14 + \or 7% 15 + \or 8% 16 + \or 8% 17 + \or 9% 18 + \or 9% 19 + \fi +} +% \end{macrocode} +% +% \subsubsection{\cs{IntCalc@Tim}} +% +% \begin{macro}{\IntCalc@Tim} +% Macro \cs{IntCalc@Tim} implements +% ``Number \emph{tim}es digit''. +% \begin{macrocode} +\def\IntCalc@Tim#1#2{% + \number + \ifcase#2 % 0 + 0% + \or % 1 + #1% + \else % 2-9 + \csname IntCalc@Empty% + \IntCalc@ProcessTim#2#1!% + \fi + \IntCalc@Space +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@ProcessTim} +% \begin{macrocode} +\def\IntCalc@ProcessTim#1#2#3{% + \ifx#3!% + \csname IntCalc@TimDigit#2\endcsname#10% + \else + \csname IntCalc@TimDigit#2\csname IntCalc@Param#1% + \@ReturnAfterFi{% + \IntCalc@ProcessTim#1#3% + }% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Param[0-9]} +% \begin{macrocode} +\def\IntCalc@Temp#1{% + \expandafter\def\csname IntCalc@Param#1\endcsname{% + \endcsname#1% + }% +} +\IntCalc@Temp 0% +\IntCalc@Temp 1% +\IntCalc@Temp 2% +\IntCalc@Temp 3% +\IntCalc@Temp 4% +\IntCalc@Temp 5% +\IntCalc@Temp 6% +\IntCalc@Temp 7% +\IntCalc@Temp 8% +\IntCalc@Temp 9% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@TimDigit0} +% \begin{macrocode} +\expandafter\def\csname IntCalc@TimDigit0\endcsname#1#2{% + \endcsname + 0#2% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@TimDigit1} +% \begin{macrocode} +\expandafter\def\csname IntCalc@TimDigit1\endcsname#1#2{% + \ifcase#2 % + \endcsname 0#1% + \else + \csname IntCalc@AddDigit#1\endcsname #2% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@TimDigit[2-9]} +% \begin{macrocode} +\def\IntCalc@Temp#1#2{% + \expandafter\def\csname IntCalc@TimDigit#1\endcsname##1{% + \expandafter\IntCalc@TimDigitCarry + \number + \ifcase##1 0% 0 + #2% + \fi + !% + }% +} +\IntCalc@Temp 2{% + \or 2% 1 + \or 4% 2 + \or 6% 3 + \or 8% 4 + \or 10% 5 + \or 12% 6 + \or 14% 7 + \or 16% 8 + \or 18% 9 +} +\IntCalc@Temp 3{% + \or 3% 1 + \or 6% 2 + \or 9% 3 + \or 12% 4 + \or 15% 5 + \or 18% 6 + \or 21% 7 + \or 24% 8 + \or 27% 9 +} +\IntCalc@Temp 4{% + \or 4% 1 + \or 8% 2 + \or 12% 3 + \or 16% 4 + \or 20% 5 + \or 24% 6 + \or 28% 7 + \or 32% 8 + \or 36% 9 +} +\IntCalc@Temp 5{% + \or 5% 1 + \or 10% 2 + \or 15% 3 + \or 20% 4 + \or 25% 5 + \or 30% 6 + \or 35% 7 + \or 40% 8 + \or 45% 9 +} +\IntCalc@Temp 6{% + \or 6% 1 + \or 12% 2 + \or 18% 3 + \or 24% 4 + \or 30% 5 + \or 36% 6 + \or 42% 7 + \or 48% 8 + \or 54% 9 +} +\IntCalc@Temp 7{% + \or 7% 1 + \or 14% 2 + \or 21% 3 + \or 28% 4 + \or 35% 5 + \or 42% 6 + \or 49% 7 + \or 56% 8 + \or 63% 9 +} +\IntCalc@Temp 8{% + \or 8% 1 + \or 16% 2 + \or 24% 3 + \or 32% 4 + \or 40% 5 + \or 48% 6 + \or 56% 7 + \or 64% 8 + \or 72% 9 +} +\IntCalc@Temp 9{% + \or 9% 1 + \or 18% 2 + \or 27% 3 + \or 36% 4 + \or 45% 5 + \or 54% 6 + \or 63% 7 + \or 72% 8 + \or 81% 9 +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@TimDigitCarry} +% \begin{macrocode} +\def\IntCalc@TimDigitCarry#1!{% + \ifnum#1<10 % + \csname IntCalc@AddDigit#1\expandafter\endcsname + \else + \@ReturnAfterFi{% + \IntCalc@@TimDigitCarry#1!% + }% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@@TimDigitCarry} +% \begin{macrocode} +\def\IntCalc@@TimDigitCarry#1#2!#3{% + \csname IntCalc@DigitCarry#1% + \csname IntCalc@AddDigit#2\endcsname #3% +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Mul}} +% +% \begin{macro}{\intcalcMul} +% \begin{macrocode} +\def\intcalcMul#1#2{% + \number + \expandafter\IntCalc@MulSwitch + \number\number#1\expandafter!% + \number#2!% + \IntCalc@Space +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IntCalc@MulSwitch} +% Decision table for \cs{IntCalc@MulSwitch}. +% \begin{quote} +% \begin{tabular}[t]{@{}|l|l|l|l|l|@{}} +% \hline +% $x<0$ & $y<0$ & $ x< y$ & $+$ & $\opMul(-x,-y)$\\ +% \cline{3-3}\cline{5-5} +% & & else & & $\opMul(-y,-x)$\\ +% \cline{2-5} +% & else & $-x> y$ & $-$ & $\opMul(-x, y)$\\ +% \cline{3-3}\cline{5-5} +% & & else & & $\opMul( y,-x)$\\ +% \hline +% else & $y<0$ & $ x>-y$ & $-$ & $\opMul( x,-y)$\\ +% \cline{3-3}\cline{5-5} +% & & else & & $\opMul(-y, x)$\\ +% \cline{2-5} +% & else & $ x> y$ & $+$ & $\opMul( x, y)$\\ +% \cline{3-3}\cline{5-5} +% & & else & & $\opMul( y, x)$\\ +% \hline +% \end{tabular} +% \end{quote} +% \begin{macrocode} +\def\IntCalc@MulSwitch#1!#2!{% + \ifnum#1<\z@ + \ifnum#2<\z@ + \ifnum#1<#2 % + \expandafter\IntCalc@Mul\number-#1\expandafter!% + \IntCalc@Gobble#2!% + \else + \expandafter\IntCalc@Mul\number-#2\expandafter!% + \IntCalc@Gobble#1!% + \fi + \else + -% + \ifnum-#1>#2 % + \expandafter\IntCalc@Mul\IntCalc@Gobble#1!#2!% + \else + \expandafter\IntCalc@Mul\number#2\expandafter!% + \IntCalc@Gobble#1!% + \fi + \fi + \else + \ifnum#2<\z@ + -% + \ifnum#1>-#2 % + \expandafter\IntCalc@Mul\number#1\expandafter!% + \IntCalc@Gobble#2!% + \else + \expandafter\IntCalc@Mul\IntCalc@Gobble#2!#1!% + \fi + \else + \ifnum#1>#2 % + \IntCalc@Mul#1!#2!% + \else + \IntCalc@Mul#2!#1!% + \fi + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Mul} +% \begin{macrocode} +\def\IntCalc@Mul#1!#2!{% + \ifcase#2 % + 0% + \or + #1% + \or + \csname IntCalc@Empty% + \expandafter\IntCalc@Shl#1!% + \else + \ifnum#2<10 % + \IntCalc@Tim{#1}#2% + \else + \IntCalc@ProcessMul!#2!#1!% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Mul} +% \begin{macrocode} +\def\IntCalc@ProcessMul#1!#2#3!#4!{% + \ifx\IntCalc@Empty#3\IntCalc@Empty + \expandafter\IntCalc@Add\number + #10\expandafter\expandafter\expandafter!% + \IntCalc@Tim{#4}#2!% + \else + \ifx\IntCalc@Empty#1\IntCalc@Empty + \expandafter\expandafter\expandafter\IntCalc@ProcessMul + \IntCalc@Tim{#4}#2!% + #3!#4!% + \else + \expandafter\IntCalc@ProcessMul\number + \expandafter\IntCalc@Add\number% + #10\expandafter\expandafter\expandafter!% + \IntCalc@Tim{#4}#2!!% + #3!#4!% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Sqr}, \op{Fac}} +% +% \begin{macro}{\intcalcSqr} +% \begin{macrocode} +\def\intcalcSqr#1{% + \number\expandafter\IntCalc@Sqr\number#1! % +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Sqr} +% \begin{macrocode} +\def\IntCalc@Sqr#1#2!{% + \ifx#1-% + \IntCalc@Mul#2!#2!% + \else + \IntCalc@Mul#1#2!#1#2!% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intcalcFac} +% \begin{macrocode} +\def\intcalcFac#1{% + \number\expandafter\IntCalc@Fac\number#1! % +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Pow}} +% +% \begin{macro}{\intcalcPow} +% \begin{macrocode} +\def\intcalcPow#1#2{% + \number\expandafter\IntCalc@Pow + \number\number#1\expandafter!% + \number#2! % +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Pow} +% \begin{macrocode} +\def\IntCalc@Pow#1#2!#3#4!{% + \ifcase#3#4 % power = 0 + 1% + \or % power = 1 + #1#2% + \or % power = 2 + \ifx#1-% + \IntCalc@Mul#2!#2!% + \else + \IntCalc@Mul#1#2!#1#2!% + \fi + \else + \ifcase#1#2 % basis = 0, power <> 0 + 0% + \ifx#3-% power < 0 + 0\IntCalcError:DivisionByZero% + \fi + \or + 1% basis = 1 + \else + \ifnum#1#2=\m@ne % basis = -1 + \ifodd#3#4 % + -% + \fi + 1% + \else % |basis| > 1 + \ifx#3-% power < 0 + 0% + \else % power > 2 + \ifx#1-% basis < 0 + \ifodd#3#4 % + -% + \fi + \IntCalc@PowRec#2!#3#4!1!% + \else + \IntCalc@PowRec#1#2!#3#4!1!% + \fi + \fi + \fi + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@PowRec} +%\begin{quote} +%\begin{verbatim} +%Pow(b, p) { +% PowRec(b, p, 1) +%} +%PowRec(b, p, r) { +% if p == 1 then +% return r +% else +% ifodd p then +% return PowRec(b*b, p div 2, r*b) % p div 2 = (p-1)/2 +% else +% return PowRec(b*b, p div 2, r) +% fi +% fi +%} +%\end{verbatim} +%\end{quote} +% \begin{macrocode} +\def\IntCalc@PowRec#1!#2!#3!{% + \ifnum#2=\@ne + \ifnum#1>#3 % + \IntCalc@Mul#1!#3!% + \else + \IntCalc@Mul#3!#1!% + \fi + \else + \expandafter\IntCalc@PowRec + \number\IntCalc@Mul#1!#1!\expandafter!% + \number\intcalcShr{#2}\expandafter!% + \number + \ifodd#2 % + \ifnum#1>#3 % + \IntCalc@Mul#1!#3!% + \else + \IntCalc@Mul#3!#1!% + \fi + \else + #3% + \fi + \expandafter!% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Div}} +% +% \begin{macro}{\intcalcDiv} +% \begin{macrocode} +\def\intcalcDiv#1#2{% + \number\expandafter\IntCalc@Div + \number\number#1\expandafter!% + \number#2! % +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Div} +% \begin{macrocode} +\def\IntCalc@Div#1!#2!{% + \ifcase#2 % + 0\IntCalcError:DivisionByZero% + \else + \ifcase#1 % + 0% + \else + \expandafter\IntCalc@DivSwitch + \number#1\expandafter!% + \number#2!% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@DivSwitch} +% Decision table for \cs{IntCalc@DivSwitch}. +% \begin{quote} +% \begin{tabular}[t]{@{}|l|l|l|l|l|@{}} +% \hline +% $x<0$ & $y<0$ & $ x< y$ & $+$ & $\opDiv(-x,-y)$\\ +% \cline{3-3}\cline{5-5} +% & & else & & $\opDiv(-y,-x)$\\ +% \cline{2-5} +% & else & $-x> y$ & $-$ & $\opDiv(-x, y)$\\ +% \cline{3-3}\cline{5-5} +% & & else & & $\opDiv( y,-x)$\\ +% \hline +% else & $y<0$ & $ x>-y$ & $-$ & $\opDiv( x,-y)$\\ +% \cline{3-3}\cline{5-5} +% & & else & & $\opDiv(-y, x)$\\ +% \cline{2-5} +% & else & $ x> y$ & $+$ & $\opDiv( x, y)$\\ +% \cline{3-3}\cline{5-5} +% & & else & & $\opDiv( y, x)$\\ +% \hline +% \end{tabular} +% \end{quote} +% \begin{macrocode} +\def\IntCalc@DivSwitch#1!#2!{% + \ifnum#1<\z@ + \ifnum#2<\z@ + \expandafter\IntCalc@@Div\number-#1\expandafter!% + \IntCalc@Gobble#2!% + \else + -% + \expandafter\IntCalc@@Div\IntCalc@Gobble#1!#2!% + \fi + \else + \ifnum#2<\z@ + -% + \expandafter\IntCalc@@Div\number#1\expandafter!% + \IntCalc@Gobble#2!% + \else + \IntCalc@@Div#1!#2!% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@@Div} +% \begin{macrocode} +\def\IntCalc@@Div#1!#2!{% + \ifnum#1>#2 % + \ifcase#2 % 0 already catched +? \IntCalcError:ThisCannotHappen% + \or % 1 + #1% + \or % 2 + \IntCalc@Shr#1!% + \else + \IntCalc@DivStart!#1!#2!#2!% + \fi + \else + \ifnum#1=#2 % + 1% + \else + 0% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@DivStart} +% \begin{macrocode} +\def\IntCalc@DivStart#1!#2#3!#4#5{% + \ifx#5!% + \@ReturnAfterElseFi{% + \IntCalc@DivStartI{#1#2}#3=!% + }% + \else + \@ReturnAfterFi{% + \IntCalc@DivStart{#1#2}!#3!#5% + }% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@StartI} +% \begin{macrocode} +\def\IntCalc@DivStartI#1!#2!{% + \expandafter\IntCalc@DivStartII + \number#2\expandafter\expandafter\expandafter!% + \intcalcShl{#2}!% + #1!% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@StartII} +% \begin{macrocode} +\def\IntCalc@DivStartII#1!#2!{% + \expandafter\IntCalc@DivStartIII + \number#1\expandafter!% + \number#2\expandafter\expandafter\expandafter!% + \intcalcShl{#2}!% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@StartIII} +% \begin{macrocode} +\def\IntCalc@DivStartIII#1!#2!#3!{% + \expandafter\IntCalc@DivStartIV + \number#1\expandafter!% + \number#2\expandafter!% + \number#3\expandafter!% + \number\IntCalc@Add#3!#2!\expandafter\expandafter\expandafter!% + \intcalcShl{#3}!% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@StartIV} +% \begin{macrocode} +\def\IntCalc@DivStartIV#1!#2!#3!#4!#5!#6!{% + \IntCalc@ProcessDiv#6!#1!#2!#3!#4!#5!/% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@ProcessDiv} +% \begin{macrocode} +\def\IntCalc@ProcessDiv#1#2#3!#4!#5!#6!#7!#8!#9/{% + #9% + \ifnum#1<#4 % 0 + 0% + \ifx#2=% + \else + \IntCalc@ProcessDiv{#1#2}#3!#4!#5!#6!#7!#8!% + \fi + \else % 1-9 + \ifnum#1<#5 % 1 + 1% + \ifx#2=% + \else + \expandafter\IntCalc@ProcessDiv\expandafter{% + \number\IntCalc@Sub#1!#4!% + #2% + }#3!#4!#5!#6!#7!#8!% + \fi + \else % 2-9 + \ifnum#1<#7 % 2 3 4 5 + \ifnum#1<#6 % 2 3 + \@ReturnAfterElseFi{% + \expandafter\IntCalc@@ProcessDiv + \number\IntCalc@Sub#1!#5!!% + 23% + }% + \else % 4 5 + \@ReturnAfterFi{% + \expandafter\IntCalc@@ProcessDiv + \number\IntCalc@Sub#1!#6!!% + 45% + }% + \fi + #2#3!#4!#5!#6!#7!#8!% + \else % 6 7 8 9 + \ifnum#1<#8 % 6 7 + \@ReturnAfterElseFi{% + \expandafter\IntCalc@@ProcessDiv + \number\IntCalc@Sub#1!#7!!% + 67% + }% + \else % 8 9 + \@ReturnAfterFi{% + \expandafter\IntCalc@@ProcessDiv + \number\IntCalc@Sub#1!#8!!% + 89% + }% + \fi + #2#3!#4!#5!#6!#7!#8!% + \fi + \fi + \fi + \ifx#2=% + \expandafter\IntCalc@Gobble + \fi + /% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@@ProcessDiv} +% \begin{macrocode} +\def\IntCalc@@ProcessDiv#1!#2#3#4#5!#6!{% + \ifnum#1<#6 % + #2% + \@ReturnAfterElseFi{% + \ifx#4=% + \expandafter\IntCalc@CleanupIV + \else + \@ReturnAfterFi{% + \IntCalc@ProcessDiv{#1#4}#5!#6!% + }% + \fi + }% + \else + #3% + \@ReturnAfterFi{% + \ifx#4=% + \expandafter\IntCalc@CleanupIV + \else + \@ReturnAfterFi{% + \expandafter\IntCalc@ProcessDiv\expandafter{% + \number\IntCalc@Sub#1!#6!\IntCalc@Space + #4% + }#5!#6!% + }% + \fi + }% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@CleanupIV} +% \begin{macrocode} +\def\IntCalc@CleanupIV#1!#2!#3!#4!{} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\op{Mod}} +% +% \begin{macro}{\intcalcMod} +% \begin{macrocode} +\def\intcalcMod#1#2{% + \number\expandafter\IntCalc@Mod + \number\number#1\expandafter!% + \number#2! % +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\intcalc@Mod} +% Pseudocode/decision table for \cs{intcalc@Mod}. +% \begin{quote} +% \begin{tabular}{@{}lll@{}} +% if & $y=0$ & DivisionByZero\\ +% elsif & $y<0$ & $-\opMod(-x,-y)$\\ +% elsif & $x=0$ & 0\\ +% elsif & $y=1$ & 0\\ +% elsif & $y=2$ & $\opOdd(x)\mathbin{?}1\mathbin{:}0$\\ +% elsif & $x<0$ & +% $z\leftarrow x+(x/y)*x;\quad (z<0)\mathbin{?}z+x\mathbin{:}z$\\ +% else & & $x-(x/y)*x$\\ +% \\ +% \end{tabular} +% \end{quote} +% \begin{macrocode} +\def\IntCalc@Mod#1!#2!{% + \ifcase#2 % + 0\IntCalcError:DivisionByZero% + \else + \ifnum#2<\z@ + -% + \expandafter\IntCalc@Mod + \number-#1\expandafter!% + \number-#2!% + \else + \ifcase#1 % + 0% + \else + \ifcase#2 % 0 already catched +? \IntCalcError:ThisCannotHappen% + \or % 1 + 0% + \or % 2 + \ifodd#1 % + 1% + \else + 0% + \fi + \else + \ifnum#1<\z@ + \expandafter\IntCalc@ModShift + \number-% + \expandafter\IntCalc@Sub + \number\IntCalc@Gobble#1\expandafter!% + \number\intcalcMul{#2}{% + \expandafter\IntCalc@Div\IntCalc@Gobble#1!#2!% + }!% + !#2!% + \else + \expandafter\IntCalc@Sub\number#1\expandafter!% + \number\intcalcMul{#2}{\IntCalc@Div#1!#2!}!% + \fi + \fi + \fi + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@ModShift} +% \begin{macrocode} +\def\IntCalc@ModShift#1!#2!{% + \ifnum#1<\z@ + \expandafter\IntCalc@Sub\number#2\expandafter!% + \IntCalc@Gobble#1!% + \else + #1% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Help macros} +% +% \begin{macro}{\IntCalc@Empty} +% \begin{macrocode} +\def\IntCalc@Empty{} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IntCalc@Gobble} +% \begin{macrocode} +\def\IntCalc@Gobble#1{} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@ReturnAfterFi} +% \begin{macrocode} +\long\def\@ReturnAfterFi#1\fi{\fi#1}% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@ReturnAfterElseFi} +% \begin{macrocode} +\long\def\@ReturnAfterElseFi#1\else#2\fi{\fi#1}% +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\IntCalc@AtEnd +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \section{Test} +% +% \subsection{Catcode checks for loading} +% +% \begin{macrocode} +%<*test1> +% \end{macrocode} +% \begin{macrocode} +\catcode`\@=11 % +\def\RestoreCatcodes{} +\count@=0 % +\loop + \edef\RestoreCatcodes{% + \RestoreCatcodes + \catcode\the\count@=\the\catcode\count@\relax + }% +\ifnum\count@<255 % + \advance\count@\@ne +\repeat + +\def\RangeCatcodeInvalid#1#2{% + \count@=#1\relax + \loop + \catcode\count@=15 % + \ifnum\count@<#2\relax + \advance\count@\@ne + \repeat +} +\def\Test{% + \RangeCatcodeInvalid{0}{47}% + \RangeCatcodeInvalid{58}{64}% + \RangeCatcodeInvalid{91}{96}% + \RangeCatcodeInvalid{123}{255}% + \catcode`\@=12 % + \catcode`\\=0 % + \catcode`\{=1 % + \catcode`\}=2 % + \catcode`\#=6 % + \catcode`\[=12 % + \catcode`\]=12 % + \catcode`\%=14 % + \catcode`\ =10 % + \catcode13=5 % + \input intcalc.sty\relax + \RestoreCatcodes +} +\Test +\csname @@end\endcsname +\end +% \end{macrocode} +% \begin{macrocode} +%</test1> +% \end{macrocode} +% +% \subsection{Macro tests} +% +% \subsubsection{Preamble with test macro definitions} +% +% \begin{macrocode} +%<*test2|test3|test4> +\NeedsTeXFormat{LaTeX2e} +\nofiles +\documentclass{article} +%<noetex>\let\SavedNumexpr\numexpr +%<noetex>\let\numexpr\UNDEFINED +\makeatletter +\chardef\IntCalc@TestMode=1 % +\makeatother +\usepackage{intcalc}[2007/09/09] +%<noetex>\let\numexpr\SavedNumexpr +\usepackage{qstest} +\IncludeTests{*} +\LogTests{log}{*}{*} +%</test2|test3|test4> +%<*test2|test3> +\newcommand*{\TestSpaceAtEnd}[1]{% +%<noetex> \let\SavedNumexpr\numexpr +%<noetex> \let\numexpr\UNDEFINED + \edef\resultA{#1}% + \edef\resultB{#1 }% +%<noetex> \let\numexpr\SavedNumexpr + \Expect*{\resultA\space}*{\resultB}% +} +\newcommand*{\TestResult}[2]{% +%<noetex> \let\SavedNumexpr\numexpr +%<noetex> \let\numexpr\UNDEFINED + \edef\result{#1}% +%<noetex> \let\numexpr\SavedNumexpr + \Expect*{\result}{#2}% +} +\newcommand*{\TestResultTwoExpansions}[2]{% +%<*noetex> + \begingroup + \let\numexpr\UNDEFINED + \expandafter\expandafter\expandafter + \endgroup +%</noetex> + \expandafter\expandafter\expandafter\Expect + \expandafter\expandafter\expandafter{#1}{#2}% +} +\newcount\TestCount +%<etex>\newcommand*{\TestArg}[1]{\numexpr#1\relax} +%<noetex>\newcommand*{\TestArg}[1]{#1} +\newcommand*{\TestTeXDivide}[2]{% + \TestCount=\TestArg{#1}\relax + \divide\TestCount by \TestArg{#2}\relax + \Expect*{\intcalcDiv{#1}{#2}}*{\the\TestCount}% +} +\newcommand*{\Test}[2]{% + \TestResult{#1}{#2}% + \TestResultTwoExpansions{#1}{#2}% + \TestSpaceAtEnd{#1}% +} +\newcommand*{\TestExch}[2]{\Test{#2}{#1}} +\newcommand*{\TestInv}[2]{% + \Test{\intcalcInv{#1}}{#2}% +} +\newcommand*{\TestAbs}[2]{% + \Test{\intcalcAbs{#1}}{#2}% +} +\newcommand*{\TestSgn}[2]{% + \Test{\intcalcSgn{#1}}{#2}% +} +\newcommand*{\TestMin}[3]{% + \Test{\intcalcMin{#1}{#2}}{#3}% +} +\newcommand*{\TestMax}[3]{% + \Test{\intcalcMax{#1}{#2}}{#3}% +} +\newcommand*{\TestCmp}[3]{% + \Test{\intcalcCmp{#1}{#2}}{#3}% +} +\newcommand*{\TestInc}[2]{% + \Test{\intcalcInc{#1}}{#2}% +} +\newcommand*{\TestDec}[2]{% + \Test{\intcalcDec{#1}}{#2}% +} +\newcommand*{\TestAdd}[3]{% + \Test{\intcalcAdd{#1}{#2}}{#3}% +} +\newcommand*{\TestSub}[3]{% + \Test{\intcalcSub{#1}{#2}}{#3}% +} +\newcommand*{\TestShl}[2]{% + \Test{\intcalcShl{#1}}{#2}% +} +\newcommand*{\TestShr}[2]{% + \Test{\intcalcShr{#1}}{#2}% +} +\newcommand*{\TestMul}[3]{% + \Test{\intcalcMul{#1}{#2}}{#3}% +} +\newcommand*{\TestSqr}[2]{% + \Test{\intcalcSqr{#1}}{#2}% +} +\newcommand*{\TestFac}[2]{% + \expandafter\TestExch\expandafter{\the\numexpr#2}{\intcalcFac{#1}}% +} +\newcommand*{\TestPow}[3]{% + \Test{\intcalcPow{#1}{#2}}{#3}% +} +\newcommand*{\TestDiv}[3]{% + \Test{\intcalcDiv{#1}{#2}}{#3}% + \TestTeXDivide{#1}{#2}% +} +\newcommand*{\TestMod}[3]{% + \Test{\intcalcMod{#1}{#2}}{#3}% +} +%</test2|test3> +%<*test4> +\newcommand*{\TestDo}[2]{% + \ifcase\numexpr#2\relax + \else + \edef\temp{\intcalcMod{#1}{#2}}% + \Expect*{% + \the\numexpr + \intcalcMul{% + \intcalcDiv{\intcalcAbs{#1}}{\intcalcAbs{#2}}% + }{\intcalcAbs{#2}}% + +\intcalcMod{\intcalcAbs{#1}}{\intcalcAbs{#2}}\relax + }*{\the\numexpr\intcalcAbs{#1}\relax}% + \fi +} +\newcommand*{\TestOne}[2]{% + \TestDo{#1}{#1}% +} +\newcommand*{\TestTwo}[3]{% + \TestDo{#1}{#2}% + \TestDo{#2}{#1}% +} +\let\TestInv\TestOne +\let\TestAbs\TestOne +\let\TestSgn\TestOne +\let\TestMin\TestTwo +\let\TestMax\TestTwo +\let\TestCmp\TestTwo +\let\TestInc\TestOne +\let\TestDec\TestOne +\let\TestAdd\TestTwo +\let\TestSub\TestTwo +\let\TestShl\TestOne +\let\TestShr\TestOne +\let\TestMul\TestTwo +\let\TestSqr\TestOne +\def\TestFac#1#2{} +\let\TestPow\TestTwo +\let\TestDiv\TestTwo +\let\TestMod\TestTwo +%</test4> +% \end{macrocode} +% +% \subsubsection{Test sets} +% +% \begin{macrocode} +%<*test2|test3|test4> +\makeatletter + +\begin{qstest}{inv}{inv}% + \TestInv{0}{0}% + \TestInv{1}{-1}% + \TestInv{-1}{1}% + \TestInv{10}{-10}% + \TestInv{-10}{10}% + \TestInv{2147483647}{-2147483647}% + \TestInv{-2147483647}{2147483647}% + \TestInv{ 0 }{0}% + \TestInv{ 1 }{-1}% + \TestInv{--1}{-1}% + \TestInv{\z@}{0}% + \TestInv{\@ne}{-1}% + \TestInv{\m@ne}{1}% +%<*etex> + \TestInv{-10+30}{-20}% + \TestInv{10-30}{20}% +%</etex> +\end{qstest} + +\begin{qstest}{abs}{abs}% + \TestAbs{0}{0}% + \TestAbs{1}{1}% + \TestAbs{-1}{1}% + \TestAbs{10}{10}% + \TestAbs{-10}{10}% + \TestAbs{2147483647}{2147483647}% + \TestAbs{-2147483647}{2147483647}% + \TestAbs{ 0 }{0}% + \TestAbs{ 1 }{1}% + \TestAbs{--1}{1}% + \TestAbs{\z@}{0}% + \TestAbs{\@ne}{1}% + \TestAbs{\m@ne}{1}% +%<*etex> + \TestAbs{-10+30}{20}% + \TestAbs{10-30}{20}% +%</etex> +\end{qstest} + +\begin{qstest}{sign}{sign}% + \TestSgn{0}{0}% + \TestSgn{1}{1}% + \TestSgn{-1}{-1}% + \TestSgn{10}{1}% + \TestSgn{-10}{-1}% + \TestSgn{2147483647}{1}% + \TestSgn{-2147483647}{-1}% + \TestSgn{ 0 }{0}% + \TestSgn{ 2 }{1}% + \TestSgn{ -2 }{-1}% + \TestSgn{--2}{1}% + \TestSgn{\z@}{0}% + \TestSgn{\@ne}{1}% + \TestSgn{\m@ne}{-1}% +%<*etex> + \TestSgn{-10+30}{1}% + \TestSgn{10-30}{-1}% +%</etex> +\end{qstest} + +\begin{qstest}{min}{min}% + \TestMin{0}{1}{0}% + \TestMin{1}{0}{0}% + \TestMin{-10}{-20}{-20}% + \TestMin{ 1 }{ 2 }{1}% + \TestMin{ 2 }{ 1 }{1}% + \TestMin{1}{1}{1}% + \TestMin{\z@}{\@ne}{0}% + \TestMin{\@ne}{\m@ne}{-1}% +%<*etex> + \TestMin{1+2}{3+4}{3}% +%</etex> +\end{qstest} + +\begin{qstest}{max}{max}% + \TestMax{0}{1}{1}% + \TestMax{1}{0}{1}% + \TestMax{-10}{-20}{-10}% + \TestMax{ 1 }{ 2 }{2}% + \TestMax{ 2 }{ 1 }{2}% + \TestMax{1}{1}{1}% + \TestMax{\z@}{\@ne}{1}% + \TestMax{\@ne}{\m@ne}{1}% +%<*etex> + \TestMax{1+2}{3+4}{7}% +%</etex> +\end{qstest} + +\begin{qstest}{cmp}{cmp}% + \TestCmp{0}{0}{0}% + \TestCmp{-21}{17}{-1}% + \TestCmp{3}{4}{-1}% + \TestCmp{-10}{-10}{0}% + \TestCmp{-10}{-11}{1}% + \TestCmp{100}{5}{1}% + \TestCmp{2147483647}{-2147483647}{1}% + \TestCmp{-2147483647}{2147483647}{-1}% + \TestCmp{2147483647}{2147483647}{0}% + \TestCmp{\z@}{\@ne}{-1}% + \TestCmp{\@ne}{\m@ne}{1}% + \TestCmp{ 4 }{ 5 }{-1}% + \TestCmp{ -3 }{ -7 }{1}% +%<*etex> + \TestCmp{1+2}{3+4}{-1}% +%</etex> +\end{qstest} + +\begin{qstest}{fac}{fac} + \TestFac{0}{1}% + \TestFac{1}{1}% + \TestFac{2}{2}% + \TestFac{3}{2*3}% + \TestFac{4}{2*3*4}% + \TestFac{5}{2*3*4*5}% + \TestFac{6}{2*3*4*5*6}% + \TestFac{7}{2*3*4*5*6*7}% + \TestFac{8}{2*3*4*5*6*7*8}% + \TestFac{9}{2*3*4*5*6*7*8*9}% + \TestFac{10}{2*3*4*5*6*7*8*9*10}% + \TestFac{11}{2*3*4*5*6*7*8*9*10*11}% + \TestFac{12}{2*3*4*5*6*7*8*9*10*11*12}% +\end{qstest} + +\begin{qstest}{inc}{inc}% + \TestInc{0}{1}% + \TestInc{1}{2}% + \TestInc{-1}{0}% + \TestInc{10}{11}% + \TestInc{-10}{-9}% + \TestInc{999}{1000}% + \TestInc{-1000}{-999}% + \TestInc{129}{130}% + \TestInc{2147483646}{2147483647}% + \TestInc{-2147483647}{-2147483646}% +\end{qstest} + +\begin{qstest}{dec}{dec}% + \TestDec{0}{-1}% + \TestDec{1}{0}% + \TestDec{-1}{-2}% + \TestDec{10}{9}% + \TestDec{-10}{-11}% + \TestDec{1000}{999}% + \TestDec{-999}{-1000}% + \TestDec{130}{129}% + \TestDec{2147483647}{2147483646}% + \TestDec{-2147483646}{-2147483647}% +\end{qstest} + +\begin{qstest}{add}{add}% + \TestAdd{0}{0}{0}% + \TestAdd{1}{0}{1}% + \TestAdd{0}{1}{1}% + \TestAdd{1}{2}{3}% + \TestAdd{-1}{-1}{-2}% + \TestAdd{2147483646}{1}{2147483647}% + \TestAdd{-2147483647}{2147483647}{0}% + \TestAdd{20}{-5}{15}% + \TestAdd{-4}{-1}{-5}% + \TestAdd{-1}{-4}{-5}% + \TestAdd{-4}{1}{-3}% + \TestAdd{-1}{4}{3}% + \TestAdd{4}{-1}{3}% + \TestAdd{1}{-4}{-3}% + \TestAdd{-4}{-1}{-5}% + \TestAdd{-1}{-4}{-5}% + \TestAdd{ -4 }{ -1 }{-5}% + \TestAdd{ -1 }{ -4 }{-5}% + \TestAdd{ -4 }{ 1 }{-3}% + \TestAdd{ -1 }{ 4 }{3}% + \TestAdd{ 4 }{ -1 }{3}% + \TestAdd{ 1 }{ -4 }{-3}% + \TestAdd{ -4 }{ -1 }{-5}% + \TestAdd{ -1 }{ -4 }{-5}% + \TestAdd{876543210}{111111111}{987654321}% + \TestAdd{999999999}{2}{1000000001}% +%<*etex> + \TestAdd{100}{50+150}{300}% + \TestAdd{2147483647}{10-2147483647}{10}% +%</etex> +\end{qstest} + +\begin{qstest}{sub}{sub} + \TestSub{0}{0}{0}% + \TestSub{1}{0}{1}% + \TestSub{1}{2}{-1}% + \TestSub{-1}{-1}{0}% + \TestSub{2147483646}{-1}{2147483647}% + \TestSub{-2147483647}{-2147483647}{0}% + \TestSub{-4}{-1}{-3}% + \TestSub{-1}{-4}{3}% + \TestSub{-4}{1}{-5}% + \TestSub{-1}{4}{-5}% + \TestSub{4}{-1}{5}% + \TestSub{1}{-4}{5}% + \TestSub{-4}{-1}{-3}% + \TestSub{-1}{-4}{3}% + \TestSub{ -4 }{ -1 }{-3}% + \TestSub{ -1 }{ -4 }{3}% + \TestSub{ -4 }{ 1 }{-5}% + \TestSub{ -1 }{ 4 }{-5}% + \TestSub{ 4 }{ -1 }{5}% + \TestSub{ 1 }{ -4 }{5}% + \TestSub{ -4 }{ -1 }{-3}% + \TestSub{ -1 }{ -4 }{3}% + \TestSub{1000000000}{2}{999999998}% + \TestSub{987654321}{111111111}{876543210}% +%<*etex> + \TestSub{100}{50+150}{-100}% + \TestSub{2147483647}{-10+2147483647}{10}% +%</etex> +\end{qstest} + +\begin{qstest}{shl}{shl} + \TestShl{0}{0}% + \TestShl{1}{2}% + \TestShl{5621}{11242}% + \TestShl{1073741823}{2147483646}% +\end{qstest} + +\begin{qstest}{shr}{shr} + \TestShr{0}{0}% + \TestShr{1}{0}% + \TestShr{2}{1}% + \TestShr{3}{1}% + \TestShr{4}{2}% + \TestShr{5}{2}% + \TestShr{6}{3}% + \TestShr{7}{3}% + \TestShr{8}{4}% + \TestShr{9}{4}% + \TestShr{10}{5}% + \TestShr{11}{5}% + \TestShr{12}{6}% + \TestShr{13}{6}% + \TestShr{14}{7}% + \TestShr{15}{7}% + \TestShr{16}{8}% + \TestShr{17}{8}% + \TestShr{18}{9}% + \TestShr{19}{9}% + \TestShr{20}{10}% + \TestShr{21}{10}% + \TestShr{22}{11}% + \TestShr{11241}{5620}% + \TestShr{73054202}{36527101}% + \TestShr{2147483646}{1073741823}% +\end{qstest} + +\begin{qstest}{mul}{mul} + \TestMul{0}{0}{0}% + \TestMul{1}{0}{0}% + \TestMul{0}{1}{0}% + \TestMul{1}{1}{1}% + \TestMul{3}{1}{3}% + \TestMul{1}{-3}{-3}% + \TestMul{-4}{-5}{20}% + \TestMul{3}{7}{21}% + \TestMul{7}{3}{21}% + \TestMul{3}{-7}{-21}% + \TestMul{7}{-3}{-21}% + \TestMul{-3}{7}{-21}% + \TestMul{-7}{3}{-21}% + \TestMul{-3}{-7}{21}% + \TestMul{-7}{-3}{21}% + \TestMul{12}{11}{132}% + \TestMul{999}{333}{332667}% + \TestMul{1000}{4321}{4321000}% + \TestMul{12345}{173955}{2147474475}% + \TestMul{1073741823}{2}{2147483646}% + \TestMul{2}{1073741823}{2147483646}% + \TestMul{-1073741823}{2}{-2147483646}% + \TestMul{2}{-1073741823}{-2147483646}% +%<*etex> + \TestMul{2+3}{5+7}{60}% + \TestMul{2147483647}{2147483647/2147483647}{2147483647}% +%</etex> +\end{qstest} + +\begin{qstest}{sqr}{sqr} + \TestSqr{0}{0}% + \TestSqr{1}{1}% + \TestSqr{2}{4}% + \TestSqr{3}{9}% + \TestSqr{4}{16}% + \TestSqr{9}{81}% + \TestSqr{10}{100}% + \TestSqr{46340}{2147395600}% + \TestSqr{-1}{1}% + \TestSqr{-2}{4}% + \TestSqr{-46340}{2147395600}% +\end{qstest} + +\begin{qstest}{pow}{pow} + \TestPow{-2}{0}{1}% + \TestPow{-1}{0}{1}% + \TestPow{0}{0}{1}% + \TestPow{1}{0}{1}% + \TestPow{2}{0}{1}% + \TestPow{3}{0}{1}% + \TestPow{-2}{1}{-2}% + \TestPow{-1}{1}{-1}% + \TestPow{1}{1}{1}% + \TestPow{2}{1}{2}% + \TestPow{3}{1}{3}% + \TestPow{-2}{2}{4}% + \TestPow{-1}{2}{1}% + \TestPow{0}{2}{0}% + \TestPow{1}{2}{1}% + \TestPow{2}{2}{4}% + \TestPow{3}{2}{9}% + \TestPow{0}{1}{0}% + \TestPow{1}{-2}{1}% + \TestPow{1}{-1}{1}% + \TestPow{-1}{-2}{1}% + \TestPow{-1}{-1}{-1}% + \TestPow{-1}{3}{-1}% + \TestPow{-1}{4}{1}% + \TestPow{-2}{-1}{0}% + \TestPow{-2}{-2}{0}% + \TestPow{2}{3}{8}% + \TestPow{2}{4}{16}% + \TestPow{2}{5}{32}% + \TestPow{2}{6}{64}% + \TestPow{2}{7}{128}% + \TestPow{2}{8}{256}% + \TestPow{2}{9}{512}% + \TestPow{2}{10}{1024}% + \TestPow{-2}{3}{-8}% + \TestPow{-2}{4}{16}% + \TestPow{-2}{5}{-32}% + \TestPow{-2}{6}{64}% + \TestPow{-2}{7}{-128}% + \TestPow{-2}{8}{256}% + \TestPow{-2}{9}{-512}% + \TestPow{-2}{10}{1024}% + \TestPow{3}{3}{27}% + \TestPow{3}{4}{81}% + \TestPow{3}{5}{243}% + \TestPow{-3}{3}{-27}% + \TestPow{-3}{4}{81}% + \TestPow{-3}{5}{-243}% + \TestPow{2}{30}{1073741824}% + \TestPow{-3}{19}{-1162261467}% + \TestPow{5}{13}{1220703125}% + \TestPow{-7}{11}{-1977326743}% +\end{qstest} + +\begin{qstest}{div}{div} + \TestDiv{1}{1}{1}% + \TestDiv{2}{1}{2}% + \TestDiv{-2}{1}{-2}% + \TestDiv{2}{-1}{-2}% + \TestDiv{-2}{-1}{2}% + \TestDiv{15}{2}{7}% + \TestDiv{-16}{2}{-8}% + \TestDiv{1}{2}{0}% + \TestDiv{1}{3}{0}% + \TestDiv{2}{3}{0}% + \TestDiv{-2}{3}{0}% + \TestDiv{2}{-3}{0}% + \TestDiv{-2}{-3}{0}% + \TestDiv{13}{3}{4}% + \TestDiv{-13}{-3}{4}% + \TestDiv{-13}{3}{-4}% + \TestDiv{-6}{5}{-1}% + \TestDiv{-5}{5}{-1}% + \TestDiv{-4}{5}{0}% + \TestDiv{-3}{5}{0}% + \TestDiv{-2}{5}{0}% + \TestDiv{-1}{5}{0}% + \TestDiv{0}{5}{0}% + \TestDiv{1}{5}{0}% + \TestDiv{2}{5}{0}% + \TestDiv{3}{5}{0}% + \TestDiv{4}{5}{0}% + \TestDiv{5}{5}{1}% + \TestDiv{6}{5}{1}% + \TestDiv{-5}{4}{-1}% + \TestDiv{-4}{4}{-1}% + \TestDiv{-3}{4}{0}% + \TestDiv{-2}{4}{0}% + \TestDiv{-1}{4}{0}% + \TestDiv{0}{4}{0}% + \TestDiv{1}{4}{0}% + \TestDiv{2}{4}{0}% + \TestDiv{3}{4}{0}% + \TestDiv{4}{4}{1}% + \TestDiv{5}{4}{1}% + \TestDiv{12345}{678}{18}% + \TestDiv{32372}{5952}{5}% + \TestDiv{284271294}{18162}{15651}% + \TestDiv{217652429}{12561}{17327}% + \TestDiv{462028434}{5439}{84947}% + \TestDiv{2147483647}{1000}{2147483}% + \TestDiv{2147483647}{-1000}{-2147483}% + \TestDiv{-2147483647}{1000}{-2147483}% + \TestDiv{-2147483647}{-1000}{2147483}% +\end{qstest} + +\begin{qstest}{mod}{mod} + \TestMod{-6}{5}{4}% + \TestMod{-5}{5}{0}% + \TestMod{-4}{5}{1}% + \TestMod{-3}{5}{2}% + \TestMod{-2}{5}{3}% + \TestMod{-1}{5}{4}% + \TestMod{0}{5}{0}% + \TestMod{1}{5}{1}% + \TestMod{2}{5}{2}% + \TestMod{3}{5}{3}% + \TestMod{4}{5}{4}% + \TestMod{5}{5}{0}% + \TestMod{6}{5}{1}% + \TestMod{-5}{4}{3}% + \TestMod{-4}{4}{0}% + \TestMod{-3}{4}{1}% + \TestMod{-2}{4}{2}% + \TestMod{-1}{4}{3}% + \TestMod{0}{4}{0}% + \TestMod{1}{4}{1}% + \TestMod{2}{4}{2}% + \TestMod{3}{4}{3}% + \TestMod{4}{4}{0}% + \TestMod{5}{4}{1}% + \TestMod{-6}{-5}{-1}% + \TestMod{-5}{-5}{0}% + \TestMod{-4}{-5}{-4}% + \TestMod{-3}{-5}{-3}% + \TestMod{-2}{-5}{-2}% + \TestMod{-1}{-5}{-1}% + \TestMod{0}{-5}{0}% + \TestMod{1}{-5}{-4}% + \TestMod{2}{-5}{-3}% + \TestMod{3}{-5}{-2}% + \TestMod{4}{-5}{-1}% + \TestMod{5}{-5}{0}% + \TestMod{6}{-5}{-4}% + \TestMod{-5}{-4}{-1}% + \TestMod{-4}{-4}{0}% + \TestMod{-3}{-4}{-3}% + \TestMod{-2}{-4}{-2}% + \TestMod{-1}{-4}{-1}% + \TestMod{0}{-4}{0}% + \TestMod{1}{-4}{-3}% + \TestMod{2}{-4}{-2}% + \TestMod{3}{-4}{-1}% + \TestMod{4}{-4}{0}% + \TestMod{5}{-4}{-3}% + \TestMod{2147483647}{1000}{647}% + \TestMod{2147483647}{-1000}{-353}% + \TestMod{-2147483647}{1000}{353}% + \TestMod{-2147483647}{-1000}{-647}% + \TestMod{ 0 }{ 4 }{0}% + \TestMod{ 1 }{ 4 }{1}% + \TestMod{ -1 }{ 4 }{3}% + \TestMod{ 0 }{ -4 }{0}% + \TestMod{ 1 }{ -4 }{-3}% + \TestMod{ -1 }{ -4 }{-1}% +%<*etex> + \TestMod{1+2}{1+3}{3}% + \TestMod{1-2}{1+3}{3}% + \TestMod{1-2}{1-4}{-1}% + \TestMod{1+2}{1-4}{0}% + \TestMod{1+2}{1-5}{-1}% +%</etex> +\end{qstest} +%</test2|test3|test4> + +%<*test2|test3> +\newcommand*{\TestError}[2]{% + \begingroup + \expandafter\def\csname IntCalcError:#1\endcsname{}% + \Expect*{#2}{0}% + \expandafter\def\csname IntCalcError:#1\endcsname{ERROR}% + \Expect*{#2}{0ERROR }% + \endgroup +} +\begin{qstest}{error}{error} + \TestError{FacNegative}{\intcalcFac{-1}}% + \TestError{FacNegative}{\intcalcFac{-2147483647}}% + \TestError{FacOverflow}{\intcalcFac{13}}% + \TestError{FacOverflow}{\intcalcFac{2147483647}}% + \TestError{ShlNegativeNumber}{\intcalcShl{-1}}% + \TestError{ShrNegativeNumber}{\intcalcShr{-1}}% + \TestError{DivisionByZero}{\intcalcPow{0}{-1}}% + \TestError{DivisionByZero}{\intcalcDiv{1}{0}}% + \TestError{DivisionByZero}{\intcalcMod{1}{0}}% +\end{qstest} +%</test2|test3> + +%<*test2|test3|test4> +\begin{document} +\end{document} +%</test2|test3|test4> +% \end{macrocode} +% +% \section{Installation} +% +% \subsection{Download} +% +% \paragraph{Package.} This package is available on +% CTAN\footnote{\url{ftp://ftp.ctan.org/tex-archive/}}: +% \begin{description} +% \item[\CTAN{macros/latex/contrib/oberdiek/intcalc.dtx}] The source file. +% \item[\CTAN{macros/latex/contrib/oberdiek/intcalc.pdf}] Documentation. +% \end{description} +% +% +% \paragraph{Bundle.} All the packages of the bundle `oberdiek' +% are also available in a TDS compliant ZIP archive. There +% the packages are already unpacked and the documentation files +% are generated. The files and directories obey the TDS standard. +% \begin{description} +% \item[\CTAN{macros/latex/contrib/oberdiek/oberdiek-tds.zip}] +% \end{description} +% \emph{TDS} refers to the standard ``A Directory Structure +% for \TeX\ Files'' (\CTAN{tds/tds.pdf}). Directories +% with \xfile{texmf} in their name are usually organized this way. +% +% \subsection{Bundle installation} +% +% \paragraph{Unpacking.} Unpack the \xfile{oberdiek-tds.zip} in the +% TDS tree (also known as \xfile{texmf} tree) of your choice. +% Example (linux): +% \begin{quote} +% |unzip oberdiek-tds.zip -d ~/texmf| +% \end{quote} +% +% \paragraph{Script installation.} +% Check the directory \xfile{TDS:scripts/oberdiek/} for +% scripts that need further installation steps. +% Package \xpackage{attachfile2} comes with the Perl script +% \xfile{pdfatfi.pl} that should be installed in such a way +% that it can be called as \texttt{pdfatfi}. +% Example (linux): +% \begin{quote} +% |chmod +x scripts/oberdiek/pdfatfi.pl|\\ +% |cp scripts/oberdiek/pdfatfi.pl /usr/local/bin/| +% \end{quote} +% +% \subsection{Package installation} +% +% \paragraph{Unpacking.} The \xfile{.dtx} file is a self-extracting +% \docstrip\ archive. The files are extracted by running the +% \xfile{.dtx} through \plainTeX: +% \begin{quote} +% \verb|tex intcalc.dtx| +% \end{quote} +% +% \paragraph{TDS.} Now the different files must be moved into +% the different directories in your installation TDS tree +% (also known as \xfile{texmf} tree): +% \begin{quote} +% \def\t{^^A +% \begin{tabular}{@{}>{\ttfamily}l@{ $\rightarrow$ }>{\ttfamily}l@{}} +% intcalc.sty & tex/generic/oberdiek/intcalc.sty\\ +% intcalc.pdf & doc/latex/oberdiek/intcalc.pdf\\ +% intcalc-test1.tex & doc/latex/oberdiek/intcalc-test1.tex\\ +% intcalc-test2.tex & doc/latex/oberdiek/intcalc-test2.tex\\ +% intcalc-test3.tex & doc/latex/oberdiek/intcalc-test3.tex\\ +% intcalc-test4.tex & doc/latex/oberdiek/intcalc-test4.tex\\ +% intcalc.dtx & source/latex/oberdiek/intcalc.dtx\\ +% \end{tabular}^^A +% }^^A +% \sbox0{\t}^^A +% \ifdim\wd0>\linewidth +% \begingroup +% \advance\linewidth by\leftmargin +% \advance\linewidth by\rightmargin +% \edef\x{\endgroup +% \def\noexpand\lw{\the\linewidth}^^A +% }\x +% \def\lwbox{^^A +% \leavevmode +% \hbox to \linewidth{^^A +% \kern-\leftmargin\relax +% \hss +% \usebox0 +% \hss +% \kern-\rightmargin\relax +% }^^A +% }^^A +% \ifdim\wd0>\lw +% \sbox0{\small\t}^^A +% \ifdim\wd0>\linewidth +% \ifdim\wd0>\lw +% \sbox0{\footnotesize\t}^^A +% \ifdim\wd0>\linewidth +% \ifdim\wd0>\lw +% \sbox0{\scriptsize\t}^^A +% \ifdim\wd0>\linewidth +% \ifdim\wd0>\lw +% \sbox0{\tiny\t}^^A +% \ifdim\wd0>\linewidth +% \lwbox +% \else +% \usebox0 +% \fi +% \else +% \lwbox +% \fi +% \else +% \usebox0 +% \fi +% \else +% \lwbox +% \fi +% \else +% \usebox0 +% \fi +% \else +% \lwbox +% \fi +% \else +% \usebox0 +% \fi +% \else +% \lwbox +% \fi +% \else +% \usebox0 +% \fi +% \end{quote} +% If you have a \xfile{docstrip.cfg} that configures and enables \docstrip's +% TDS installing feature, then some files can already be in the right +% place, see the documentation of \docstrip. +% +% \subsection{Refresh file name databases} +% +% If your \TeX~distribution +% (\teTeX, \mikTeX, \dots) relies on file name databases, you must refresh +% these. For example, \teTeX\ users run \verb|texhash| or +% \verb|mktexlsr|. +% +% \subsection{Some details for the interested} +% +% \paragraph{Attached source.} +% +% The PDF documentation on CTAN also includes the +% \xfile{.dtx} source file. It can be extracted by +% AcrobatReader 6 or higher. Another option is \textsf{pdftk}, +% e.g. unpack the file into the current directory: +% \begin{quote} +% \verb|pdftk intcalc.pdf unpack_files output .| +% \end{quote} +% +% \paragraph{Unpacking with \LaTeX.} +% The \xfile{.dtx} chooses its action depending on the format: +% \begin{description} +% \item[\plainTeX:] Run \docstrip\ and extract the files. +% \item[\LaTeX:] Generate the documentation. +% \end{description} +% If you insist on using \LaTeX\ for \docstrip\ (really, +% \docstrip\ does not need \LaTeX), then inform the autodetect routine +% about your intention: +% \begin{quote} +% \verb|latex \let\install=y\input{intcalc.dtx}| +% \end{quote} +% Do not forget to quote the argument according to the demands +% of your shell. +% +% \paragraph{Generating the documentation.} +% You can use both the \xfile{.dtx} or the \xfile{.drv} to generate +% the documentation. The process can be configured by the +% configuration file \xfile{ltxdoc.cfg}. For instance, put this +% line into this file, if you want to have A4 as paper format: +% \begin{quote} +% \verb|\PassOptionsToClass{a4paper}{article}| +% \end{quote} +% An example follows how to generate the +% documentation with pdf\LaTeX: +% \begin{quote} +%\begin{verbatim} +%pdflatex intcalc.dtx +%makeindex -s gind.ist intcalc.idx +%pdflatex intcalc.dtx +%makeindex -s gind.ist intcalc.idx +%pdflatex intcalc.dtx +%\end{verbatim} +% \end{quote} +% +% \begin{History} +% \begin{Version}{2007/09/09 v1.0} +% \item +% First version. +% \end{Version} +% \end{History} +% +% \PrintIndex +% +% \Finale +\endinput |