summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/apnum
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2014-11-24 23:02:52 +0000
committerKarl Berry <karl@freefriends.org>2014-11-24 23:02:52 +0000
commit8d5e4e32a3903044e0fdaf0a085ae6d2a5124937 (patch)
tree4fbc3d98d743d6d4fb0b4ebda55668a53c24824e /Master/texmf-dist/tex/generic/apnum
parent95ab5f818c4a00ba3efeef3070973446324b38d6 (diff)
apnum (24nov14)
git-svn-id: svn://tug.org/texlive/trunk@35655 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/generic/apnum')
-rw-r--r--Master/texmf-dist/tex/generic/apnum/apnum.tex730
1 files changed, 730 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/generic/apnum/apnum.tex b/Master/texmf-dist/tex/generic/apnum/apnum.tex
new file mode 100644
index 00000000000..cb891d55bcc
--- /dev/null
+++ b/Master/texmf-dist/tex/generic/apnum/apnum.tex
@@ -0,0 +1,730 @@
+% Arbitrary precision numbers
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% 2014 Petr Olsak
+
+% See the documentation apnum.pdf or apnum.d for more information
+
+\def\apnumversion{1.0 <Nov. 2014>}
+\message{The Arbitrary Precision Numbers, \apnumversion}
+
+%%%%%%%%%%%% Internal registers:
+
+\newcount\apnumA \newcount\apnumB \newcount\apnumC \newcount\apnumD
+\newcount\apnumE \newcount\apnumF \newcount\apnumG \newcount\apnumH
+\newcount\apnumO \newcount\apnumL
+\newcount\apnumX \newcount\apnumY \newcount\apnumZ
+\newcount\apSIGNa \newcount\apSIGNb \newcount\apEa \newcount\apEb
+\newif\ifapX
+
+\apnumZ=\catcode`\@ \catcode`\@=12
+
+%%%%%%%%%%%% Public macros, sec. 2.1 in apnum.pdf
+
+\def\evaldef{\relax \apEVALa}
+\def\PLUS{\relax \apPPab\apPLUSa}
+\def\MINUS#1#2{\relax \apPPab\apPLUSa{#1}{-#2}}
+\def\MUL{\relax \apPPab\apMULa}
+\def\DIV{\relax \apPPab\apDIVa}
+\def\POW{\relax \apPPab\apPOWa}
+\def\ABS{\relax \apEVALone\apABSa}
+\def\iDIV{\relax \apEVALtwo\apiDIVa}
+\def\iMOD{\relax \apEVALtwo\apiMODa}
+\def\iROUND#1{\relax \evaldef\OUT{#1}\apiROUNDa}
+\def\iFRAC{\relax \apEVALone\apiFRACa}
+\def\FAC{\relax \apEVALone\apFACa}
+\def\ROUND{\apPPs\apROUNDa}
+\def\ROLL{\apPPs\apROLLa}
+\def\NORM{\apPPs\apNORMa}
+\def\addE#1{\edef#1{#1\ifnum\apE=0 \else E\ifnum\apE>0+\fi\the\apE\fi}}
+
+\newcount\apSIGN \let\SIGN=\apSIGN
+\newcount\apE
+\newcount\apTOT \apTOT=-30
+\newcount\apFRAC \apFRAC=20
+
+%%%%%%%%%%%% Evaluation of the expression, sec. 2.2 in apnum.pdf
+
+\def\apEVALa#1#2{{\apnumA=0 \apnumE=1 \apEVALb#2\end\expandafter}\tmpb \let#1=\OUT}
+\def\apEVALb{\def\tmpa{}\apEVALc}
+\def\apEVALc#1{%
+ \ifx+#1\apEVALd \apEVALc \fi
+ \ifx-#1\edef\tmpa{\tmpa-}\apEVALd\apEVALc \fi
+ \ifx(#1\apEVALd \apEVALe \fi
+ \ifx\the#1\apEVALd \apEVALf\the\fi
+ \ifx\number#1\apEVALd \apEVALf\number\fi
+ \apTESTdigit#1\iftrue
+ \ifx E#1\let\tmpb=\tmpa \expandafter\apEVALd\expandafter\apEVALk
+ \else \edef\tmpb{\tmpa#1}\expandafter\apEVALd\expandafter\apEVALn\fi\fi
+ \edef\tmpb{\tmpa\noexpand#1}\futurelet\next\apEVALg
+}
+\def\apEVALd#1\fi#2\next\apEVALg{\fi#1}
+\def\apEVALe{%
+ \ifx\tmpa\empty \else \ifnum\tmpa1<0 \def\tmpb{-1}\apEVALp \MUL 4\fi\fi
+ \advance\apnumA by4
+ \apEVALb
+}
+\def\apEVALf#1#2{\expandafter\def\expandafter\tmpb\expandafter{\tmpa#1#2}\apEVALo}
+\def\apEVALg{\ifx\next \bgroup \expandafter\apEVALh \else \expandafter\apEVALo \fi}
+\def\apEVALh#1{\expandafter\def\expandafter\tmpb\expandafter{\tmpb{#1}}\futurelet\next\apEVALg}
+\def\apEVALk{\afterassignment\apEVALm\apE=}
+\def\apEVALm{\edef\tmpb{\tmpb E\the\apE}\apEVALo}
+\def\apEVALn#1{\apTESTdigit#1%
+ \iftrue \ifx E#1\afterassignment\apEVALm\expandafter\expandafter\expandafter\apE
+ \else\edef\tmpb{\tmpb#1}\expandafter\expandafter\expandafter\apEVALn\fi
+ \else \expandafter\apEVALo\expandafter#1\fi
+}
+\def\apEVALo#1{\let\next=\apEVALb
+ \ifx+#1\apEVALp \apEPLUS 1\fi
+ \ifx-#1\apEVALp \apEMINUS 1\fi
+ \ifx*#1\apEVALp \apEMUL 2\fi
+ \ifx/#1\apEVALp \apEDIV 2\fi
+ \ifx^#1\apEVALp \apEPOW 3\fi
+ \ifx)#1\advance\apnumA by-4 \let\next=\apEVALo \let\tmpa=\relax
+ \ifnum\apnumA<0 \apEVALerror{many brackets ")"}\fi
+ \fi
+ \ifx\end#1%
+ \ifnum\apnumA>0 \apEVALerror{missing bracket ")"}%
+ \else \apEVALp\END 0\fi
+ \let\next=\relax
+ \fi
+ \ifx\tmpa\relax \else \apEVALerror{unknown operator "\string#1"}\fi
+ \apnumE=0 \next
+}
+\def\apEVALp#1#2{%
+ \apnumB=#2 \advance\apnumB by\apnumA
+ \toks0=\expandafter{\expandafter{\tmpb}{#1}}%
+ \expandafter\apEVALpush\the\toks0\expandafter{\the\apnumB}% {value}{op}{priority}
+ \let\tmpa=\relax
+}
+\let\apEPLUS=\PLUS \let\apEMINUS=\MINUS \let\apEMUL=\MUL \let\apEDIV=\DIV \let\apEPOW=\POW
+\def\apEVALstack{{}{}{0}.}
+\def\apEVALpush#1#2#3{% value, operator, priority
+ \toks0={{#1}{#2}{#3}}%
+ \expandafter\def\expandafter\apEVALstack\expandafter{\the\toks0\apEVALstack}%
+ \expandafter\apEVALdo\apEVALstack@%
+}
+\def\apEVALdo#1#2#3#4#5#6#7@{%
+ \apnumB=#3 \ifx#2\POW \advance\apnumB by1 \fi
+ \ifnum\apnumB>#6\else
+ \ifnum#6=0 \def\tmpb{#1}%\toks0={#1}\message{RESULT: \the\toks0}
+ \ifnum\apnumE=1 \def\tmpb{\apPPn{#1}}\fi
+ \else \def\apEVALstack{#7}\apEVALpush{#5{#4}{#1}}{#2}{#3}%
+ \fi\fi
+}
+\def\apEVALerror#1{\message{\noexpand\evaldef ERROR: #1.}%
+ \def\tmpb{\def\OUT{??}}\def\next##1\end{}%
+}
+\def\apTESTdigit#1#2{%
+ \ifx E#1\apXtrue \else
+ \ifcat.\noexpand#1%
+ \ifx.#1\apXtrue \else
+ \ifnum`#1<`0 \apXfalse\else
+ \ifnum`#1>`9 \apXfalse\else \apXtrue\fi
+ \fi\fi
+ \else \apXfalse
+ \fi\fi
+ \ifapX
+}
+
+%%%%%%%%%%%% Preparation of the parameter, sec. 2.3 in apnum.pdf
+
+\def\apPPa#1#2{\expandafter\apPPb#2@#1}
+\def\apPPb{\def\tmpc{}\apSIGN=1 \apE=0 \apXfalse \expandafter\expandafter\expandafter\apPPc}
+\def\apPPc#1{%
+ \ifx+#1\apPPd \fi
+ \ifx-#1\apSIGN=-\apSIGN \apPPd \fi
+ \ifx\relax#1\apPPe \fi
+ \apPPg#1%
+}
+\def\apPPd#1\apPPg#2{\fi\expandafter\expandafter\expandafter\apPPc}
+\def\apPPe#1\apPPg#2#3@{\fi\apXtrue{#3% execution of the parameter in the group
+ \edef\tmpc{\apE=\the\apE\relax\noexpand\apPPf\OUT@}\expandafter}\tmpc
+}
+\def\apPPf#1{\ifx-#1\apSIGN=-\apSIGN \expandafter\apPPg\else\expandafter\apPPg\expandafter#1\fi}
+\def\apPPg#1{%
+ \ifx.#1\def\tmpc{.}\apPPh\fi
+ \ifx\tmpc\empty\else\edef\tmpc{\tmpc#1}\fi
+ \ifx0#1\apPPh\fi
+ \ifx\tmpc\empty\edef\tmpc{#1}\fi
+ \ifx@#1\def\tmpc{@}\fi
+ \expandafter\apPPi\tmpc
+}
+\def\apPPh#1\apPPi\tmpc{\fi\apPPg}
+\def\apPPi{\ifapX \expandafter\apPPj \else \expandafter\apPPk \fi}
+\def\apPPj#1@#2{\def#2{#1}}
+\def\apPPk#1@#2{\ifx@#1@\apSIGN=0 \def#2{0}\else \apPPl#1E@#2\fi}
+\def\apPPl#1E#2@#3{%
+ \ifx@#1@\def#3{1}\else\def#3{#1}\fi
+ \ifx@#2@\else \afterassignment\apPPm \apE=#2\fi
+}
+\def\apPPm E{}
+\def\apPPn#1{\expandafter\apPPb#1@\OUT \edef\OUT{\ifnum\apSIGN<0-\fi\OUT}}
+\def\apPPab#1#2#3{%
+ \expandafter\apPPb#2@\tmpa \apSIGNa=\apSIGN \apEa=\apE
+ \expandafter\apPPb#3@\tmpb \apSIGNb=\apSIGN \apEb=\apE
+ #1%
+}
+\def\apPPs#1#2#3{\def\tmpc{#3}\expandafter\apPPt\expandafter#1#2.@#2}
+\def\apPPt#1#2{%
+ \ifx-#2\apnumG=-1 \def\next{#1}%
+ \else \ifx0#2\apnumG=0 \def\next{\apPPu#1}\else \apnumG=1 \def\next{#1#2}\fi\fi
+ \next
+}
+\def\apPPu#1#2.@#3{\ifx@#2@\apnumG=0 \ifx#1\apROUNDa\def\XOUT{}\fi
+ \else\def\next{\apPPt#1#2.@#3}\expandafter\next\fi
+}
+\def\apEVALone#1#2{\evaldef\OUT{#2}\ifnum\apSIGN<0 \expandafter\apNOminus\OUT@\OUT\fi #1}
+\def\apEVALtwo#1#2#3{%
+ {\evaldef\OUT{#2}\apOUTtmpb}\tmpb \let\tmpa=\OUT \apSIGNa=\apSIGN \apEa=\apE
+ \ifnum\apSIGNa<0 \expandafter\apNOminus\tmpa@\tmpa\fi
+ {\evaldef\OUT{#3}\apOUTtmpb}\tmpb \let\tmpb=\OUT \apSIGNb=\apSIGN \apEb=\apE
+ \ifnum\apSIGNb<0 \expandafter\apNOminus\tmpb@\tmpb\fi
+ #1%
+}
+\def\apNOminus-#1@#2{\def#2{#1}}
+
+%%%%%%%%%%%% Addition and Subtraction, sec. 2.4 in apnum.pdf
+
+\def\apPLUSa{%
+ \ifnum\apEa=\apEb \apE=\apEa \else \apPLUSxE \fi
+ \apDIG\tmpa\relax \apnumA=\apnumD % digits before decimal point
+ \apDIG\tmpb\relax \apnumB=\apnumD
+ \apIVmod \apnumA \apnumE \advance\apnumA by-\apnumE % digits in the first Digit
+ \apIVmod \apnumB \apnumF \advance\apnumB by-\apnumF
+ \apnumC=\apnumB \advance\apnumC by-\apnumA % difference between Digits
+ \ifnum\apSIGNa<0 \def\apPLUSxA{-}\else \def\apPLUSxA{}\fi
+ \ifnum\apSIGNb<0 \def\apPLUSxB{-}\else \def\apPLUSxB{}\fi
+ \apSIGN=0 % \apSIGN=0 means that we are doing subtraction
+ \ifx\apPLUSxA\empty \ifx\apPLUSxB\empty \apSIGN=1 \fi\fi
+ \if\apPLUSxA-\relax \if\apPLUSxB-\relax \apSIGN=-1 \def\apPLUSxA{}\def\apPLUSxB{}\fi\fi
+ \ifnum\apnumC>0 \apPLUSg \apPLUSb \tmpb\apnumF \tmpa\apnumE \apnumB % first pass
+ \else \apnumC=-\apnumC \apPLUSb \tmpa\apnumE \tmpb\apnumF \apnumA
+ \fi
+ \ifnum\apnumG=0 \def\OUT{0}\apSIGN=0 \apE=0 \else
+ \ifnum\apSIGN=0 \apSIGN=\apnumG \let\next=\apPLUSm \else \let\next=\apPLUSp \fi
+ \apnumX=0 \edef\OUT{\expandafter}\expandafter \next \OUT@% second pass
+ \ifnum\apnumD<1 % result in the form .000123
+ \apnumZ=-\apnumD
+ \def\tmpa{.}%
+ \ifnum\apnumZ>0 \apADDzeros\tmpa \fi % adding dot and left zeros
+ \edef\OUT{\ifnum\apSIGN<0-\fi\tmpa\OUT}%
+ \else
+ \edef\OUT{\expandafter}\expandafter\apPLUSy \OUT@% removing left zeros
+ \fi\fi
+}
+\def\apPLUSb#1#2#3#4#5{%
+ \edef\tmpd{\ifcase#4\or{}{}{}\or{}{}\or{}\fi#3}%
+ \edef\tmpc{\ifcase#2\or{}{}{}\or{}{}\or{}\fi}%
+ \let\next=\apPLUSc \apnumD=#5\advance\apnumD by4 \apnumG=0 \apnumZ=0 \def\OUT{}%
+ \expandafter\expandafter\expandafter\apPLUSc\expandafter\tmpc#1\apNL\apNL\apNL\apNL@%
+}
+\def\apPLUSc#1#2#3#4{\apnumY=\apPLUSxA#1#2#3#4\relax
+ \ifx\apNL#4\let\next=\apPLUSd\fi
+ \ifx\apNL#1\relax \ifx\tmpd\empty \expandafter\expandafter\expandafter\apPLUSf \fi\fi
+ \apPLUSe
+}
+\def\apPLUSd{\apnumY=0 \ifx\tmpd\empty \expandafter\apPLUSf \else\expandafter \apPLUSe\fi}
+\def\apPLUSe{%
+ \ifnum\apnumC>0 \advance\apnumC by-4
+ \else \apIVread\tmpd \advance\apnumY by\apPLUSxB\apnumX \fi
+ \ifnum\apnumZ=0 \apPLUSh \fi
+ \edef\OUT{{\the\apnumY}\OUT}%
+ \advance\apnumD by-4
+ \next
+}
+\def\apPLUSf#1@{}
+\def\apPLUSg{\let\tmpc=\apPLUSxA \let\apPLUSxA=\apPLUSxB \let\apPLUSxB=\tmpc}
+\def\apPLUSh{\apnumZ=\apnumY
+ \ifnum\apnumY=0 \else \ifnum\apnumY<0 \apnumG=-1 \apnumY=-\apnumY \apPLUSg \else\apnumG=1 \fi\fi
+}
+\def\apPLUSm#1{%
+ \ifx@#1\else
+ \apnumA=#1 \advance\apnumA by-\apnumX
+ \ifnum\apnumA<0 \advance\apnumA by\apIVbase \apnumX=1 \else \apnumX=0 \fi
+ \apPLUSw
+ \expandafter\apPLUSm
+ \fi
+}
+\def\apPLUSp#1{%
+ \ifx@#1\ifnum\apnumX>0 \edef\OUT{1\OUT}\fi
+ \else
+ \apnumA=\apnumX \advance\apnumA by#1
+ \ifnum\apnumA<\apIVbase \apnumX=0 \else \apnumX=1 \advance\apnumA by-\apIVbase \fi
+ \apPLUSw
+ \expandafter\apPLUSp
+ \fi
+}
+\def\apPLUSw{%
+ \ifnum\apnumD=0 \ifx\OUT\empty \def\OUT{\empty}\else \edef\OUT{.\OUT}\fi \fi
+ \advance\apnumD by4
+ \ifx\OUT\empty \edef\tmpa{\apIVwrite\apnumA}\edef\OUT{\apREMzerosR\tmpa}%
+ \else \edef\OUT{\apIVwrite\apnumA\OUT}\fi
+}
+\def\apPLUSy#1{\ifx0#1\expandafter\apPLUSy\else \expandafter\apPLUSz\expandafter#1\fi}
+\def\apPLUSz#1@{\edef\OUT{\ifnum\apSIGN<0-\fi#1}}
+\def\apPLUSxE{%
+ \apnumE=\apEa \advance\apnumE by-\apEb
+ \ifnum\apEa>\apEb \apPPs\apROLLa\tmpb{-\apnumE}\apE=\apEa
+ \else \apPPs\apROLLa\tmpa{\apnumE}\apE=\apEb \fi
+}
+
+%%%%%%%%%%%% Multiplication, sec. 2.5 in apnum.pdf
+
+\def\apMULa{%
+ \apE=\apEa \advance\apE by\apEb
+ \apSIGN=\apSIGNa \multiply\apSIGN by\apSIGNb
+ \ifnum\apSIGN=0 \def\OUT{0}\apE=0 \else
+ \apDIG\tmpa\apnumA \apnumX=\apnumA \advance\apnumA by\apnumD
+ \apDIG\tmpb\apnumB \advance\apnumX by\apnumB \advance\apnumB by\apnumD
+ \apnumD=\apnumX % \apnumD = the number of digits after decimal point in the result
+ \apIVmod \apnumA \apnumF % \apnumF = digits in the first Digit of \tmpa
+ \edef\tmpc{\ifcase\apnumF\or{}{}{}\or{}{}\or{}\fi}\def\OUT{}%
+ \expandafter\expandafter\expandafter \apMULb \expandafter \tmpc \tmpa @@@@%
+ \edef\OUT{*.\OUT}%
+ \apIVmod \apnumB \apnumF % \apnumF = digits in the first Digit of \tmpb
+ \edef\tmpc{\ifcase\apnumF\or{}{}{}\or{}{}\or{}\fi}\def\tmpa{}%
+ \expandafter\expandafter\expandafter \apMULc \expandafter \tmpc \tmpb @@@@%
+ \expandafter\apMULd \tmpa@%
+ \expandafter\apMULg \OUT
+ \edef\tmpa{\ifnum\apSIGN<0-\fi}%
+ \ifnum\apnumD>0 \apnumZ=\apnumD \edef\tmpa{\tmpa.}\apADDzeros\tmpa \fi
+ \ifx\tmpa\empty \else \edef\OUT{\tmpa\OUT}\fi
+ \fi
+}
+\def\apMULb#1#2#3#4{\ifx@#4\else
+ \ifx\OUT\empty \edef\OUT{{#1#2#3#4}*}\else\edef\OUT{{#1#2#3#4}0\OUT}\fi
+ \expandafter\apMULb\fi
+}
+\def\apMULc#1#2#3#4{\ifx@#4\else \edef\tmpa{{#1#2#3#4}\tmpa}\expandafter\apMULc\fi}
+\def\apMULd#1{\ifx@#1\else
+ \apnumA=#1 \expandafter\apMULe \OUT
+ \expandafter\apMULd
+ \fi
+}
+\def\apMULe#1*#2{\apnumX=0 \def\OUT{#1{#2}*}\def\apOUTl{}\apnumO=1 \apnumL=0 \apMULf}
+\def\apMULf#1#2{%
+ \advance\apnumO by-1 \ifnum\apnumO=0 \apOUTx \fi
+ \apnumB=#1 \multiply\apnumB by\apnumA \advance\apnumB by\apnumX
+ \ifx*#2%
+ \ifnum\apnumB<\apIVbase
+ \edef\OUT{\OUT\expandafter\apOUTs\apOUTl.,\ifnum\the\apnumB#1=0 \else{\the\apnumB}{#1}\fi*}%
+ \else \apIVtrans
+ \expandafter \edef\csname apOUT:\apOUTn\endcsname
+ {\csname apOUT:\apOUTn\endcsname{\the\apnumB}{#1}}%
+ \apMULf0*\fi
+ \else \advance\apnumB by#2
+ \ifnum\apnumB<\apIVbase \apnumX=0 \else \apIVtrans \fi
+ \expandafter
+ \edef\csname apOUT:\apOUTn\endcsname{\csname apOUT:\apOUTn\endcsname{\the\apnumB}{#1}}%
+ \expandafter\apMULf \fi
+}
+\def\apMULg#1{\def\OUT{}\apMULh}
+\def\apMULh#1{\ifx*#1\expandafter\apMULi
+ \else \apnumA=#1 \apMULo4{\apIVwrite\apnumA}%
+ \expandafter\apMULh
+ \fi
+}
+\def\apMULi#1#2#3{\apnumA=#1
+ \ifx*#3\apMULo{\apNUMdigits\tmpa}{\the\apnumA}\expandafter\apMULj
+ \else \apMULo4{\apIVwrite\apnumA}\expandafter\apMULi
+ \fi{#3}%
+}
+\def\apMULj#1{}
+\def\apMULo#1#2{\edef\tmpa{#2}%
+ \advance\apnumD by-#1
+ \ifnum\apnumD<1 \ifnum\apnumD>-4 \apMULt\fi\fi
+ \edef\OUT{\tmpa\OUT}%
+}
+\def\apMULt{\edef\tmpa{\apIVdot{-\apnumD}\tmpa}\edef\tmpa{\tmpa}}
+
+%%%%%%%%%%%% Division, sec. 2.6 in apnum.pdf
+
+\def\apDIVa{%
+ \ifnum\apSIGNb=0 \errmessage{Dividing by zero}\else
+ \apSIGN=\apSIGNa \multiply\apSIGN by\apSIGNb
+ \ifnum\apSIGNa=0 \def\OUT{0}\def\XOUT{0}\apE=0 \apSIGN=0 \else
+ \apE=\apEa \advance\apE by-\apEb
+ \apDIG\tmpb\relax \apnumB=\apnumD
+ \apDIG\tmpa\relax \apnumH=\apnumD
+ \advance\apnumD by-\apnumB % \apnumD = num. of digits before decimal point in the result
+ \apDIVcomp\tmpa\tmpb % apXtrue <=> A>=B, i.e 1 digit from A/B
+ \ifapX \advance\apnumD by1 \advance\apnumH by1 \fi
+ \apnumC=\apTOT
+ \ifnum\apTOT<0 \apnumC=-\apnumC
+ \ifnum\apnumD>\apnumC \apnumC=\apnumD \fi
+ \fi
+ \ifnum\apTOT=0 \apnumC=\apFRAC \advance\apnumC by\apnumD
+ \else \apnumX=\apFRAC \advance\apnumX by\apnumD
+ \ifnum\apnumC>\apnumX \apnumC=\apnumX \fi
+ \fi
+ \ifnum\apnumC>0 % \apnumC = the number of digits in the result
+ \advance\apnumH by-\apnumC % \apnumH = the position of decimal point in the remainder
+ \apIVmod \apnumC \apnumF % \apnumF = the number of digits in the first Digit
+ \apIVread\tmpb \apnumB=\apnumX % \apnumB = partial divisor
+ \apnumX=\apnumF \ifapX \advance\apnumX by-1 \fi
+ \apIVreadX\apnumX\tmpa
+ \apnumA=\apnumX % \apnumA = first Digit of the partial dividend
+ \apIVread\tmpa % \apnumX = second Digit of the partial dividend
+ \edef\apDIVxA{\the\apnumA\apIVwrite\apnumX}% first partial dividend
+ \edef\apDIVxB{\the\apnumB}% partial divisor
+ \edef\XOUT{{\apDIVxB}{\the\apnumX}@{\the\apnumA}}% the \XOUT is initialized
+ \edef\OUT{\ifnum\apSIGN<0-\fi}%
+ \ifnum\apnumD<0 \edef\OUT{\OUT.}\apnumZ=-\apnumD \apADDzeros\OUT \fi
+ \apnumE=1 \apnumZ=0
+ \let\next=\apDIVg \next % <--- the main calculation loop is here
+ \ifnum\apnumD>0 \apnumZ=\apnumD \apADDzeros\OUT \fi
+ \ifnum\apnumE=0 \def\XOUT{0}\else % extracting remainder from \XOUT
+ \edef\XOUT{\expandafter}\expandafter\apDIVv\XOUT
+ \def\tmpc{\apnumH}\apnumG=\apSIGNa \expandafter\apROLLa\XOUT.@\XOUT
+ \fi
+ \else \def\OUT{0}\def\XOUT{0}\apE=0 \apSIGN=0
+ \fi\fi\fi
+}
+\def\apDIVcomp#1#2{%
+ \expandafter\def\expandafter\tmpc\expandafter{#1\apNL\apNL\apNL\apNL\apNL\apNL\apNL\apNL@}%
+ \expandafter\def\expandafter\tmpd\expandafter{#2\apNL\apNL\apNL\apNL\apNL\apNL\apNL\apNL@}%
+ \def\next{\expandafter\expandafter\expandafter\apDIVcompA\expandafter\tmpc\tmpd}%
+ \apXtrue \next
+}
+\def\apDIVcompA#1#2#3#4#5#6#7#8#9@{%
+ \ifx#8\apNL \def\tmpc{0000000\apNL@}\else\def\tmpc{#9@}\fi
+ \apnumX=#1#2#3#4#5#6#7#8\relax
+ \apDIVcompB
+}
+\def\apDIVcompB#1#2#3#4#5#6#7#8#9@{%
+ \ifnum\apnumX<#1#2#3#4#5#6#7#8 \let\next=\relax \apXfalse \else
+ \ifnum\apnumX>#1#2#3#4#5#6#7#8 \let\next=\relax \apXtrue
+ \fi\fi
+ \ifx\next\relax\else
+ \ifx#8\apNL \def\tmpd{0000000\apNL@}\ifx\tmpc\tmpd\let\next=\relax\fi \else\def\tmpd{#9@}\fi
+ \fi
+ \next
+}
+\def\apDIVg{%
+ \ifx\tmpb\empty
+ \ifx\tmpa\empty \def\next{\apDIVi!}\let\nexti=\apDIVi
+ \else \def\next{\expandafter\apDIVh\tmpa\apNL\apNL\apNL\apNL!}\let\nexti=\apDIVh
+ \fi\fi
+ \ifx\next\apDIVg
+ \apIVread\tmpa \apnumA=\apnumX
+ \apIVread\tmpb
+ \edef\XOUT{{\the\apnumX}{\the\apnumA}\XOUT}%
+ \fi
+ \next
+}
+\def\apDIVh#1#2#3#4{\apnumZ=#1#2#3#4
+ \ifx\apNL#4\let\nexti=\apDIVi\fi
+ \apDIVi
+}
+\def\apDIVi{%
+ \ifnum\apnumE=0 \apnumC=0 \fi
+ \ifnum\apnumC>0
+ \expandafter\apDIVp\XOUT
+ \advance\apnumC by-4
+ \apnumZ=0
+ \expandafter\nexti
+ \else
+ \expandafter\apDIVj
+ \fi
+}
+\def\apDIVj#1!{}
+\def\apDIVp{%
+ \apnumA=\apDIVxA \divide\apnumA by\apDIVxB
+ \def\apOUTl{}\apnumO=1 \apnumL=0
+ \apnumX=0 \apnumB=0 \apnumE=0
+ \let\next=\apDIVq \next 0\apnumZ
+}
+\def\apDIVq#1#2#3{% B A B
+ \advance\apnumO by-1 \ifnum\apnumO=0 \apOUTx \fi
+ \apnumY=\apnumB
+ \apnumB=#1\multiply\apnumB by-\apnumA
+ \advance\apnumB by#2\advance\apnumB by-\apnumX
+ \ifnum\apnumB<0 \apnumX=\apnumB \advance\apnumX by1
+ \divide\apnumX by-\apIVbase \advance\apnumX by1
+ \advance\apnumB by\the\apnumX 0000
+ \else \apnumX=0 \fi
+ \expandafter
+ \edef\csname apOUT:\apOUTn\endcsname{\csname apOUT:\apOUTn\endcsname{#3}{\the\apnumB}}%
+ \ifnum\apnumE<\apnumB \apnumE=\apnumB \fi
+ \ifx@#3\let\next=\apDIVr \fi
+ \next{#3}%
+}
+\def\apDIVr#1#2{%
+ \ifnum\apnumX=#2 % the calculated Digit is OK, we save it
+ \edef\XOUT{\expandafter\apOUTs\apOUTl.,}%
+ \edef\tmpa{\ifnum\apnumF=4 \expandafter\apIVwrite\else \expandafter\the\fi\apnumA}%
+ \ifnum\apnumD<\apnumF \ifnum\apnumD>-1 \apDIVt \fi\fi %adding dot
+ \ifx\nexti\apDIVh \apnumE=1 \fi
+ \ifnum\apnumE=0 \apDIVu % removing zeros
+ \advance\apnumD by-\apNUMdigits\tmpa \relax
+ \else \advance\apnumD by-\apnumF \apnumF=4 \fi
+ \edef\OUT{\OUT\tmpa}% save the Digit
+ \edef\apDIVxA{\the\apnumB\apIVwrite\apnumY}% next partial dvividend
+ \else % we need do correction and run the remainder calculation again
+ \advance\apnumA by-1 \apnumX=0 \apnumB=0 \apnumE=0
+ \def\apOUTl{}\apnumO=1 \apnumL=0
+ \def\next{\let\next=\apDIVq
+ \expandafter\next\expandafter0\expandafter\apnumZ\XOUT}%
+ \expandafter\next
+ \fi
+}
+\def\apDIVt{\edef\tmpa{\apIVdot\apnumD\tmpa}\edef\tmpa{\tmpa}}
+\def\apDIVu{\edef\tmpa{\apREMzerosR\tmpa}\edef\tmpa{\apREMdotR\tmpa}}
+\def\apDIVv#1#2{\apnumX=#2
+ \ifx@#1\apDIVw{.\apIVwrite\apnumX}\else\apDIVw{\apIVwrite\apnumX}\expandafter\apDIVv\fi
+}
+\def\apDIVw#1{%
+ \ifx\XOUT\empty \ifnum\apnumX=0
+ \else \edef\tmpa{#1}\edef\XOUT{\apREMzerosR\tmpa\XOUT}%
+ \fi
+ \else \edef\XOUT{#1\XOUT}\fi
+}
+
+%%%%%%%%%%%% Power to the integer, sec. 2.7 in apnum.pdf
+
+\def\apPOWa{%
+ \ifnum\apSIGNa=0 \def\OUT{0}\apSIGN=0 \apE=0 \else
+ \ifnum\apSIGNb=0 \def\OUT{1}\apSIGN=1 \apE=0 \else
+ \apDIG\tmpb\apnumB
+ \ifnum\apnumB>0 \errmessage{POW: non-integer exponent is not implemented yet}\apPOWe\fi
+ \ifnum\apEb=0 \else \errmessage{POW: the E notation of exponent isn't allowed}\apPOWe\fi
+ \ifnum\apnumD>8 \errmessage{POW: too big exponent.
+ Do you really need about 10^\the\apnumD\space digits in output?}\apPOWe\fi
+ \apE=\apEa \multiply\apE by\tmpb\relax
+ \apSIGN=\apSIGNa
+ \ifodd\tmpb \else \apSIGN=1 \fi
+ \apDIG\tmpa\apnumA \apnumC=\apnumA \advance\apnumC by\apnumD
+ \apnumD=\apnumA \multiply\apnumD by\tmpb
+ \apIVmod \apnumC \apnumA
+ \edef\tmpc{\ifcase\apnumA\or{}{}{}\or{}{}\or{}\fi}\def\OUT{}%
+ \expandafter\expandafter\expandafter \apMULb \expandafter \tmpc \tmpa @@@@%
+ \edef\OUT{*.\OUT}% \OUT := \tmpa in interleaved format
+ \let\tmpd=\tmpa \def\tmpa{}%
+ \expandafter\expandafter\expandafter \apMULc \expandafter \tmpc \tmpd @@@@%
+ \def\tmpc{*.1*}\apnumE=10
+ \edef\tmpb{\apREV\tmpb}%
+ \expandafter\apPOWb\tmpb@% do multiplications
+ \expandafter\apPOWg \tmpc % \OUT := \tmpc in human raedable form
+ \ifnum\apnumD=0 \ifnum \apSIGN<0 \edef\OUT{-\OUT}\fi
+ \else \def\tmpc{-\apnumD}\apnumG=\apSIGN \expandafter\apROLLa\OUT.@\OUT\fi
+ \ifnum\apSIGNb<0 \apPPab\apDIVa 1\OUT \fi
+ \relax
+ \fi\fi
+}
+\def\apPOWb#1{%
+ \ifx@#1\else
+ \ifnum\apnumE<10
+ \expandafter\apPOWc\ifcase\apnumE
+ ppmp.\or ppmp.\or pmp.\or mmp.\or mp.\or p.\or mmmm.\or mmm.\or mm.\or m.\or .\fi
+ \def\tmpb{}\expandafter\apPOWd\OUT \let\tmpa=\tmpb
+ \fi
+ \apnumE=#1
+ \ifnum\apnumE=0 \else
+ \expandafter\apPOWc\ifcase\apnumE
+ \or .\or p.\or pm.\or pp.\or ppm.\or pmp.\or pmpm.\or ppp.\or pppm.\fi
+ \def\tmpb{}\expandafter\apPOWd\OUT
+ \let\tmpd=\OUT \let\OUT=\tmpc
+ \expandafter\apMULd \tmpb@\expandafter\apPOWn\OUT@%
+ \let\tmpc=\OUT \let\OUT=\tmpd
+ \fi
+ \expandafter\apPOWb
+ \fi
+}
+\def\apPOWc#1{\ifx.#1\else \csname apPOW#1\endcsname \expandafter\apPOWc\fi}
+\def\apPOWd#1#2{% \apPOWd <spec format> => \tmpb (in simple reverse format)
+ \ifx*#1\expandafter\apPOWd \else
+ \edef\tmpb{\tmpb{#1}}%
+ \ifx*#2\else \expandafter\expandafter\expandafter\apPOWd\fi
+ \fi
+}
+\def\apPOWe#1\relax{\fi}
+\def\apPOWg#1#2{\def\OUT{}\apPOWh} % conversion to the human readable form
+\def\apPOWh#1#2{\apnumA=#1
+ \ifx*#2\edef\OUT{\the\apnumA\OUT}\else \edef\OUT{\apIVwrite\apnumA\OUT}\expandafter\apPOWh\fi
+}
+\def\apPOWm{\expandafter\apMULd\tmpa@\expandafter\apPOWn\OUT@}
+\def\apPOWp{\expandafter\apPOWt\OUT \expandafter\apPOWn\OUT@}
+\def\apPOWn#1{\def\OUT{*}\apPOWna}
+\def\apPOWna#1{\ifx*#1\expandafter\apPOWnn\else \edef\OUT{\OUT0{#1}}\expandafter\apPOWna\fi}
+\def\apPOWnn#1#2{\ifx*#1\edef\OUT{\OUT*}\else\edef\OUT{\OUT0{#1}}\expandafter\apPOWnn\fi}
+\def\apPOWt#1#2{\apPOWu} % power to two
+\def\apPOWu#1#2{\apnumA=#1
+ \expandafter\apPOWv\OUT
+ \ifx*#2\else \expandafter\apPOWu\fi
+}
+\def\apPOWv#1*#2#3#4{\def\apOUTl{}\apnumO=1 \apnumL=0
+ \apnumB=\apnumA \multiply\apnumB by\apnumB \multiply\apnumA by2
+ \ifx*#4\else\advance\apnumB by#4 \fi
+ \ifx\apnumB<\apIVbase \apnumX=0 \else \apIVtrans \fi
+ \edef\OUT{#1{#2}{\the\apnumB}*}%
+ \ifx*#4\apMULf0*\else\expandafter\apMULf\fi
+}
+
+%%%%%%%%%%%% ROLL, ROUND and NORM macros, sec. 2.8 in apnum.pdf
+
+\def\apROLLa{\apnumA=\tmpc\relax \ifnum\apnumA<0 \expandafter\apROLLc\else \expandafter\apROLLg\fi}
+\def\apROLLc{\edef\tmpc{}\edef\tmpd{\ifnum\apnumG<0-\fi}\apnumB=0 \apROLLd}
+\def\apROLLd#1{%
+ \ifx.#1\expandafter\apROLLe
+ \else \edef\tmpc{\tmpc#1}%
+ \advance\apnumB by1
+ \expandafter\apROLLd
+ \fi
+}
+\def\apROLLe#1{\ifx@#1\edef\tmpc{\tmpc.@}\else\edef\tmpc{\tmpc#1}\fi
+ \advance\apnumB by\apnumA
+ \ifnum\apnumB<0
+ \apnumZ=-\apnumB \edef\tmpd{\tmpd.}\apADDzeros\tmpd
+ \expandafter\expandafter\expandafter\apROLLf\expandafter\tmpc
+ \else
+ \apnumA=\apnumB
+ \expandafter\expandafter\expandafter\apROLLi\expandafter\tmpc
+ \fi
+}
+\def\apROLLf#1.@#2{\edef#2{\tmpd#1}}
+\def\apROLLg#1{\edef\tmpd{\ifnum\apnumG<0-\fi}\ifx.#1\apnumB=0 \else\apnumB=1 \fi \apROLLh#1}
+\def\apROLLh#1{\ifx.#1\expandafter\apROLLi\else \edef\tmpd{\tmpd#1}\expandafter\apROLLh\fi}
+\def\apROLLi#1{\ifx.#1\expandafter\apROLLi\else
+ \ifnum\apnumA>0 \else \apROLLj \apROLLk#1\fi
+ \ifx@#1\apROLLj \apROLLi0@\fi
+ \advance\apnumA by-1
+ \ifx0#1\else \apnumB=1 \fi
+ \ifnum\apnumB>0 \edef\tmpd{\tmpd#1}\fi
+ \expandafter\apROLLi\fi
+}
+\def\apROLLj#1\fi#2\apROLLi\fi{\fi\fi#1}
+\def\apROLLk#1{\ifx@#1\expandafter\apROLLo\expandafter@\else
+ \def\tmpc{}\apnumB=0 \expandafter\apROLLn\expandafter#1\fi
+}
+\def\apROLLn#1{%
+ \ifx.#1\ifnum\apnumB>0 \edef\tmpd{\tmpd.\tmpc}\fi \expandafter\apROLLo
+ \else \edef\tmpc{\tmpc#1}\advance\apnumB by#1 \expandafter\apROLLn
+ \fi
+}
+\def\apROLLo@#1{\let#1=\tmpd}
+
+\def\apROUNDa{\apnumD=\tmpc\relax
+ \ifnum\apnumD<0 \expandafter\apROUNDe
+ \else \expandafter\apROUNDb
+ \fi
+}
+\def\apROUNDb#1.{\edef\tmpc{#1}\apnumX=0 \def\tmpd{}\let\next=\apROUNDc \next}
+\def\apROUNDc#1{\ifx@#1\def\next{\apROUNDd.@}%
+ \else \advance\apnumD by-1
+ \ifnum\apnumD<0 \def\next{\apROUNDd#1}%
+ \else \ifx.#1\else \advance\apnumX by#1 \edef\tmpd{\tmpd#1}\fi
+ \fi
+ \fi \next
+}
+\def\apROUNDd#1.@#2{\def\XOUT{#1}%
+ \ifnum\apnumX=0 \def\tmpd{}\fi
+ \ifx\tmpd\empty
+ \ifx\tmpc\empty \def#2{0}%
+ \else \edef#2{\ifnum\apnumG<0-\fi\tmpc}\fi
+ \else\edef#2{\ifnum\apnumG<0-\fi\tmpc.\tmpd}\fi
+}
+\def\apROUNDe#1.@#2{\apnumC=\apnumD
+ \apPPs\apROLLa#2{\apnumC}\apPPs\apROUNDa#2{0}\apPPs\apROLLa#2{-\apnumC}%
+}
+\def\apNORMa#1.@#2{\ifnum\apnumG<0 \def#2{#1}\fi \expandafter\apNORMb\expandafter#2\tmpc@}
+\def\apNORMb#1#2#3@{%
+ \ifx.#2\apnumC=#3\relax \apDIG#1\apnumA \apNORMc#1%
+ \else \apnumC=#2#3\relax \apDIG#1\relax \apNORMd#1%
+ \fi
+}
+\def\apNORMc#1{\advance\apE by-\apnumA \advance\apE by\apnumC
+ \def\tmpc{-\apnumC}\expandafter\apROLLa#1.@#1%
+}
+\def\apNORMd#1{\advance\apE by\apnumD \advance\apE by-\apnumC
+ \def\tmpc{\apnumC}\expandafter\apROLLa\expandafter.#1.@#1%
+}
+
+%%%%%%%%%%%% Function-like macros, sec. 2.9 in apnum.pdf
+
+\def\apABSa{\ifnum\apSIGN<0 \apSIGN=1 \fi}
+\def\apiDIVa{{\apFRAC=0 \apTOT=0 \apDIVa \apOUTtmpb}\tmpb}
+\def\apiMODa{{\apFRAC=0 \apTOT=0 \apDIVa \let\OUT=\XOUT \apOUTtmpb}\tmpb}
+\def\apiROUNDa{\apROUNDa\OUT0}
+\def\apiFRACa{\apROUNDa\OUT0\ifx\XOUT\empty\def\OUT{0}\else\edef\OUT{.\XOUT}\fi}
+\def\apFACa{{\apnumC=\OUT\relax
+ \loop \ifnum \apnumC>2 \advance\apnumC by-1
+ \MUL{\OUT}{\the\apnumC}\repeat
+ \global\let\OUT=\OUT}%
+}
+
+%%%%%%%%%%%% Auxiliary macros, sec. 2.10 in apnum.pdf
+
+\def\apREV#1{\expandafter\apREVa#1@!}
+\def\apREVa#1#2!{\ifx@#1\else\apREVa#2!#1\fi}
+
+\def\apDIG#1#2{\ifx\relax#2\def\tmpc{}\else #2=0 \def\tmpc{\advance#2 by1 }\fi
+ \apnumD=0 \expandafter\apDIGa#1..@#1%
+}
+\def\apDIGa#1{\ifx.#1\csname apDIG\ifnum\apnumD>0 c\else b\fi\expandafter\endcsname
+ \else \advance\apnumD by1 \expandafter\apDIGa\fi}
+\def\apDIGb#1{%
+ \ifx0#1\advance\apnumD by-1 \tmpc \expandafter\apDIGb
+ \else \expandafter\apDIGc \expandafter#1\fi
+}
+\def\apDIGc#1.{\def\tmpd{#1}%
+ \ifx\tmpc\empty \let\next=\apDIGe
+ \else \def\next{\expandafter\apDIGd\tmpd@}%
+ \fi \next
+}
+\def\apDIGd#1{\ifx@#1\expandafter\apDIGe \else \tmpc \expandafter\apDIGd \fi}
+\def\apDIGe#1@#2{%
+ \ifx@#1@\else % #1=empty <=> the param has no dot, we need to do nothing
+ \ifnum\apnumD>0 \edef#2{\expandafter\apDIGf#2@}% the dot plus digits before dot
+ \else \let#2=\tmpd % there are only digits after dot, use \tmpd
+ \fi\fi
+}
+\def\apDIGf#1.#2@{#1#2}
+
+\def\apNL{0}
+\def\apIVread#1{\expandafter\apIVreadA#1\apNL\apNL\apNL\apNL\apNL@#1}
+\def\apIVreadA#1#2#3#4#5\apNL#6@#7{\apnumX=#1#2#3#4\relax \def#7{#5}}
+\def\apIVreadX#1#2{\edef\tmpc{\ifcase#1{}{}{}0\or{}{}{}\or{}{}\or{}\fi}%
+ \expandafter\expandafter\expandafter\apIVreadA\expandafter\tmpc#2\apNL\apNL\apNL\apNL\apNL@#2%
+}
+\def\apIVwrite#1{\ifnum#1<1000 0\ifnum#1<100 0\ifnum#1<10 0\fi\fi\fi\the#1}
+
+\mathchardef\apIVbase=10000
+\def\apIVtrans{\apnumX=\apnumB \divide\apnumB by\apIVbase \multiply\apnumB by-\apIVbase
+ \advance\apnumB by\apnumX \divide\apnumX by\apIVbase
+}
+\def\apIVmod#1#2{#2=#1\divide#2by4 \multiply#2by-4 \advance#2by#1\relax
+ \ifnum#2>0 \else \advance#2by4 \fi
+}
+
+\def\apIVdot#1#2{\noexpand\apIVdotA\ifcase#1....\or...\or..\or.\fi #2....@}
+\def\apIVdotA#1#2#3#4#5.#6@{\ifx.#1\else#1\fi
+ \ifx.#2\else#2\fi \ifx.#3\else#3\fi \ifx.#4\else#4\fi\ifx.#5.\else.#5\fi
+}
+\def\apNUMdigits#1{\expandafter\apNUMdigitsA#1@@@@!}
+\def\apNUMdigitsA#1#2#3#4#5!{\ifx@#4\ifx@#3\ifx@#2\ifx@#10\else1\fi \else2\fi \else3\fi \else4\fi}
+
+\def\apADDzeros#1{\edef#1{#10}\advance\apnumZ by-1
+ \ifnum\apnumZ>0 \expandafter\apADDzeros\expandafter#1\fi
+}
+\def\apREMzerosR#1{\expandafter\apREMzerosRa#1@0@!}
+\def\apREMzerosRa#10@#2!{\ifx!#2!\apREMzerosRb#1\else\apREMzerosRa#1@0@!\fi}
+\def\apREMzerosRb#1@{#1}
+\def\apREMdotR#1{\expandafter\apREMdotRa#1@.@!}
+\def\apREMdotRa#1.@#2!{\ifx!#2!\apREMzerosRb#1\else#1\fi}
+
+\def\apOUTx{\apnumO=7
+ \edef\apOUTn{\the\apnumL}\edef\apOUTl{\apOUTl\apOUTn,}%
+ \expandafter\def\csname apOUT:\apOUTn\endcsname{}%
+ \advance\apnumL by1
+}
+\def\apOUTs#1,{\ifx.#1\else\csname apOUT:#1\expandafter\endcsname\expandafter\apOUTs\fi}
+
+\def\apOUTtmpb{\edef\tmpb{\apSIGN=\the\apSIGN \apE=\the\apE \edef\noexpand\OUT{\OUT}}\expandafter}
+
+%%%%%%%%%%%% Conclusion, sec. 2.11 in apnum.pdf
+
+\ifx\documentclass\undefined \else % please, don't remove this message
+\message{SORRY, you are using LaTeX. I don't recommend this. Petr Olsak}\fi
+\catcode`\@=\apnumZ
+\endinput
+