diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/splint/tex/xarithm.sty |
Initial commit
Diffstat (limited to 'support/splint/tex/xarithm.sty')
-rw-r--r-- | support/splint/tex/xarithm.sty | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/support/splint/tex/xarithm.sty b/support/splint/tex/xarithm.sty new file mode 100644 index 0000000000..4d424a863c --- /dev/null +++ b/support/splint/tex/xarithm.sty @@ -0,0 +1,317 @@ +% Copyright 2014, Alexander Shibakov +% This file is part of SPLinT +% +% SPLinT is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% SPLinT is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with SPLinT. If not, see <http://www.gnu.org/licenses/>. + +% a minimum of expandable arithmetic to implement a few macros in yyparse.sty and flex.sty +% the goal of these macros was not implementing a complete +% integer arithmetic but rather providing the minimal functionality +% where such arithmetic is required. +% there are a few instances in which the utility of such arithmetic is +% beneficial: +% o whenever an `expession macro' should behave like a number (i.e. be +% useful in a \number context); see \YYSTART implementation for an +% example +% o whenever the use of a register is to be avoided in iterative +% macros and replaced by a `tail parameter' (see \yyless for a hint +% of such a use) +% o whenever \TeX's number size limitations are inadequate +% +% the last situation has not been a concern for this package while the +% other two were. +% +% `expandable' may have different meanings. in the context of +% arithmetic, expansion within \edef context, `prefix expansion' or +% \number or \romannumeral0 context expansion may all be valid +% targets. the preferred way seems to be the \romannumeral0 +% interface. the disadvantage of this method is that each macro needs +% to produce a space at the end of its `expansion cycle', the +% advantage is the ability to carry the extension for arbitrarily +% large numbers (unlike, say, the \number interface). the macros below +% are implemented so that the \expandafter\expandafter `prefix' +% expansion and \number both work, even though internally, the +% \romannumeral0 approach is taken. this is done to present a cleaner +% use pattern to the consumer of the macros. +% +% for a complete implementation of expandable arithmetic (including +% floating point), see the corresponding parts of the +% \LaTeX\ project. it was decided against using that implementation to +% avoid creating dependencies. + +% temporary definition, to avoid using reserved counters + +\edef\xxcarry{\count3=\the\count3\count\z@\the\count\z@\count\@ne\the\count\@ne} + +% digit extractor, used as part of several macros below. + +\count\z@\z@ +\bloop + \edef\next{\def\csname digit\number\count\z@\endcsname##1\number\count\z@##2##3.{##2}}\next % +\ifnum9>\count\z@ + \advance\count\z@\@ne +\repeat + +% multiplication tables: +% \xmultby?#1 expands into a pair ab which is a product of ? and #1 + +\count\z@\z@ +\bloop{% + \count\@ne\z@ + \let\next\empty + \bloop + \count3\count\z@ + \multiply\count3\count\@ne + \edef\next{\next\number\count\@ne{\ifnum9<\count3 \else0\fi\number\count3}}% + \ifnum9>\count\@ne + \advance\count\@ne\@ne + \repeat + \edef\next{\def\csname xmultby\number\count\z@\endcsname##1{\noexpand\csname digit##1\noexpand\endcsname\next.}}\next +\ifnum9>\count\z@ + \advance\count\z@\@ne +}\repeat + +% addition tables: +% \xaddto?#1 expands into a pair ab which is a sum of ? and #1 + +\count\z@\z@ +\bloop{% + \count\@ne\z@ + \let\next\empty + \bloop + \count3\count\z@ + \advance\count3\count\@ne + \edef\next{\next\number\count\@ne{\ifnum9<\count3 \else0\fi\number\count3}}% + \ifnum9>\count\@ne + \advance\count\@ne\@ne + \repeat + \edef\next{\def\csname xaddto\number\count\z@\endcsname##1{\noexpand\csname digit##1\noexpand\endcsname\next.}}\next +\ifnum9>\count\z@ + \advance\count\z@\@ne +}\repeat + +% division tables: +% \xdivby?#1 expands into #1 div ? + +\count\z@\@ne +\bloop{% + \count\@ne\z@ + \let\next\empty + \bloop + \count3\count\@ne + \divide\count3\count\z@ + \edef\next{\next\number\count\@ne{\number\count3}}% + \ifnum9>\count\@ne + \advance\count\@ne\@ne + \repeat + \edef\next{\def\csname xdivby\number\count\z@\endcsname##1{\noexpand\csname digit##1\noexpand\endcsname\next.}}\next +\ifnum9>\count\z@ + \advance\count\z@\@ne +}\repeat + +\xxcarry % restore registers + +% #1\times #2 + #3 + +\def\xxcarry#1#2#3{% + \expandafter\x@carry\number1\csname xmultby#1\endcsname#2#3% +} + +% #1 is a bogus parameter, so that a leading 0 is not dropped by \number + +\def\x@carry#1#2#3#4{% + \expandafter\x@@arry\number1\csname xaddto#3\endcsname#4#2% +} + +\def\x@@arry#1#2#3#4{% + \ifnum#2>\z@\number\csname xaddto#2\endcsname#4\else#4\fi#3% +} + +% most macros internally consume the digits from left to right. + +\def\xreverse#1{% + \romannumeral0\xr@verse{}#1.% +} + +\def\xr@verse#1#2{% + \if#2.% + \yybreak{ #1}% + \else + \yybreak{\xr@verse{#2#1}}% + \yycontinue +} + +% multiplication by 0-9 +% #1 is the number +% #2 is the digit +% expands to #1 * #2 in reverse digid order + +\def\xmultiplybydigit#1#2{% + \romannumeral0\xbydigit{#2}{0}{}#1.% +} + +% #1 is the digit +% #2 is the carry +% #3 is the result +% #4 is the next digit of the big factor + +\def\xbydigit#1#2#3#4{% + \if#4.% + \yybreak{\ifnum#2=\z@\xskiptofi{ #3}\else\xskiptofi{ #3#2}\fi}% + \else + \yybreak{\expandafter\xb@digit\number1#1\xxcarry#1#4#2 {#3}}% + \yycontinue +} + +% #1 is a bogus parameter (see above) +% #2 is the digit +% #3 is the carry +% #4 is the next digit of the result +% #5 is the result up to now + +\def\xb@digit#1#2#3#4#5{% + \xbydigit#2#3{#5#4}% +} + +% a version of the macros above that perform the reversion to save an +% extra step + +% #1 is the digit +% #2 is the carry +% #3 is the result +% #4 is the next digit of the big factor + +\def\xbytigid#1#2#3#4{% + \if#4.% + \yybreak{\ifnum#2=\z@\xskiptofi{ #3}\else\xskiptofi{ #2#3}\fi}% + \else + \yybreak{\expandafter\xb@tigid\number1#1\xxcarry#1#4#2 {#3}}% + \yycontinue +} + +% #1 is a bogus parameter (see above) +% #2 is the digit +% #3 is the carry +% #4 is the next digit of the result +% #5 is the result up to now + +\def\xb@tigid#1#2#3#4#5{% + \xbytigid#2#3{#4#5}% +} + +% similar to \xmultiply by digit above by produces the result in the +% usual digit order + +\def\xsmallmultiple#1#2{% + \romannumeral0\expandafter\xsm@llmultiple\expandafter{\romannumeral0\xr@verse{}#1.}#2% +} + +\def\xsm@llmultiple#1#2{% + \xbytigid{#2}{0}{}#1.% +} + +% division by 2 + +\def\xdivbytwo#1{% + \romannumeral0\expandafter\xdivbytw@\romannumeral0\xr@verse{}#1..% +} + +\def\xdivbytw@#1#2{% + \if#2.% + \yybreak{\expandafter\space\number\csname xdivby2\endcsname#1}% + \else + \yybreak{\expandafter\xdivb@tw@\expandafter{\number\csname xdivby2\endcsname#1}#2}% + \yycontinue +} + +\def\xdivb@tw@#1{% + \xbytigid{5}{#1}{}% +} + +% increment by 1 + +\def\xincrement#1{% + \romannumeral0\expandafter\x@ncrement\expandafter{\romannumeral0\xr@verse{}#1.}% +} + +\def\x@ncrement#1{% + \x@ncr@ment{1}{}#1.% +} + +% #1 is the carry +% #2 is the result +% #3 is the next digit of the operand + +\def\x@ncr@ment#1#2#3{% + \if#3.% + \yybreak{\ifnum#1=\z@\xskiptofi{ #2}\else\xskiptofi{ #1#2}\fi}% + \else + \yybreak{\ifnum#1=\z@\xskiptofi{\x@@cr@m@nt{#3#2}}\else + \xskiptofi{\expandafter\x@ncr@m@nt\number1\csname xaddto#1\endcsname#3{#2}}\fi}% + \yycontinue +} + +\def\x@ncr@m@nt#1#2#3#4{% + \x@ncr@ment#2{#3#4}% +} + +\def\x@@cr@m@nt#1#2.{% + \xr@verse{}#2.#1% +} + +% decimal complements table + +\def\xcplof#1{\ifcase#1 \or9\or8\or7\or6\or5\or4\or3\or2\or1\fi} + +% single digit decrement by 1 table + +\def\xdecof#1{\ifcase#1 \or0\or1\or2\or3\or4\or5\or6\or7\or8\fi} + +% decrement by 1 + +\def\xdecrement#1{% + \romannumeral0\expandafter\xd@crement\expandafter{\romannumeral0\xr@verse{}#1.}% +} + +\def\xd@crement#1{% + \xd@cr@ment1{}#1.% +} + +% #1 is the carry +% #2 is the result +% #3 is the next digit of the operand + +\def\xd@cr@ment#1#2#3{% + \if#3.% + \yybreak{ -1}% + \else + \yybreak{\ifnum#1=\z@ + \xskiptofi{\xde@@@m@nt{#3#2}}% + \else + \xskiptofi{% + \ifnum#3=\z@ + \xskiptofi{\xd@cr@ment1{9#2}}% + \else + \xskiptofi{\expandafter\xde@@@m@nt\expandafter{\number\xdecof#3 #2}}% + \fi}% + \fi}% + \yycontinue +} + +\def\xd@cr@m@nt#1#2#3{% + \xd@cr@ment#1{#2#3}% +} + +\def\xde@@@m@nt#1#2.{% + \xr@verse{}#2.#1% +} |