summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/pgf/math/pgfint.code.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgf/math/pgfint.code.tex')
-rw-r--r--Master/texmf-dist/tex/generic/pgf/math/pgfint.code.tex126
1 files changed, 126 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfint.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfint.code.tex
new file mode 100644
index 00000000000..8921ee5fbd1
--- /dev/null
+++ b/Master/texmf-dist/tex/generic/pgf/math/pgfint.code.tex
@@ -0,0 +1,126 @@
+% Copyright 2019 by Henri Menke
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+% Guard against reading twice
+\ifx\pgfintloaded\pgfutil@undefined
+ \let\pgfintloaded=\relax
+\else
+ \expandafter\endinput
+\fi
+
+% This module is pretty much a rip-off of the LaTeX3 l3int module for integer
+% calculations. Since PGF supports e-TeX now, we can make use of those
+% extended facilities.
+
+% In contrast to l3int we will just admit that integers are regular TeX \count
+% register and will not implement an extra "integer datatype".
+
+% Evaluate an integer expression using \numexpr
+\def\pgfinteval#1{\number\numexpr#1\relax}
+
+% Get the absolute value of an integer by stripping off a leading minus sign
+\def\pgfintabs#1{\number\expandafter\pgfint@abs\number\numexpr#1\relax}
+\def\pgfint@abs#1{\ifx-#1\else\expandafter#1\fi}
+
+% Minimum and maximum
+\def\pgfintmax#1#2{%
+ \number\expandafter\pgfint@minmax
+ \number\numexpr#1\expandafter;%
+ \number\numexpr#2;%
+ >
+}
+\def\pgfintmin#1#2{%
+ \number\expandafter\pgfint@minmax
+ \number\numexpr#1\expandafter;%
+ \number\numexpr#2;%
+ <
+}
+\def\pgfint@minmax#1;#2;#3{%
+ \ifnum#1#3#2
+ #1%
+ \else
+ #2%
+ \fi
+}
+
+% \numexpr has the annoying property to round divisions rather than truncating
+% (as you would expect for integer arithmetic). Therefore we need a truncating
+% division function.
+\def\pgfintdivtruncate#1#2{%
+ \number\numexpr\expandafter\pgfint@divtruncate
+ \number\numexpr#1\expandafter;%
+ \number\numexpr#2;%
+ \relax
+}
+\def\pgfint@divtruncate#1#2;#3#4;{%
+ \ifx0#1
+ 0%
+ \else
+ (#1#2%
+ \ifx-#1 +\else-\fi
+ (\ifx-#3 -\fi#3#4-1)/2%
+ )%
+ \fi
+ /#3#4%
+}
+
+% \pgfintdivtruncate always truncates the result which leads to a rounding
+% towards zero. Donald Knuth defines in TAoCP, Vol 1, 3rd Ed, Section 1.2.4
+% that the modulo operation is
+%
+% x mod y = x - y * floor(x/y)
+%
+% In contrast to truncated division, floored division always rounds towards
+% -inf, i.e. floor(1/2) = 0 and floor(-1/2) = -1. This is also how integer
+% division is done in Lua.
+\def\pgfintdivfloor#1#2{%
+ \number\numexpr\expandafter\pgfint@divfloor
+ \number\numexpr#1\expandafter;%
+ \number\numexpr#2;%
+ \relax
+}
+\def\pgfint@divfloor#1#2;#3#4;{%
+ \ifx0#1
+ 0%
+ \else
+ \ifnum
+ 0\ifx-#1\ifx#3-\else1\fi\fi
+ 0\ifx-#3\ifx#1-\else1\fi\fi
+ >0
+ \pgfint@@divfloor#1#2;#3#4;-+%
+ \else
+ \pgfint@@divfloor#1#2;#3#4;+-%
+ \fi
+ \fi
+ /#3#4%
+}
+\def\pgfint@@divfloor#1#2;#3#4;#5#6{%
+ (#1#2%
+ \ifx-#1 #5\else#6\fi
+ (\ifx-#3 -\fi#3#4#61)/2%
+ )%
+}
+
+% Round
+\def\pgfintdivround#1#2{\number\numexpr(#1)/(#2)\relax}
+
+% Modulo
+\def\pgfintmod#1#2{%
+ \number\numexpr\expandafter\pgfint@mod%
+ \number\numexpr#1\expandafter;%
+ \number\numexpr#2;%
+ \relax
+}
+\def\pgfint@mod#1;#2;{#1-(\pgfint@divfloor#1;#2;)*#2}
+
+% Setter function so we don't always have to write \pgfinteval
+\def\pgfintset#1#2{#1 \numexpr#2\relax}
+
+\endinput