You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
3.0 KiB
126 lines
3.0 KiB
% 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
|
|
|