\errorcontextlines999\relax X\input minifp.sty\relax X\MFPloadextra X \def\empty{} \def\frac#1#2{{#1\over#2}} \def\cs#1{{\tt \char`\\#1}} \def\mybreak{\vskip 0pt plus 100pt\penalty 0 \vskip 0pt plus -100pt\relax} \def\\{\hfil\break\ignorespaces} \def\y{Rpop\Z\Z\\} \def\Y{Rpop\Z\Z} \everymath{\displaystyle} {\bf Stack-only operations:}\\ Example of a program. Computes the solution of $ax^2 + bx + c = 0$ using the quadratic formula. If the result is complex, it detects this. Coefficients stored in \cs{A}, \cs{B} and \cs{C}. First case: $4x^2 + 5y^2 - 1= 0$. Solutions are $x = -\frac{5}{8} \pm \frac{1}{8}\sqrt{41}$ \def\A{4}\def\B{5}\def\C{-1} X\startMFPprogram % stack \Rpush\B\Rdup\Rsq % B(B^2) \Rpush\A\Rpush\C\Rmul\Rdbl\Rdbl % B(B^2)(4AC) \Rsub % B(B^2-4AC) \IFneg{\def\I{i}\Rchs}{\def\I{}}% % B(|B^2-4AC|) \Rsqrt\Rpush\A\Rdbl\Rdiv % B(sqrt(|B^2-4AC|)/2A) \Rpop\Ypart % B \Rpush\A\Rdbl\Rdiv\Rchs % (-B/2A) \Rpop\Xpart % %\expandafter\show\csname MFP@Rstack\endcsname \Rpush\Xpart\Rpush\Ypart\Radd\Rpop\Broot \Rpush\Xpart\Rpush\Ypart\Rsub\Rpop\Sroot \Export\Xpart \Export\Ypart \Export\Broot \Export\Sroot \Export\I \stopMFPprogram X \indent Solution: $x = \Xpart \pm \I\Ypart = \Broot$ and $\Sroot$. Second case $2x^2 - 2x + 3 = 0$. Solutions are $x = \frac{1}{2} \pm \frac{i}{2}\sqrt{5}$. \def\A{2}\def\B{-2}\def\C{3} X\startMFPprogram % stack \Rpush\B\Rdup\Rsq % B(B^2) \Rpush\A\Rpush\C\Rmul\Rdbl\Rdbl % B(B^2)(4AC) \Rsub % B(B^2-4AC) \IFneg{\def\I{i}\Rchs}{\def\I{}}% % B(|B^2-4AC|) \Rsqrt\Rpush\A\Rdbl\Rdiv % B(sqrt(|B^2-4AC|)/2A) \Rpop\Ypart % B \Rpush\A\Rdbl\Rdiv\Rchs % (-B/2A) \Rpop\Xpart % \Export\Xpart \Export\Ypart \Export\I \stopMFPprogram X %\expandafter\show\csname MFP@Rstack\endcsname \indent Solution: $x = \Xpart \pm \I\Ypart$. Now try square roots (should be exactly 1234.5678 and 1524): X\startMFPprogram % stack \Rpush{1524157.65279684}\Rsqrt\Rpop\X \Rpush{1524}\Rsq\Rsqrt\Rpop\Y \Export\X \Export\Y \stopMFPprogram X \X { and }\Y. Below we test for speed and to check for any space characters accidentally produced. You should see only a few xX pairs with hopefully no spaces in between them. As curently set up, these tests perform about 34000 numerical operations. It all takes about 31 seconds on a moderately old (2 years?) Windows 7 running plain tex from TeX~Live~2012. This operation count does not distinguish between basic operations like addition and multiplication, and those operations from mfpextra that are probably each equivalent to a dozen or more multiplications. Counting each such operation with the an estimated multiplicity, the tests probably perform 400 thousand or more basic operations. Of the basic operations, multiplication is (by measurement) 4 times as lengthy as addition, and division is about twice as lengthy as multiplication. Actual times depend on the machine, but the ratios remain pretty much the same. Here is a summary of timings on my fastest machine; each operation is run 500 times in a loop: \medskip \indent\vtop{\halign{\hfil$#$&\quad$#\,$sec\cr \noalign{\hrule\smallskip} 2.54321+22432.87654321 &0.015\cr 2.54321\times22432.87654321 &0.06\cr 22432.87654321/2.54321 &0.14\cr \sqrt{23456789.54321} &0.20\cr 1.00001234^{8000} &0.73\cr \exp(2.54321) &0.41\cr \sin(2.54321) &0.45\cr \log(2.54321) &0.53\cr \mathop{\fam0 angle}(254.321,100) &1.17\cr \noalign{\smallskip\hrule} }} \medskip Originally, all the tests combined took 21 seconds on a 4-year-old Windows XP under TeX Live 2011. But since then I have changed angle and power computations so that they are considerably more accurate, but with a possible reduction in speed. Of course, some of the speed loss may be due to the operating system. On a Windows 7 machine, 64-bit, laptop, it takes 32 seconds to process this file. On another Win7, machine, 32-bit, desktop, it takes 10 seconds. The difference could be explained partially by the fact that the second machine is newer and partially by the fact that TeX is a 32-bit program, and therefore a better match to the operating system of the second system. \def\testi{% stack forms \startMFPprogram \Rpush{0.000 001}\Rpop\X \Rpush{1.2}\Rpush{-2.3}\Rexch\Rdup \Rpop\X\Rpop\X \Rpop\X\Rpush{21.34}\Rchs \Rpop\X\Rpush{21.34}\Rabs \Rpop\X\Rpush{21.34}\Rchs \Rpop\X\Rpush{21.34}\Rint \Rpop\X\Rpush{21.34}\Rfrac \Rpop\X\Rpush{21.34}\Rdbl \Rpop\X\Rpush{21.34}\Rhalve \Rpop\X\Rpush{21.34}\Rsgn \Rpop\X\Rpush{21.34}\Rsin \Rpop\X\Rpush{21.34}\Rcos \Rpop\X\Rpush{21.34}\Rdeg \Rpop\X\Rpush{21.34}\Rrad \Rpop\X\Rpush{21.34}\Rlog \Rpop\X\Rpush{21.34}\Rln \Rpop\X\Rpush{-1.34}\Rexp \Rpop\X\Rpush{3.3}\Rexp \Rpop\X\Rpush{21.34}\Rsq \Rpop\X\Rpush{21.34}\Rinv \Rpop\X\Rpush{21.34}\Rfloor \Rpop\X\Rpush{21.34}\Rceil \Rpop\X\Rpush{21.34}\Rsqrt \Rpop\X\Rpush{21.34}\Rpush{12.34}\Rcmp \IFlt{}{}\IFgt{}{}\IFeq{}{}\Rsub \IFneg{}{}\IFpos{}{}\IFzero{}{}\Rpop\X \Rpush{1.2}\Rpush{-2.3}\Radd \Rpop\X\Rpush{1.2}\Rpush{-2.3}\Rsub \Rpop\X\Rpush{1.2}\Rpush{-2.3}\Rmul \Rpop\X\Rpush{1.2}\Rpush{-2.3}\Rdiv \Rpop\X\Rpush{2.3}\Rpush{17}\Rpow \Rpop\X\Rpush{2.3}\Rpush{-17}\Rpow \Rpop\X\Rpush{1.2}\Rpush{-2.3}\Rmax \Rpop\X\Rpush{1.2}\Rpush{-2.3}\Rmin \stopMFPprogram} \def\testii{% unary operand forms, including \MFPchs\X\Z % extra tests of sin, log, exp and pow \MFPchs\Y\Z \MFPabs\X\Z \MFPabs\Y\Z \MFPdbl\X\Z \MFPdbl\Y\Z \MFPhalve\X\Z \MFPhalve\Y\Z \MFPint\X\Z \MFPint\Y\Z \MFPsgn\X\Z \MFPsgn\Y\Z \MFPsq\X\Z \MFPsq\Y\Z \MFPinv\X\Z \MFPinv\Y\Z \MFPfrac\X\Z \MFPfrac\Y\Z \MFPfloor\X\Z \MFPfloor\Y\Z \MFPceil\X\Z \MFPceil\Y\Z \MFPsin{30}\Z \MFPsin{420}\Z \MFPcos{60}\Z \MFPcos{390}\Z \MFPlog\X\Z \MFPln\X\Z \MFPexp\X\Z \MFPexp\Y\Z \MFPsin{1}\Z \MFPsin{2}\Z \MFPsin{3}\Z \MFPsin{4}\Z \MFPsin{5}\Z \MFPsin{6}\Z \MFPsin{7}\Z \MFPsin{8}\Z \MFPsin{9}\Z \MFPsin{10}\Z \MFPsin{20}\Z \MFPsin{30}\Z \MFPsin{40}\Z \MFPsin{50}\Z \MFPsin{60}\Z \MFPsin{70}\Z \MFPsin{80}\Z \MFPsin{90}\Z \MFPlog{.1}\Z \MFPlog{.2}\Z \MFPlog{.3}\Z \MFPlog{.4}\Z \MFPlog{.5}\Z \MFPlog{.6}\Z \MFPlog{.7}\Z \MFPlog{.8}\Z \MFPlog{.9}\Z \MFPlog{1}\Z \MFPlog{1.01}\Z \MFPlog{1.02}\Z \MFPlog{1.03}\Z \MFPlog{1.04}\Z \MFPlog{1.05}\Z \MFPlog{1.06}\Z \MFPlog{1.07}\Z \MFPlog{1.08}\Z \MFPlog{1.09}\Z \MFPexp{.000001}\Z \MFPexp{.00001}\Z \MFPexp{.0001}\Z \MFPexp{.001}\Z \MFPexp{.01}\Z \MFPexp{.1}\Z \MFPexp{1}\Z \MFPexp{2}\Z \MFPexp{3}\Z \MFPexp{4}\Z \MFPexp{5}\Z \MFPexp{6}\Z \MFPexp{7}\Z \MFPexp{8}\Z \MFPexp{9}\Z \MFPexp{10}\Z \MFPexp{-8.3254}\Z \MFPpow\MFPe{-10}\Z \MFPpow\MFPe{-9}\Z \MFPpow\MFPe{-8}\Z \MFPpow\MFPe{-7}\Z \MFPpow\MFPe{-6}\Z \MFPpow\MFPe{-5}\Z \MFPpow\MFPe{-4}\Z \MFPpow\MFPe{-3}\Z \MFPpow\MFPe{-2}\Z \MFPpow\MFPe{-1}\Z \MFPpow\MFPe{0}\Z \MFPpow\MFPe{1}\Z \MFPpow\MFPe{2}\Z \MFPpow\MFPe{3}\Z \MFPpow\MFPe{4}\Z \MFPpow\MFPe{5}\Z \MFPpow\MFPe{6}\Z \MFPpow\MFPe{7}\Z \MFPpow\MFPe{8}\Z \MFPpow\MFPe{9}\Z \MFPpow\MFPe{10}\Z} \def\testiii{%% binary operand forms and print formating, plus \MFPsqrt{0}\Z % additional tests of sqrt \MFPsqrt{1}\Z \MFPsqrt{2}\Z \MFPsqrt{3}\Z \MFPsqrt{4}\Z \MFPsqrt{5}\Z \MFPsqrt{6}\Z \MFPsqrt{7}\Z \MFPsqrt{8}\Z \MFPsqrt{9}\Z \MFPsqrt{10}\Z \MFPsqrt{1524157.65279684}\Z \MFPadd\X\Y\Z \MFPsub\X\Y\Z \MFPsub\Y\X\Z \MFPsub\X\X\Z \MFPsub\Y\Y\Z \MFPmul\X\Y\Z \MFPdiv\X\Y\Z \MFPdiv\Y\X\Z \MFPmax\X\Y\Z \MFPmin\X\Y\Z \MFPpow\X{5}\Z \MFPpow\X{-5}\Z \MFPpow\Y{5}\Z \MFPpow\Y{-5}\Z \MFPcmp\X\Y \IFlt{}{}\IFgt{}{}\IFeq{}{}% \MFPsub\X\Y\Z \IFneg{}{}\IFpos{}{}\IFzero{}{}% \def\T{333.00000000}% \def\S{1357.12345678}% \MFPtruncate{4}\T\Z \MFPtruncate{0}\T\Z \MFPtruncate{-2}\T\Z \MFPstrip\T\Z \MFPstrip*\T\Z \MFPround{3}\S\Z \MFPround{5}\S\Z \MFPround{0}\S\Z \MFPround{-2}\S\Z \def\T{-333.00000000}% \def\S{-1357.12345678}% \MFPtruncate{4}\T\Z \MFPtruncate{0}\T\Z \MFPtruncate{-2}\T\Z \MFPstrip\T\Z \MFPstrip*\T\Z \MFPround{3}\S\Z \MFPround{5}\S\Z \MFPround{0}\S\Z \MFPround{-2}\S\Z} Three test loops follow. The first repeats 500 times a stack program that performs each available command followed by popping the result and repushing the original value(s). \newcount\n \def\testloopi{% \ifnum \n>0 \advance\n -1 \testi \expandafter \testloopi \fi } \n=500 x\testloopi X The second repeats 100 times a sequence in which all the unary operand commands are performed twice, plus extra of sine, log and exp. \def\testloopii{% \ifnum \n>0 \advance\n -1 \testii \expandafter \testloopii \fi } \def\X{1.2} \def\Y{-2.3} \n=100 x\testloopii X The third repeats 100 times a sequence in which all the binary operand commands are performed, plus some extra tests of sqrt and then all the print-preparation commands. \def\testloopiii{% \ifnum \n>0 \advance\n -1 \testiii \expandafter \testloopiii \fi } \n=100 x\testloopiii X \end \end{document}