From e9a0efc06e926644568e9975bdc6c46044423d36 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 5 Feb 2013 23:41:08 +0000 Subject: minifp (5feb13) git-svn-id: svn://tug.org/texlive/trunk@29037 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/generic/minifp/README | 9 +- Master/texmf-dist/doc/generic/minifp/minifp.pdf | Bin 418427 -> 419173 bytes Master/texmf-dist/doc/generic/minifp/test1.tex | 19 +- Master/texmf-dist/source/generic/minifp/minifp.dtx | 385 +++++++++++---------- Master/texmf-dist/tex/generic/minifp/mfpextra.tex | 45 ++- Master/texmf-dist/tex/generic/minifp/minifp.sty | 8 +- 6 files changed, 249 insertions(+), 217 deletions(-) diff --git a/Master/texmf-dist/doc/generic/minifp/README b/Master/texmf-dist/doc/generic/minifp/README index f6b413bf9ee..eec67f09a9e 100644 --- a/Master/texmf-dist/doc/generic/minifp/README +++ b/Master/texmf-dist/doc/generic/minifp/README @@ -13,7 +13,7 @@ Purpose: Minifp should work in both latex and plaintex. - This is version 0.9. It should work reasonably well, barring any bugs, + This is version 0.92. It should work reasonably well, barring any bugs, but I expect to spend some time fine-tuning it for version 1.0. License: @@ -79,12 +79,13 @@ Manifest: This distribution, the latest updates, and possibly some past versions, should also be available at my web site: - . + . History: - Version 0.9 : maximum possible accuracy achieved for angle, at some - cost to speed. + Version 0.92 : Bugfixes: correct sign of floor and ceiling. Correct + occasional minus sign in front of 0 for sin or cos. + Version 0.9 : angle: near maximum accuracy, at some cost to speed. Version 0.8 : exp: now more accurate for many cases. Version 0.7 : sqrt: now exact when possible and much more accurate. Version 0.6 : Added angle to mfpextra. Changed package name to minifp. diff --git a/Master/texmf-dist/doc/generic/minifp/minifp.pdf b/Master/texmf-dist/doc/generic/minifp/minifp.pdf index 94d43d6488f..baca0c62f24 100644 Binary files a/Master/texmf-dist/doc/generic/minifp/minifp.pdf and b/Master/texmf-dist/doc/generic/minifp/minifp.pdf differ diff --git a/Master/texmf-dist/doc/generic/minifp/test1.tex b/Master/texmf-dist/doc/generic/minifp/test1.tex index 024e5c5a44d..c08127eb8b9 100644 --- a/Master/texmf-dist/doc/generic/minifp/test1.tex +++ b/Master/texmf-dist/doc/generic/minifp/test1.tex @@ -80,16 +80,16 @@ Exponential:\Rexp\y Back to $21.34$:\Rpop\X\Rpush{21.34}\y Square:\Rsq\y \Rpop\X\Rpush{21.34}% -\tracingmacros1 Inversion:\Rinv\y -\tracingmacros0 \Rpop\X\Rpush{21.34}% +\tracingmacros1 Floor:\Rfloor\y +\tracingmacros0 \Rpop\X\Rpush{21.34}% Ceiling:\Rceil\y \Rpop\X\Rpush{21.34}% Square root:\Rsqrt\y -Now put $21.34$ and $12.34$ in that order:\Rpop\X\Rpush{21.34}\Rpush{12.34}\y +Now push $21.34$ and $12.34$ in that order:\Rpop\X\Rpush{21.34}\Rpush{12.34}\y Compare: \Rcmp 21.34 is\IFlt{}{ not} less than 12.34. 21.34 is\IFgt{}{ not} more than 12.34. @@ -404,7 +404,16 @@ negative:^^J} Square root of $8$:\MFPsqrt{8}\Z\w Square root of $9$:\MFPsqrt{9}\Z\w Square root of $10$:\MFPsqrt{10}\Z\w - Square root of $1524157.65279684$ (should be exact):\MFPsqrt{1524157.65279684}\Z\w + Square root of $99$:\MFPsqrt{99}\Z\w + Square root of $500$:\MFPsqrt{500}\Z\w + Square root of $1000$:\MFPsqrt{1000}\Z\w + Square root of $5000$:\MFPsqrt{5000}\Z\w + Square root of $9999$:\MFPsqrt{9999}\Z\w +Square root of $100000$:\MFPsqrt{100000}\Z\w +Square root of $100000$:\MFPsqrt{100000}\Z\w +Square root of $1500000$:\MFPsqrt{1500000}\Z\w +Square root of $1524157.65279684$ (should be exact):\MFPsqrt{1524157.65279684}\Z\w +Square root of $15000000$:\MFPsqrt{15000000}\Z\w Square root of $99999998.00000001$ (should be exact):\MFPsqrt{99999998.00000001}\Z\w Square root of $9999.99$:\MFPsqrt{9999.99}\Z\w Square root of $9999.999 999$:\MFPsqrt{9999.999999}\Z\W @@ -418,7 +427,7 @@ Subtract $Y-X$:\MFPsub\Y\X\Z\w Subtract $X-X$:\MFPsub\X\X\Z\w Subtract $Y-Y$:\MFPsub\Y\Y\Z\w Multiply:\MFPmul\X\Y\Z\w -Multiply $10^4\times10^4$:\MFPmul{10000}{10000}\Z\w +Multiply $10^{4}\times10^4$ (loses the overflow digit):\MFPmul{10000}{10000}\Z\w Divide $X/Y$:\MFPdiv\X\Y\Z\w Divide $Y/X$:\MFPdiv\Y\X\Z\w Max:\MFPmax\X\Y\Z\w diff --git a/Master/texmf-dist/source/generic/minifp/minifp.dtx b/Master/texmf-dist/source/generic/minifp/minifp.dtx index 3c3ff629144..77f56099f70 100644 --- a/Master/texmf-dist/source/generic/minifp/minifp.dtx +++ b/Master/texmf-dist/source/generic/minifp/minifp.dtx @@ -13,8 +13,8 @@ % minifp has maintenance status "author-maintained". The Current Maintainer % is Daniel H. Luecking. The Base Interpreter is TeX (plain TeX or LaTeX). %<*driver|sty> -\def\MFPfiledate{2013/01/01}% -\def\MFPfileversion{0.9}% +\def\MFPfiledate{2013/02/01}% +\def\MFPfileversion{0.92}% % % %<*driver> @@ -102,7 +102,7 @@ \end{document} % %\fi -% \CheckSum{3325} +% \CheckSum{3339} % \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 @@ -136,22 +136,22 @@ % In working on an application that needed to be able to automatically % generate numeric labels on the axes of a graph, I needed to be able % to make simple calculations with real numbers. What \TeX{} provides is -% far to limited. In fact, its only native user-level support for real +% far too limited. In fact, its only native user-level support for real % numbers is as factors for dimensions. For example one can ``multiply'' % $3.1\times 0.2$ by \verb$\dimen0=0.2pt \dimen0=3.1\dimen0 $. % -% Unfortunately \TeX{} stores dimensions as integer multiples of of the +% Unfortunately \TeX{} stores dimensions as integer multiples of the % ``scaled point'' (\dim{sp}) with \dim{sp}${}=2^{-16}$\dim{pt}, and % therefore \dim{.2pt} is approximated by $\frac{13107}{65536}$, which is % not exact. Then mutiplying by $3.1$ produces $\frac{40631}{65536}$. If -% we ask for 5 digit accuracy, this produces $0.61998$\dim{pt} and not the +% we ask for five digit accuracy, this produces $0.61998$\dim{pt} and not the % exact value $0.62$. This is sufficiently accurate for positioning % elements on a page, but not for displaying automatically computed axis -% labels if 5 digit accuracy is needed. +% labels if five digit accuracy is needed. % % The \mfp{} package was written to provide the necessary calculations % with the necessary accuracy for this application. The implementation -% would have been an order of magnitude smaller and faster if only 4 digit +% would have been an order of magnitude smaller and faster if only four digit % accuracy were provided (and I may eventually do that for the application % under consideration), but I have decided to clean up what I have % produced and release it as is. The full \mfp{} package provides nearly @@ -161,8 +161,8 @@ % the \prog{mfpic} drawing package. % % I decided on eight digits on both sides of the decimal point essentially -% because I wanted at least 5 digits and the design I chose made multiples -% of 4 the easiest to work with. +% because I wanted at least five digits and the design I chose made multiples +% of four the easiest to work with. % % \Mfp{} also provides a simple stack-based language for writing assembly % language-like programs. Originally, this was to be the native @@ -186,14 +186,14 @@ % Another simplification: multiplication has to be done by breaking the % number into parts. \TeX{} can multiply any two 4-digit integers without % overflow, but it cannot multiply most pairs of 5-digit integers. Two -% 8-digit numbers conveniently break ito four 4-digit parts. To get even +% 8-digit numbers conveniently break into four 4-digit parts. To get even % nine digits of accuracy would require six parts (five, if we don't % insist on a separation occuring at the decimal point). The complexity of % the multiplication process goes up as the square of the number of parts, % so six parts would more than double the complexity. % -% A final simplification: \TeX{} places a limit of 9 on the number of -% arguments a macro can have. Quite often the last argument is needed +% A final simplification: \TeX{} places a limit of nine on the number of +% arguments a macro can have. Quite often the last argument is needed to % clear out unused text to be discarded. Thus, a string of eight digits % can quite often be processed with one execution of one nine-argument % macro. @@ -208,7 +208,7 @@ % Multiplication is carried out internally to an exact 16-digit answer, % which is then rounded to an 8-digit result. Overflow (more than 8 % digits in the integer part) is discarded. Division is internally -% carried to 9 digits after the decimal, which is then also rounded to +% carried to nine digits after the decimal, which is then also rounded to % an 8-digit result. % % We supply two kinds of operations in this package. There are stack-based @@ -239,10 +239,10 @@ % in the same way. The internal commands will thus have a standard form to % operate on. All results are returned in standard form. % -% The standard form referred to above is an integer part (1 to 8 digits +% The standard form referred to above is an integer part (one to eight digits % with no unnecessary leading zeros nor unnecessary sign) followed by the % decimal point (always a dot, which is ASCII \number`\.), followed by exactly -% 8 digits, all of this preceded by a minus sign if the number is +% eight digits, all of this preceded by a minus sign if the number is % negative. Thus, $-{-0.25}$ would be processed and stored as % ``\texttt{0.25000000}'' and $-.333333$ as ``\texttt{-0.33333300}''. % @@ -293,7 +293,7 @@ % \Rpush{3.4} % \Radd % \Rpop\X \end{verbatim} -% which would push first \texttt{1.20000000} then \texttt{3.40000000} onto +% which would \op{push} first \texttt{1.20000000} then \texttt{3.40000000} onto % the stack, then replace them with \texttt{4.60000000}, then remove that % and store it in \verb$\X$. Clearly the stack is intended for % calculations that produce a lot of intermediate values and only the @@ -318,8 +318,8 @@ % \meta{num} can be any decimal real number with at most 8 % digits on each side of the decimal point, or they can be macros that % contain such a number. If the decimal dot is absent, the fractional part -% will be taken to be 0, if the integer part or the fractional part is -% absent, it will be taken to be 0. (One consequence of these rules is +% will be taken to be $0$, if the integer part or the fractional part is +% absent, it will be taken to be $0$. (One consequence of these rules is % that all the following arguments produce the same internal % representation of zero: \marg{0.0}, \marg{0.}, \marg{.0}, % \marg{0}, \marg{.}, and \marg{}\,.) Spaces may appear anywhere in the @@ -389,12 +389,12 @@ % \SpecialUsageIndex{\MFPint}^^A % \cs{MFPint}\mmarg{num}\cs{macro}& % Replaces the part of \meta{num} after the decimal point with zeros -% (keeps the sign unless the result is zero) and stores the result in +% (keeps the sign unless the result is $0$) and stores the result in % \cs{macro}.\\ % \SpecialUsageIndex{\MFPfrac}^^A % \cs{MFPfrac}\mmarg{num}\cs{macro}& -% Replaces the part of \meta{num} before the decimal point with zero -% (keeps the sign unless the result is zero) and stores the result in +% Replaces the part of \meta{num} before the decimal point with $0$ +% (keeps the sign unless the result is $0$) and stores the result in % \cs{macro}.\\ % \SpecialUsageIndex{\MFPfloor}^^A % \cs{MFPfloor}\mmarg{num}\cs{macro}& @@ -432,7 +432,7 @@ % The command \cs{MFPzero} is useful for ``macro programs''. If you want % to do something to a number depending on the outcome of a test, you may % occasionally want to simply absorbed the number and output a default -% result. (There are more efficient ways to simply store 0 in a macro.) +% result. (There are more efficient ways to simply store $0$ in a macro.) % % Note that one could easily double, halve, square, increment, % decrement or invert a \meta{num} using the binary versions of @@ -502,10 +502,10 @@ % \medskip % Issuing \verb$\MFPchk{\X}$ will check the sign of the number stored in % the macro \cs{X}. Then \verb$\IFneg{A}{B}$ will produce `\verb$A$' if it -% is negative and `\verb$B$' if it is 0 or positive. Similarly, +% is negative and `\verb$B$' if it is $0$ or positive. Similarly, % \verb$\MFPcmp{\X}{1}$ will compare the number stored in \cs{X} to $1$. % Afterward, \verb$\IFlt{A}{B}$ will produce `\verb$A$' if \cs{X} is less -% than $1$ and `\verb$B$' if \cs{X} is equal to or greater than 1. +% than $1$ and `\verb$B$' if \cs{X} is equal to or greater than $1$. % % If users finds it tiresome to type two separate commands, they can % easily define a single command that both checks a value and runs @@ -584,8 +584,8 @@ % for the absolute values. The processing will remove redundant signs % along with redundant leading zeros: \verb$\MFPtruncate{-3}{-+123.456}$ % will produce \texttt{0}. The rounding rule is as follows: round up if -% the digit to the right of the rounding point is 5 or more, round down if -% the digit is 4 or less. +% the digit to the right of the rounding point is $5$ or more, round down if +% the digit is $4$ or less. % % % \subsection{Stack-based macros}\label{stack} @@ -608,7 +608,7 @@ % and define the given macro to have that number as its definition. % % All the binary operations remove the last two numbers from the stack, -% operate on them in the order they were put on the stack, and push the +% operate on them in the order they were put on the stack, and \op{push} the % result on the stack. Thus the program % \begin{verbatim} % \Rpush{1.2} @@ -683,13 +683,13 @@ % Obtains the reciprocal. Slightly more efficient than the equivalent % division.\\ % \SpecialUsageIndex{\Rincr}\cs{Rincr}& -% Increases by 1. Slightly more efficient than the equivalent +% Increases by $1$. Slightly more efficient than the equivalent % addition.\\ % \SpecialUsageIndex{\Rdecr}\cs{Rdecr}& -% Decreases by 1. Slightly more efficient than the equivalent +% Decreases by $1$. Slightly more efficient than the equivalent % subtraction.\\ % \SpecialUsageIndex{\Rzero}\cs{Rzero}& -% Replaces the number with zero. Slightly more convenient than the +% Replaces the number with $0$. Slightly more convenient than the % equivalent \cs{Rpop}\cs{X} followed by a \cs{Rpush}\marg{0}.\\ % \end{tabular}} % @@ -808,12 +808,12 @@ % % \subsection{Errors} % -% If one tries to pop from an empty stack, an error message will be +% If one tries to \op{pop}from an empty stack, an error message will be % issued. Ignoring the error causes the macro to have the value stored % in the macro \SpecialUsageIndex{\EndofStack}\verb$\EndofStack$. % Its default is \texttt{0.00000000}. % -% If one tries to divide by zero, an error message will be issued. +% If one tries to divide by $0$, an error message will be issued. % Ignoring the error causes the result to be one of the following: % \begin{itemize} % \item Dividing $0$ by $0$ gives a result whose integer part is stored @@ -1020,7 +1020,7 @@ % I have been lax at making sure \cs{MFP@z@Ovr} is properly initiallized % and properly checked whenever it could be relevant, and properly % passed on. I think every internal command \cs{MFP@R}\textit{xxx} -% should ensure it starts being 0 and ends with a numerical value. I +% should ensure it starts being $0$ and ends with a numerical value. I % notice that division might make it empty. % % \cs{MFP@subroutine} executes its argument (typically a single command) with @@ -1052,7 +1052,7 @@ % % \DescribeMacro{\EndofStack} % We define here the error messages: popping from an empty stack and -% dividing by zero. In addition to the error messages, we provide some +% dividing by $0$. In addition to the error messages, we provide some % default values that hopefully allow some operations to continue. % % We also have a warning or two. @@ -1065,7 +1065,7 @@ \errmessage{MiniFP error: #1}% \endgroup}% \def\MFP@popempty@err{% - \MFP@errmsg{cannot pop from an empty stack}% + \MFP@errmsg{cannot POP from an empty stack}% {There were no items on the stack for the POP operation. % If you continue, ^^Jthe macro will contain the % value \EndofStack.}}% @@ -1087,7 +1087,7 @@ % \DescribeMacro{\MaxRealInt}These are the largest possible integer and % fractional parts of a real % \DescribeMacro{\MaxRealFrac}number. They are returned for division by -% zero, for logarithm of 0, and when overflow is detected in the +% $0$, for logarithm of $0$, and when overflow is detected in the % exponential function. % \begin{macrocode} \def\MaxRealInt {99999999}% @@ -1096,11 +1096,11 @@ % % \SpecialUsageIndex{\MaxRealInt} % \SpecialUsageIndex{\MaxRealFrac} -% These are the results returned when trying to divide by zero. Two are +% These are the results returned when trying to divide by $0$. Two are % \DescribeMacro{\xOverZeroInt} % \DescribeMacro{\xOverZeroFrac} -% used when dividing a nonzero number by zero and and two when trying to -% divide zero by zero. +% used when dividing a nonzero number by $0$ and and two when trying to +% divide $0$ by $0$. % \DescribeMacro{\ZeroOverZeroInt} % \DescribeMacro{\ZeroOverZeroFrac} % \begin{macrocode} @@ -1111,8 +1111,8 @@ % \end{macrocode} % % These macros strip the spaces, process a number into sign, integer and -% fractional parts, and pad the fractional part out to 8 decimals. They -% are used in PUSH so that the stack will only contains reals in a +% fractional parts, and pad the fractional part out to eight decimals. They +% are used in \op{push} so that the stack will only contains reals in a % normalized form. Some of them are also used to preprocess the reals in % the operand versions of commands % @@ -1120,7 +1120,7 @@ % stored in \cs{MFP@*@Sgn} as $-1$, $0$ or $1$. % % We strip the spaces and pad the fractional parts separately because -% they are unnecessary when processing POPed reals (though they wouldn't +% they are unnecessary when processing \op{pop}ed reals (though they wouldn't % hurt). % % The number to be parsed is \arg4 and the macros to contain the parts @@ -1152,14 +1152,14 @@ \@xp\MFPsplit@dot#1..\mfp@end #3#4% % \end{macrocode} % -% This is the first place where having at most 8 digits simplifies things. +% This is the first place where having at most eight digits simplifies things. % At this point \arg3 could contain any number of consecutive signs -% followed by any 8 digits. It could be zero, so to avoid losing the sign -% we append a \texttt{1} (for up to 9 digits). We temporarily define the +% followed by any eight digits. It could be $0$, so to avoid losing the sign +% we append a \texttt{1} (for up to nine digits). We temporarily define the % sign based on the result, but may need to drop it if both the integer -% and fractional parts are zero. +% and fractional parts are $0$. % -% Prepending a zero to the fractional part pemits it to be empty. +% Prepending a 0 to the fractional part permits it to be empty. % In the final \cs{edef}, \arg3 is made positive. % \begin{macrocode} \ifnum#31<0 @@ -1183,7 +1183,7 @@ % \end{macrocode} % % This is used to pad the fractional part to eight places with zeros. If -% a number with more than 8 digits survives to this point, it gets +% a number with more than eight digits survives to this point, it gets % truncated. % \begin{macrocode} \def\MFPpadto@eight#1{% @@ -1191,7 +1191,7 @@ % \end{macrocode} % % These take operands off the stack. We know already that there are no -% spaces and that the fractional part has 8 digits. +% spaces and that the fractional part has eight digits. % \begin{macrocode} \def\MFPgetoperand@x{\Rpop\MFP@x@Val \MFPprocess@into@parts\MFP@x@Val\MFP@x@Sgn\MFP@x@Int\MFP@x@Frc}% @@ -1225,8 +1225,8 @@ \def\MFPpush@result{\MFP@Rchk\MFPcurr@Sgn\MFP@Rcat\MFP@z@Val}% % \end{macrocode} % -% When POP encounters an empty stack it gobbles the code that would -% perform the pop (\arg1) and defines the macro (\arg2) to contain +% When \op{pop} encounters an empty stack it gobbles the code that would +% perform the \op{pop} (\arg1) and defines the macro (\arg2) to contain % \cs{EndofStack}. The default meaning for this macro is $0$. % \begin{macrocode} \def\if@EndofStack{% @@ -1238,7 +1238,7 @@ % \end{macrocode} % % The macro \cs{Rpop} calls \cs{MFP@popit} followed by the contents of the -% stack, the token \cs{mfp@end} and the macro to pop into. If the stack is +% stack, the token \cs{mfp@end} and the macro to \op{pop} into. If the stack is % not empty, \cs{doMFP@popit} will read the first group \arg1 into that macro % \arg3, and then redefine the stack to be the rest of the argument \arg2. % If the stack is empty, \cs{doMFP@EOS} will equate the macro to @@ -1365,7 +1365,7 @@ % \item[cmp] compare $x$ and $y$ (stack version does not change stack). % \item[chk] examine the sign of $x$ (stack version does not change stack). % \item[dup] stack only, duplicate the top element of the stack. -% \item[push] stack only, push a value onto the stack. +% \item[push] stack only, put a value on top of the stack. % \item[pop] stack only, remove the top element of the stack, % store it in a variable. % \item[exch] stack only, exchange top two elements of the stack. @@ -1561,7 +1561,7 @@ % % These are the wrappers for binary operations. The top level definitions % are almost identical to those of the unary operations. The only difference -% is they pop or parse two operands. +% is they \op{pop} or parse two operands. % \begin{macrocode} \def\MFP@stack@Binary#1{% \MFPgetoperand@y \MFPgetoperand@x @@ -1589,12 +1589,12 @@ % \end{macrocode} % % The doubling and halving operations are more efficient ways to -% multiply or divide a number by 2. For doubling, copy $x$ to $y$ +% multiply or divide a number by $2$. For doubling, copy $x$ to $y$ % and add. For halving, we use basic \TeX{} integer division, more % efficient than multiplying by $0.5$ and far more than using % \cs{MFP@Rdiv}. % -% In \cs{MFP@Rhalve}. we add 1 to the fractional part for rounding +% In \cs{MFP@Rhalve}. we add $1$ to the fractional part for rounding % purposes, and we move any odd 1 from the end of the integer part to the % start of the fractional part. % \begin{macrocode} @@ -1629,7 +1629,7 @@ % \end{macrocode} % % The inversion operation just calls \cs{MFP@Rdiv} after copying $x$ to -% $y$ and 1 to $x$. +% $y$ and $1$ to $x$. % \begin{macrocode} \def\MFP@Rinv{\MFP@Rcopy xy\MFP@Rload x110\MFP@Rdiv}% % \end{macrocode} @@ -1640,13 +1640,13 @@ \MFP@Rloadz {\ifnum\MFP@x@Int=0 0\else\MFP@x@Sgn\fi}\MFP@x@Int 0}% % \end{macrocode} % -% Fractional part: replace integer part with a zero. +% Fractional part: replace integer part with a $0$. % \begin{macrocode} \def\MFP@Rfrac{% \MFP@Rloadz {\ifnum\MFP@x@Frc=0 0\else\MFP@x@Sgn\fi}0\MFP@x@Frc}% % \end{macrocode} % -% To increment and decrement by 1, except in border cases, we need only +% To increment and decrement by $1$, except in border cases, we need only % address the integer part of a number. This doesn't seem so simple % written out but, even so, it is more efficient than full-blown addition. % It would be very slightly more efficient to repeat the increment code in @@ -1693,7 +1693,7 @@ \advance\MFP@tempa1 \fi \fi - \MFP@Rloadz{\ifnum\MFP@z@Int=0 0\else\MFP@x@Sgn\fi}\MFP@tempa0}% + \MFP@Rloadz{\ifnum\MFP@x@Int=0 0\else\MFP@x@Sgn\fi}\MFP@tempa0}% \def\MFP@Rfloor{\MFP@Rfloororceil>}% \def\MFP@Rceil {\MFP@Rfloororceil<}% % \end{macrocode} @@ -1726,14 +1726,14 @@ % \end{macrocode} % % We will store the intermediate and final products in \cs{MFP@z@*}. Each one -% is ultimately reduced to 4 digits, like the parts of $x$ and $y$. As each +% is ultimately reduced to four digits, like the parts of $x$ and $y$. As each % base-$10000$ digit of $y$ is multiplied by a digit of $x$, we add the % result to the appropriate digit of the partial result $z$. Thus, we need % to zero out $z$ at the start (or treat the first iteration differently): % % The underflow ends up in \cs{MFP@z@Frc@iv} and \cs{MFP@z@Frc@iii}. % Overflow will be in \cs{MFP@z@Int@iii}. Unlike the rest, it can be up to -% 8 digits because we do not need to carry results out of it. +% eight digits because we do not need to carry results out of it. % \begin{macrocode} \def\MFPmore@init@z{% \def\MFP@z@Frc@iv {0}% @@ -1940,7 +1940,7 @@ % \end{macrocode} % % \cs{MFP@Rmul} first computes the (theoretical) sign of the product: if -% zero return 0, otherwise provisionally set the sign of the product and +% $0$, return $0$, otherwise provisionally set the sign of the product and % call \cs{MFP@@Rmul}. % \begin{macrocode} \def\MFP@Rmul{% @@ -1955,9 +1955,9 @@ % % \cs{MFP@@Rmul} splits the four expected macros into eight macros % considered to be four base-10000 digits for each of $x$ and $y$. -% Then each digit of $y$ is used to multiply the 4 digits of $x$ and the +% Then each digit of $y$ is used to multiply the four digits of $x$ and the % results are added to corresponding digits of $z$, which have been -% initialized to 0 by \cs{MFPmore@init@z}. +% initialized to $0$ by \cs{MFPmore@init@z}. % \begin{macrocode} \def\MFP@@Rmul{% \MFPmore@init@z @@ -1991,13 +1991,13 @@ \MFP@carrym\MFP@z@Int@i \MFP@z@Int@ii \MFP@carrym\MFP@z@Int@ii\MFP@z@Int@iii % \end{macrocode} -% To end, we arrange for all macros to hold 4 digits (except +% To end, we arrange for all macros to hold four digits (except % \cs{MFP@z@Int@ii} which doesn't need leading 0s, and \cs{MFP@z@Int@iii} % which also doesn't) and load them into the appropriate 8-digit macros. % The underflow digits are stored in \cs{MFP@z@Und} in case we ever need % to examine them, and the overflow in \cs{MFP@z@Ovr} in case we ever need % to implement an overflow error. Theoretically $z \ne 0$, but it is -% possible that $z=0$ after rounding to 8 places. If so, we must reset +% possible that $z=0$ after rounding to eight places. If so, we must reset % \cs{MFP@z@Sgn}. % \begin{macrocode} \makeMFP@fourdigits\MFP@z@Frc@iv @@ -2019,9 +2019,9 @@ % For division, we will obtain the result one digit at a time until the % $9$th digit after the decimal is found. That $9$th will be used to round % to eight digits (and stored as underflow). We normalize the denominator -% by shifting left until the integer part is 8 digits. We do the same for -% the numerator. The integer quotient of the integer parts will be 1 digit -% (possibly 0). If the denominator is shifted $d$ digits left and the +% by shifting left until the integer part is eight digits. We do the same for +% the numerator. The integer quotient of the integer parts will be one digit +% (possibly a 0). If the denominator is shifted $d$ digits left and the % numerator $n$ digits left, the quotient will have to be shifted $n-d$ % places right or $d-n$ places left. Since the result is supposed to have % $9$ digits after the dot, our quotient needs $9+d-n+1$ total digits. @@ -2031,7 +2031,7 @@ % only $16$ significant digits should be retained in any case.) If $d$ is % $0$ and $n$ is $15$ we would need $-5$ digits. That means the first % nonzero digit is in the 15th or 16th place after the dot and the -% quotient is effectively 0. +% quotient is effectively $0$. % % Here I explain why we normalize the parts in this way. If a numerator % has the form $n_1.n_2$ and the denominator has the form $d_1.d_2$ then @@ -2041,9 +2041,9 @@ % however is the largest integer $q$ such that $q(d_1.d_2) \le n_1.n_2$. % It can easily be shown that $q \le q_1$. It is true, but not so easily % shown, that $q \ge q_1 - 1$. This is only true if $d_1$ is large enough, -% in our case it has to be at least 5 digits. Thus we only have to do one +% in our case it has to be at least five digits. Thus we only have to do one % simple division and decide if we need to reduce the quotient by one. If -% we arrange for $d_1$ to have 8 digits, then $q_1$ will be one digit and +% we arrange for $d_1$ to have eight digits, then $q_1$ will be one digit and % the test for whether we need to reduce it becomes easier. % % This test is done as follows. The first trial quotient, $q_1$, will work @@ -2069,14 +2069,14 @@ % % Now I need to get it organized. \cs{MFP@Rdiv} will have \cs{MFP@x@*} and % \cs{MFP@y@*} available. One step (could be first or last). Is to calculate -% the sign. Let's do it first (because we need to check for 0 anyway). +% the sign. Let's do it first (because we need to check for $0$ anyway). % -% We invoke an error message upon division by 0, but nevertheless return -% a value. By default they are $0$ for $0/0$ and the maximum possible real -% for $x/0$ when $x$ is not zero. If the numerator is 0 and the -% denominator not, we do nothing as $z$ was initialized to be 0. +% We invoke an error message upon division by $0$, but nevertheless return +% a value. By default it is $0$ for $0/0$ and the maximum possible real +% for $x/0$ when $x$ is not $0$. If the numerator is $0$ and the +% denominator not, we do nothing as $z$ was initialized to be $0$. % -% If neither is 0, we calculate the sign of the result and call +% If neither is $0$, we calculate the sign of the result and call % \cs{MFP@@Rdiv} to divide the absolute values. % \begin{macrocode} \def\MFP@Rdiv{% @@ -2106,7 +2106,7 @@ % but knowing the shift will give us the correct quotient in the end. % % We first arrange that \cs{MFP@y@Int} is nonzero by making it \cs{MFP@y@Frc} if -% it is zero (a shift of eight digits). Then the macro +% it is $0$ (a shift of eight digits). Then the macro % \cs{MFP@numdigits@toshift} computes $8$ minus the number of digits in % \cs{MFP@y@Int}, which is how many positions left $y$ will be shifted. % We then call \cs{MFP@doshift@y} on the concatenation of the digits in @@ -2180,7 +2180,7 @@ % % If \arg1 of \cs{MFP@numdigits@toshift}, has $n$ digits then % \cs{MFP@numdigits@toshift} picks out the value $8-n$. \cs{MFP@doshift@x} -% reads the first eight digits into \cs{MFP@x@Int} and then pulls out 8 more +% reads the first eight digits into \cs{MFP@x@Int} and then pulls out eight more % from the rest (\arg9) inside \cs{MFP@x@Frc}. The same with % \cs{MFP@doshift@y}. % \begin{macrocode} @@ -2328,7 +2328,7 @@ % % The macro \cs{MFPget@Intdigits} should have exactly 17 digits following it. % It puts eight of them in \cs{MFP@z@Int}, then calls \cs{MFPget@Frcdigits} to -% read the fractional part. That requires exactly 9 digits follow it, +% read the fractional part. That requires exactly nine digits follow it, % putting eight in \cs{MFP@z@Frc} and the last in \cs{MFP@z@Und}. Still, to % allow a graceful exit should there be more, we gobble the rest of the % digits. @@ -2450,10 +2450,10 @@ % % \DescribeMacro{\MFPstrip} % Stripping zeros from the right end of the fractional part. The star form -% differs only in the handling of a zero fractional part. So we check -% whether it is zero and when it is, we either append `\texttt{.0}' or +% differs only in the handling of a $0$ fractional part. So we check +% whether it is $0$ and when it is, we either append `\texttt{.0}' or % nothing. The rest of the code grabs a digit at a time and stops when the -% rest are zero. +% rest are $0$. % \begin{macrocode} \def\MFPstrip{% \@ifstar{\MFP@strip{}}{\MFP@strip{.0}}}% @@ -2647,7 +2647,7 @@ % % \DescribeMacro{\LogOfZeroInt} % \DescribeMacro{\LogOfZeroFrac} -% Trying to take the logarithm of 0 will result in an error message. +% Trying to take the logarithm of $0$ will result in an error message. % If one allows \TeX{} to continue, the returned value will be negative, % with an integer part equal to the contents of \cs{LogOfZeroInt} and a % fractional part equal to the contents of \cs{LogOfZeroFrac}. The @@ -2766,7 +2766,7 @@ % % Our degree/radian conversions try to be more accurate than a simple % multiplication by $57.2957 7951$ or $0.0174 5329$. These conversion -% factors are accurate to only 8 digits, and the rounding error is +% factors are accurate to only eight digits, and the rounding error is % magnified by multiplication. Thus we will use 16 digits for these % constants. That is, we multiply first by $57.2957 7951$, then by the % next eight digits ($.30823208\times 10^{-8}$), performing the ``${}\times @@ -2794,16 +2794,16 @@ \MFP@Rcopy sy\MFP@Radd}% % \end{macrocode} % -% There are very few angles that are expressible in 8 digits whose sine -% or cosine can be expressed exactly in 8 digits. For these, we do obtain +% There are very few angles that are expressible in eight digits whose sine +% or cosine can be expressed exactly in eight digits. For these, we do obtain % an exact result. Other values produce inexact results. It would be nice -% if we could at least obtain these correctly rounded to 8 decimals, but -% unfortunately our methods will often produce a result off by 1 in the +% if we could at least obtain these correctly rounded to eight decimals, but +% unfortunately our methods will often produce a result off by $1$ in the % eighth decimal from the correctly rounded value. Anything that % involves the addition of two or more rounded results can have this % problem. The only way to get correctly rounded results is to carry out % all operations internally to additional places. Even then, there will be -% the occasional $.4999\dots$ that should round to 0 but rounds to 1 +% the occasional $.4999\dots$ that should round to $0$ but rounds to $1$ % instead. % % For the cosine, just compute $\sin(90-x)$. @@ -2889,7 +2889,7 @@ % and correspondingly increasing the appropriate factors. Since the % number of significant figures of a product is limited by the least % number of significant figures of the two factors, the bottleneck on -% accuracy is that of the smaller term: all our numbers have 8 digits +% accuracy is that of the smaller term: all our numbers have eight digits % so if a number is small, the number of nonzero digits is small. % % Dividing by 100 seems a good choice (so our units are @@ -2900,41 +2900,64 @@ % computations amount to concatenating the top six digits of % \cs{MFP@tempb} to the digits of \cs{MFP@tempa}. This will produce the % integer form of the fractional part of $x/100$ (the integer part of -% $x/100$ is 0). +% $x/100$ is $0$). +% +% Division by $100$ can turn a number into $0$. This is one place we can +% lose accuracy in the last digit of the result. In compensation, the rest +% of the calculations become extremely accurate. % \begin{macrocode} - \advance\MFP@tempb 50 - \divide\MFP@tempb 100 - \multiply\MFP@tempa 1000000 - \advance\MFP@tempb\MFP@tempa - \MFP@Rsin@prog - \fi}% + \advance\MFP@tempb 50 \divide\MFP@tempb 100 + \multiply\MFP@tempa 1000000 \advance\MFP@tempb\MFP@tempa + \ifnum\MFP@tempb=0 + \MFP@Rzero + \else % \end{macrocode} % -% \cs{MFP@Rsin@prog} is the power series computation. We save some -% multiplications by working with $t=x^2$. As we don't need the original -% $x$ anymore, we simply replace it with the new reduced value. We also -% save this $x$ in another register, \texttt{s}, as we will need it again -% at the end, and our intermediate calculations do not preserve the -% \texttt{x} register. Then we square $x$ and save it in another temporary -% register \texttt{t}: +% We save some multiplications by working with $t=x^2$. As we don't need +% the original $x$ anymore, we simply replace it with the newly reduced +% value. We also save this reduced $x$ in another register, \texttt{s}, as +% we will need it again at the end, and our intermediate calculations do +% not preserve the \texttt{x} register. Then we square $x$ and, if that +% square is $0$ we can skip all the power series and simply return $x$ +% converted to radians (that's the last multiplication). If $x^2$ is not +% $0$, we save it in temporary register \texttt{t} and call our power +% series. When this program is finished, all that remains is a final +% multiplication by a conversion factor\dots +% \begin{macrocode} + \MFP@Rload x10\MFP@tempb + \MFP@Rcopy xs% + \MFP@Rsq + \ifnum \MFP@z@Frc>0 + \MFP@Rcopyz t\MFP@Rsin@prog + \else + \MFP@Rcopy sx% + \fi + \MFP@Rload y11{74532925}\MFP@Rmul +% \end{macrocode} +% \dots except this fiddle about the sign. Theoretically, all cases +% where $\sin x$ can be $0$ were previously weeded out. However, I am not +% 100 percent certain that rounding in \cs{MFP@Rsin@prog} will never +% lead to a value of $0$. % \begin{macrocode} -\def\MFP@Rsin@prog{% - \MFP@Rload x10\MFP@tempb - \MFP@Rcopy xs% - \MFP@Rsq - \MFP@Rcopyz t% + \ifnum\MFP@z@Sgn=0 \else + \let\MFP@z@Sgn\MFP@sin@Sgn + \fi + \fi + \fi}% % \end{macrocode} % -% The power series need only go to 8 terms as the ninth would be less than -% $.5*10^{-8}$ and so our 8-place computations would return $0$. Our -% 8-term series is: +% \cs{MFP@Rsin@prog} is the power series computation. The power series +% need only go to eight terms as the ninth would be less than $.5*10^{-8}$ and +% so our 8-place computations would return $0$. Our 8-term series is: % $$ % rx(1 - r^2t/3! + r^4t^2/5! - r^6t^3/7! + r^8t^4/9! - r^{10}t^5/11! + % r^{12}t^6/13! - r^{14}t^7/15!) % $$ % where $r$ is the factor that converts $x$ to radian measure -% (hectodegrees to radians). We minimize any multiplications of tiny -% numbers by computing this as +% (hectodegrees to radians). When $x$ is so small as to produce $t = 0$ we +% have skipped all this. +% +% We minimize any multiplications of tiny numbers by computing this as % $$ % r(1 - gt(1 - ft(1 - et(1 - dt(1 - ct(1 - bt(1 - at))))))). % $$ @@ -2949,13 +2972,13 @@ % from the previous one (e.g., if $u = t^3/7!$ is the fourth term, the next % one is $u*t*(1/(8*9))$). This is a bit more complicated to code and requires % moving values around more. It would have the advantage that we can stop -% whenever a term evaluates to 0, making computation faster for small +% whenever a term evaluates to $0$, making computation faster for small % values of $x$. % % We avoid divisions by precomputing the coefficients $a$, $b$, $c$, etc. % Note that without the reduction in $x$, the value of $a$ for example -% would be $0.00000145$, with only 3 significant figures of accuracy. -% Now we can have 7, and the accuracy is more-or-less determined by that +% would be $0.00000145$, with only three significant figures of accuracy. +% Now we can have seven, and the accuracy is more-or-less determined by that % of the reduced x. % $$ % \vcenter{\centering @@ -2974,8 +2997,11 @@ % % The macro \cs{MFP@com@iter} `flips' the previous result then multiplies % by $t$ and the indicated coefficient. (The name of this macro stands for -% ``common iterated'' code; it is reused for other power series -% computations.) +% ``common iterated'' code; it is reused for some other power series.) +% +% For extra efficiency, the power series uses a ``small'' version of +% multiplication \cs{MFP@Rsmul}, used only when the factors are sure to +% lie in $[0,1]$. % % Despite what I said above, our chosen method of computation has a % slightly improved accuracy (in numerical experiments) if we take it one @@ -2984,23 +3010,18 @@ % It has provably better worst-case accuracy, but on average, who knows? % We are right at the edge of our 8-digit accuracy anyway. The constant % \texttt{00559959} corresponds to half of $r^2/16/17$. -% -% For extra efficiency I am using a ``small'' version of multiplication -% \cs{MFP@Rsmul}, used only when the multiplicands are sure to lie in -% $[0,1]$. % \begin{macrocode} +\def\MFP@Rsin@prog{% \MFP@Rcopy tx% \MFP@Rload y10{00559959}\MFP@Rsmul\MFP@com@iter{01450559}% \MFP@com@iter{01952675}\MFP@com@iter{02769249}\MFP@com@iter{04230797}% \MFP@com@iter{07252796}\MFP@com@iter{15230871}\MFP@com@iter{50769570}% - \MFP@flipz\MFP@Rcopyzx\MFP@Rcopy sy\MFP@Rsmul - \MFP@Rcopyzx\MFP@Rload y11{74532925}\MFP@Rmul - \let\MFP@z@Sgn\MFP@sin@Sgn}% + \MFP@flipz \MFP@Rcopyzx \MFP@Rcopy sy\MFP@Rsmul \MFP@Rcopyzx}% \def\MFP@flipz{% \ifnum\MFP@z@Sgn=0 \MFP@Rloadz 110% \else - \MFP@tempa\MFP@ttteight % representing 1.00000000 + \MFP@tempa\MFP@ttteight \advance\MFP@tempa-\MFP@z@Frc\relax \MFP@Rloadz{\ifcase\MFP@tempa 0\else1\fi}0\MFP@tempa \fi}% @@ -3011,7 +3032,7 @@ % % As to the accuracy of these computations, we can certainly lose accuracy % at each step. In principle, if $x$ is known to 10 significant figures -% ($x \ge 10$~degrees), then even though we lose 2 figures with division +% ($x \ge 10$~degrees), then even though we lose two figures with division % by 100, the accuracy bottleneck is the fact that our coefficients have % only seven figures. Now we have 17 multiplications, and while products % are said to have the same number of significant figures as the factors, @@ -3021,26 +3042,26 @@ % isn't that bad, probably because the direction of inaccuracies usually % varies randomly, and inaccuracies in one direction compensate for those % going the other way. I have not seen a case where the result is off by -% more than 1 in the last decimal place (i.e., $\pm 1.5\times 10^{-8}$). +% more than $1$ in the last decimal place (i.e., $\pm 1.5\times 10^{-8}$). % In the case where we can know the result exactly, $x=30$, we get an -% exact answer, even though we don't single it out (as we do 0, 90 and -% 180). +% exact answer, even though we don't single it out (as we do $0$, $90$ and +% $180$). % % The following is the ``small'' version of \cs{MFP@Rmul}. Limited to -% non-negative numbers less than or equal to 1. Theoretically all the +% non-negative numbers less than or equal to $1$. Theoretically all the % numbers are strictly between $0$ and $1$, but in practice a % multiplication could round to $0$ and then, after subtraction, a $1$ % could occur. We handle those easy cases separately, so that in -% \cs{MFP@@Rsmul} we don't have to wory about the integer parts at all. +% \cs{MFP@@Rsmul} we don't have to worry about the integer parts at all. % \begin{macrocode} \def\MFP@Rsmul{% \ifnum \MFP@x@Sgn=0 \MFP@Rzero \else\ifnum \MFP@y@Sgn=0 \MFP@Rzero - \else\ifnum\MFP@x@Int>0 % x must be 1.0 + \else\ifnum\MFP@x@Int>0 \MFP@Rcopy yz% - \else\ifnum\MFP@y@Int>0 % y must be 1.0 + \else\ifnum\MFP@y@Int>0 \MFP@Rcopy xz% \else \MFP@@Rsmul @@ -3081,12 +3102,6 @@ % the two coordinates of a point and computes its angle in polar % coordinates. One then has, for example, $\arctan x = % \mathop{\rm angle}(1,x)$ and $\arccos x = \angle(x, \sqrt{1-x^2})$. -% The latter could be obtain in a program by: -% \begin{verbatim} -% \Rpush\X \Rdup -% \Rsq \Rchs -% \Rincr \Rsqrt -% \Rangle \end{verbatim} % % We start, as usual, with a few reductions. When the $y$-part is $0$, we % immediately return $0$ or $180$. If the $y$-part is negative, we compute @@ -3162,7 +3177,7 @@ % To get the accuracy we need we work in ``scaled reals''. That is, we % get 10 decimal places of accuracy by letting two digits of the integer % part represent the first two digits after the decimal point, and the -% 8 digits of the fractional part represent digits 3 through 10 after the +% eight digits of the fractional part represent digits 3 through 10 after the % point. The macro \cs{MFP@RmulC} (around line 19 of the definition of % \cs{MFP@@@Rangle}) is a quick multiplication by 100, converting the % argument of the arctangent command to a scaled real. @@ -3211,7 +3226,7 @@ % \end{macrocode} % % Here are fast multiplication and division by 100. We need these because -% we are going to comput the arctangent in radians to ten decimal places. +% we are going to compute the arctangent in radians to ten decimal places. % We do this by computing with scaled reals in which, for example, $0.5$ % is represented by $50.0$. When we do this, multiplication requires a % division by 100: $.5\times.5 = .25$ would be computed as $(50\times50) / @@ -3244,7 +3259,7 @@ % around $0.25$ (represented by $25.0$), we have to sum to at least its % $15$th power ($4^{-15}/15 \approx .6\times 10^{-10}$ and the next term % in the series is effectively $0$). Fortunately, the power series has -% only odd terms, so there are only 8 terms we actually need to calculate. +% only odd terms, so there are only eight terms we actually need to calculate. % The calculation proceeds much like the one for the sine, starting with % the sum % $$ @@ -3282,9 +3297,9 @@ % Now for logarithms. We are going to compute a base 10 logarithm. This % allows the first step of the calculation to be essentially trivial: to % get the integer part of the log for numbers with positive integer part, -% count the digits in the integer part and subtract 1. For numbers less +% count the digits in the integer part and subtract $1$. For numbers less % than one, count the number of zeros at the beginning of the fractional -% part and add 1 (subtract this from the result of the second part). This +% part and add $1$ (subtract this from the result of the second part). This % reduces the problem to numbers $1 \le x < 10$. A few divisions (when % necessary) reduce to the case where $x = 1 + u$ with $u$ small enough % that the power series for $\log (1 + u)$ can be computed accurately in @@ -3307,7 +3322,7 @@ \MFP@Rload s000% % \end{macrocode} % -% If the integer part is zero, the fractional part is not. Save the +% If the integer part is $0$, the fractional part is not. Save the % number of places that will be shifted in \cs{MFP@tempa}. We use % \cs{number} to strip the leading zeros and (essentially) we count % the number of digits that remain. Then we shift left, putting the first @@ -3325,7 +3340,7 @@ \MFPpadto@eight\MFP@t@Frc \else % \end{macrocode} -% When the integer part is not zero, we get the number of digits to +% When the integer part is not $0$, we get the number of digits to % shift again in \cs{MFP@tempa}. We actually want one less than the % number of digits, so that is what \cs{MFP@numdigits} actually produces. % \begin{macrocode} @@ -3341,7 +3356,7 @@ % The integer part of $\log x$ is now known, so save it in value-so-far. % Also, set the sign of the reduced argument to positive. Then call % \cs{MFP@log@reduce}, which reduces $x$ to at most $10^{1/16} \approx -% 1.155\,$. Finally, if the reduced $x$ is 1, return the value so far, +% 1.155\,$. Finally, if the reduced $x$ is $1$, return the value so far, % otherwise call the power series program. % \begin{macrocode} \edef\MFP@s@Int{\number\MFP@tempa}% @@ -3396,8 +3411,8 @@ % \log (1 + u) = \frac{1}{\ln 10} \sum_{n=0}^\infty (-1)^n \frac{u^{n+1}}{n+1}. % $$ % We only need to carry it far enough to assure that the next term would -% be 0 in our finite resolution arithmetic, that is $.155^{k}/k/\ln10 < .5\times -% 10^{-8}$. This is satisfied by $k=9$, so we only need 8 terms. +% be $0$ in our finite resolution arithmetic, that is $.155^{k}/k/\ln10 < .5\times +% 10^{-8}$. This is satisfied by $k=9$, so we only need eight terms. % % Again, we compute this by % $$ @@ -3424,7 +3439,7 @@ % % \subsection{Powers} % -% With the exponential function we immediately return 1 if $x=0$. We +% With the exponential function we immediately return $1$ if $x=0$. We % call two separate handlers for positive and negative $x$. This is % because the issues are different between positive and negative % exponents. @@ -3436,7 +3451,7 @@ \MFP@Rexp@pos \else \def\MFP@x@Sgn{1}% - \MFP@Rexp@neg % computes e^{-x}, not e^x + \MFP@Rexp@neg \fi}% % \end{macrocode} % @@ -3445,8 +3460,9 @@ % overflow is $18.42068074$ so we first compare to that; if larger, % issue the error message and return $99999999.99999999$. % -% We compute the integer power first, using an \cs{ifcase}, because -% there are only 19 cases to consider. +% We compute the integer power first, using an \cs{ifcase}. Because there +% are only 19 cases to consider a table lookup is faster than +% multiplications. % % Then, we examine the first digit $d$ after the decimal and compute % $e^{0.d}$, again by cases. This is multiplied by the integer power @@ -3513,8 +3529,8 @@ \fi}% % \end{macrocode} % -% Since the $x$ value is now less than $0.1$, we can get 8 places of -% accuracy with only 6 terms of the power series. We can also arrange to +% Since the $x$ value is now less than $0.1$, we can get eight places of +% accuracy with only six terms of the power series. We can also arrange to % use the more efficient \cs{MFP@Rsmul} for multiplication. % % We organize the computation thusly @@ -3525,7 +3541,7 @@ % \texttt{z}, then repeatedly run \cs{MFP@Rexp@iter} feeding it the % successive values of $1/n$. This iterator first multiplies the most % recent result (the \texttt{z} register) by $1/n$, then that by $x$ and -% then adds $x$ to that. The final step is to add 1. +% then adds $x$ to that. The final step is to add $1$. % \begin{macrocode} \def\MFP@Rexp@pos@prog{% \MFP@Rcopy tz\MFP@Rexp@iter{16666667}\MFP@Rexp@iter{20000000}% @@ -3541,15 +3557,15 @@ % in $e^x$, That is, knowing $x$ only to $10^{-8}$ means $e^x$ is off by % (about) $e^x\cdot 10^{-8}$. Roughly speaking, this means only about $8$ % places of $e^x$ are accurate, so if the integer part of $e^x$ has six -% places then only 2 places after the decimal are significant. Even if -% $x$ is exact (say $x=10$), we can only represent $e$ itself to 8 -% decimals and the repeated multiplications accumulate errors in such a -% way that one still cannot get more than 8 significant figures. +% places then only two places after the decimal are significant. Even if +% $x$ is exact, we can only represent $e$ itself to eight decimals and the +% repeated multiplications accumulate errors in such a way that one still +% cannot get more than eight significant figures. % % \bigskip % The first issue with negative exponents is that it doesn't take much to -% produce a value of $e^{-x}$ that rounds to 0. Any $x > 19.11382792$. So -% we start by comparing to that value and simply return 0 if $x$ is +% produce a value of $e^{-x}$ that rounds to $0$. Any $x > 19.11382792$. So +% we start by comparing to that value and simply return $0$ if $x$ is % larger. % % We perform exactly the same reductions as for positive exponents, @@ -3624,7 +3640,7 @@ % Since this has exactly the same form as the the power series calculation % for $\log$ and $\sin$, we can reuse the code in \cs{MFP@com@iter}. We % end with the final multiplication by $x$ and the subtraction from 1 -% rather than call \cs{MFP@com@iter} with a useless multiplication by 1. +% rather than call \cs{MFP@com@iter} with a useless multiplication by $1$. % \begin{macrocode} \def\MFP@Rexp@neg@prog{% \MFP@Rcopy tx\MFP@Rload y10{16666667}\MFP@Rsmul @@ -3671,13 +3687,13 @@ \MFP@msgbreak The fractional part will be ignored}% \fi \MFP@loopctr=\MFP@y@Int\relax - \ifnum\MFP@loopctr=0 % zero power = 1 + \ifnum\MFP@loopctr=0 \MFP@Rloadz 110% \else \ifnum\MFP@x@Sgn=0 - \ifnum\MFP@y@Sgn>0 % + powers of zero are 0 + \ifnum\MFP@y@Sgn>0 \MFP@Rloadz 000% - \else % - powers are errors + \else \MFP@badpower@err \MFP@Rloadz 1\xOverZeroInt\xOverZeroFrac \fi @@ -3762,14 +3778,14 @@ % $\sqrt{9} = 3$. In fact, if a square root can be expressed exactly % within our 8-digit precision, our code will find it. % -% For the square root we return 0 if $x$ is not positive. If the integer +% For the square root we return $0$ if $x$ is not positive. If the integer % part of $x$ is $0$, we copy the fractional part to the integer part % (that is, we multiply by $10^{8}$, remembering to multiply by $10^{-4}$ % later). This makes the square root of such numbers slightly more % accurate. We then compute the square root using an algorithm that will % be exact whenever possible. We perform one additional processing step. % To explain it, note that our algorithm actually produces the largest -% number $s$ with 4 digits right of the decimal place that satisfies $s^2 +% number $s$ with four digits right of the decimal place that satisfies $s^2 % \le x$. That is % $$ % s^2 \le x < \left( s + 10^{-4} \right)^2 @@ -3790,7 +3806,7 @@ % % I originally tried power series methods, but they failed to produce % exact answers when they existed (unless they were inconveniently carried -% to 9 decimals and then rounded to 8). Then I tried the ``exact when +% to nine decimals and then rounded to eight). Then I tried the ``exact when % possible'' algorithm to get $s$, but correcting it as follows: find % $\sqrt{x/s^2}$ by power series and multiply by $s$. But this turned out % to be remarkably inaccurate, being paradoxically worst when $s$ is @@ -3842,12 +3858,12 @@ % The process turns out to be simpler if we convert $10^8 x$ to base 4 % rather than binary. Also, instead of producing the square root encoded % in a string of binary digits, we simply build the numerical result as we -% discover the binary digits (multiply previous value by 2 and add the +% discover the binary digits (multiply previous value by two and add the % new digit.) Fortunately, the square root of $10^8 x$ (and the % temporary scratch registers used in the code) will never exceed \TeX{}'s % limit for integers. % -% The macro \cs{MFP@ItoQ} implements the conversion to base 4 digits. +% The macro \cs{MFP@ItoQ} implements the conversion to base-4 digits. % The two arguments are the integer and fractional part of $x$. The % result is stored in \cs{MFP@ItoQ@Tmp}, which is so far only used by the % square root code. @@ -3856,9 +3872,9 @@ % Combining two of them yields the quadrenary digits. The % \cs{ifodd}\cs{MFP@tempa} tests are there to check whether there % will be a remainder after division by $2$, which should then be -% inserted at the front of \cs{MFP@tempb} before division by 2. Two -% divisions by 2 each iteration amounts to division by 4. This is slightly -% more efficient than dividing by 4 and determining the remainder. +% inserted at the front of \cs{MFP@tempb} before division by $2$. Two +% divisions by $2$ each iteration amounts to division by $4$. This is slightly +% more efficient than dividing by $4$ and determining the remainder. % \begin{macrocode} \def\MFP@ItoQ#1#2{% \MFP@tempa#1\relax\MFP@tempb#2\relax @@ -3883,7 +3899,7 @@ % \end{macrocode} % % This integer square root $n$ is $10^4$ times the largest number $y$ -% satisfying $y^2 \le x$ and having at most 4 decimal places. The rest of +% satisfying $y^2 \le x$ and having at most four decimal places. The rest of % the code after the \cs{MFP@Isqrt@loop} is intended to divide $n$ % (returned in \cs{MFP@tempc}) by $10^4$ in order to get the number $y$ % itself. @@ -3905,9 +3921,8 @@ % % The following is a loop that essentially performs a base-2 version of % the base-10 algorithm that I learned at age 12 from my father -% (apparently it was taught in 8th or 9th grade in his day: he never -% finished grade 9). Seeing it written out, I am surprise at how concise -% and elegant it is! +% (apparently it was taught in eighth or ninth grade in his day). Seeing +% it written out, I am surprise at how concise and elegant it is! % \begin{macrocode} \def\MFP@Isqrt@loop#1{% \ifx\mfp@end #1% @@ -3930,7 +3945,7 @@ % \cs{MFP@tempb}, but only if the last digit is a 1. Then the next % quadrenary digit is appended to \cs{MFP@tempb}. Finally, the last binary % digit found is added (not appended) to \cs{MFP@tempa}. The ``appending'' -% of a digit means a multiplication by 2 (or 4) and the addition of the +% of a digit means a multiplication by $2$ (or $4$) and the addition of the % digit. We perform such additions only if the digit is a 1, and we % determine if the digit is 1 or 0 by the \cs{ifnum} test. %\Finale diff --git a/Master/texmf-dist/tex/generic/minifp/mfpextra.tex b/Master/texmf-dist/tex/generic/minifp/mfpextra.tex index 7d541bd4747..2e9a6d88bf0 100644 --- a/Master/texmf-dist/tex/generic/minifp/mfpextra.tex +++ b/Master/texmf-dist/tex/generic/minifp/mfpextra.tex @@ -124,29 +124,36 @@ \ifnum\MFP@tempa=90 \MFP@Rloadz \MFP@sin@Sgn10% \else - \advance\MFP@tempb 50 - \divide\MFP@tempb 100 - \multiply\MFP@tempa 1000000 - \advance\MFP@tempb\MFP@tempa - \MFP@Rsin@prog + \advance\MFP@tempb 50 \divide\MFP@tempb 100 + \multiply\MFP@tempa 1000000 \advance\MFP@tempb\MFP@tempa + \ifnum\MFP@tempb=0 + \MFP@Rzero + \else + \MFP@Rload x10\MFP@tempb + \MFP@Rcopy xs% + \MFP@Rsq + \ifnum \MFP@z@Frc>0 + \MFP@Rcopyz t\MFP@Rsin@prog + \else + \MFP@Rcopy sx% + \fi + \MFP@Rload y11{74532925}\MFP@Rmul + \ifnum\MFP@z@Sgn=0 \else + \let\MFP@z@Sgn\MFP@sin@Sgn + \fi + \fi \fi}% \def\MFP@Rsin@prog{% - \MFP@Rload x10\MFP@tempb - \MFP@Rcopy xs% - \MFP@Rsq - \MFP@Rcopyz t% \MFP@Rcopy tx% \MFP@Rload y10{00559959}\MFP@Rsmul\MFP@com@iter{01450559}% \MFP@com@iter{01952675}\MFP@com@iter{02769249}\MFP@com@iter{04230797}% \MFP@com@iter{07252796}\MFP@com@iter{15230871}\MFP@com@iter{50769570}% - \MFP@flipz\MFP@Rcopyzx\MFP@Rcopy sy\MFP@Rsmul - \MFP@Rcopyzx\MFP@Rload y11{74532925}\MFP@Rmul - \let\MFP@z@Sgn\MFP@sin@Sgn}% + \MFP@flipz \MFP@Rcopyzx \MFP@Rcopy sy\MFP@Rsmul \MFP@Rcopyzx}% \def\MFP@flipz{% \ifnum\MFP@z@Sgn=0 \MFP@Rloadz 110% \else - \MFP@tempa\MFP@ttteight % representing 1.00000000 + \MFP@tempa\MFP@ttteight \advance\MFP@tempa-\MFP@z@Frc\relax \MFP@Rloadz{\ifcase\MFP@tempa 0\else1\fi}0\MFP@tempa \fi}% @@ -158,9 +165,9 @@ \MFP@Rzero \else\ifnum \MFP@y@Sgn=0 \MFP@Rzero - \else\ifnum\MFP@x@Int>0 % x must be 1.0 + \else\ifnum\MFP@x@Int>0 \MFP@Rcopy yz% - \else\ifnum\MFP@y@Int>0 % y must be 1.0 + \else\ifnum\MFP@y@Int>0 \MFP@Rcopy xz% \else \MFP@@Rsmul @@ -370,7 +377,7 @@ \MFP@Rexp@pos \else \def\MFP@x@Sgn{1}% - \MFP@Rexp@neg % computes e^{-x}, not e^x + \MFP@Rexp@neg \fi}% \def\MFP@Rexp@pos{% \MFP@Rload y1{18}{42068074}\MFP@Rcmp @@ -506,13 +513,13 @@ \MFP@msgbreak The fractional part will be ignored}% \fi \MFP@loopctr=\MFP@y@Int\relax - \ifnum\MFP@loopctr=0 % zero power = 1 + \ifnum\MFP@loopctr=0 \MFP@Rloadz 110% \else \ifnum\MFP@x@Sgn=0 - \ifnum\MFP@y@Sgn>0 % + powers of zero are 0 + \ifnum\MFP@y@Sgn>0 \MFP@Rloadz 000% - \else % - powers are errors + \else \MFP@badpower@err \MFP@Rloadz 1\xOverZeroInt\xOverZeroFrac \fi diff --git a/Master/texmf-dist/tex/generic/minifp/minifp.sty b/Master/texmf-dist/tex/generic/minifp/minifp.sty index 21462ece64f..321ec4197f1 100644 --- a/Master/texmf-dist/tex/generic/minifp/minifp.sty +++ b/Master/texmf-dist/tex/generic/minifp/minifp.sty @@ -21,8 +21,8 @@ %% is Daniel H. Luecking. The Base Interpreters associated %% with minifp are plain TeX and LaTeX. %% -\def\MFPfiledate{2013/01/01}% -\def\MFPfileversion{0.9}% +\def\MFPfiledate{2013/02/01}% +\def\MFPfileversion{0.92}% \expandafter \ifx \csname MFP@finish\endcsname\relax \else \expandafter\endinput \fi @@ -144,7 +144,7 @@ \errmessage{MiniFP error: #1}% \endgroup}% \def\MFP@popempty@err{% - \MFP@errmsg{cannot pop from an empty stack}% + \MFP@errmsg{cannot POP from an empty stack}% {There were no items on the stack for the POP operation. % If you continue, ^^Jthe macro will contain the % value \EndofStack.}}% @@ -387,7 +387,7 @@ \advance\MFP@tempa1 \fi \fi - \MFP@Rloadz{\ifnum\MFP@z@Int=0 0\else\MFP@x@Sgn\fi}\MFP@tempa0}% + \MFP@Rloadz{\ifnum\MFP@x@Int=0 0\else\MFP@x@Sgn\fi}\MFP@tempa0}% \def\MFP@Rfloor{\MFP@Rfloororceil>}% \def\MFP@Rceil {\MFP@Rfloororceil<}% \def\MFP@split#1#2#3{% -- cgit v1.2.3