blob: 8921ee5fbd19859c8d83f74ec0385aa7e8702670 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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
|