% Copyright 2019 by Mark Wibrow
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Free Documentation License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.


\section{Fixed Point Arithmetic Library}

\begin{pgflibrary}{fixedpointarithmetic}
    This library provides an interface to the \LaTeX{} package |fp| for fixed
    point arithmetic. In addition to loading this library you must ensure |fp|
    is loaded, otherwise errors will occur.
\end{pgflibrary}


\subsection{Overview}

Whilst the mathematical engine that comes with \pgfname{} is reasonably fast
and flexible when it comes to parsing, the accuracy tends to be fairly low,
particularly for expressions involving many operations chained together. In
addition the range of values that can be computed is very small:
$\pm16383.99999$. Conversely, the |fp| package has a reasonably high accuracy,
and can perform computations over a wide range of values (approximately
$\pm9.999\times10^{17}$), but is comparatively slow and not very flexible,
particularly regarding parsing.

This library enables the combination of the two: the flexible parser of the
\pgfname{} mathematical engine with the evaluation accuracy of |fp|. There are,
however, a number of important points to bear in mind:
%
\begin{itemize}
    \item Whilst |fp| supports very large numbers, \pgfname{} and \tikzname{}
        do not. It is possible to calculate the result of |2^20| or
        |1.2e10+3.4e10|, but it is not possible to use these results in
        pictures directly without some ``extra work''.
    \item The \pgfname{} mathematical engine will still be used to evaluate
        lengths, such as |10pt| or |3em|, so it is not possible for an length
        to exceed the range of values supported by \TeX-dimensions
        ($\pm16383.99999$pt), even though the resulting expression is within
        the range of |fp|. So, for example, one can calculate |3cm*10000|, but
        not |3*10000cm|.
    \item Not all of the functions listed in Section~\ref{pgfmath-syntax}, have
        been mapped onto |fp| equivalents. Of those that have been, it is not
        guaranteed that functions will perform in the same way as they do in
        \pgfname. Reference should be made to the documentation for |fp|.
    \item In \pgfname, trigonometric functions such as |sin| and |cos| assume
        arguments are in degrees, and functions such as |asin| and |acos|
        return results in degrees. Although |fp| uses radians for such
        functions, \pgfname{} automatically converts arguments from degrees to
        radians, and converts results from radians to degrees, to ensure
        everything ``works properly''.
    \item The overall speed will actually be slower than using \pgfname{}
        mathematical engine. The calculating power of |fp| comes at the cost of
        an increased processing time.
\end{itemize}


\subsection{Using Fixed Point Arithmetic in PGF and \tikzname}

The following key is provided to use |fp| in \pgfname{} and \tikzname:

\begin{key}{/pgf/fixed point arithmetic=\meta{options}}
\keyalias{tikz}
    This key will set the key path to |/pgf/fixed point|, and execute
    \meta{options}. Then it will install the necessary commands so that the
    \pgfname{} parser will use |fp| to perform calculations. The best way to
    use this key is as an argument to a scope or picture. This means that |fp|
    does not always have to be used, and \pgfname{} can use its own
    mathematical engine at other times, which can lead to a significant
    reduction in the time for a document to compile.
\end{key}

Currently there are only a few keys key supported for \meta{options}:

\begin{key}{/pgf/fixed point/scale results=\meta{factor}}
    As noted above, |fp| can process a far greater range of numbers than
    \pgfname{} and \tikzname{}. In order to use results from |fp| in a
    |{pgfpicture}| or a |{tikzpicture}| they need to be scaled. When this key
    is used \pgfname{} will scale results of any evaluation by \meta{factor}.
    However, as it is not desirable for every part of every expression to be
    scaled, scaling will only take place if a special prefix |*| is used. If
    |*| is used at the beginning of an expression the evaluation of the
    expression will evaluated and then multiplied by \meta{factor}.
    %
\begin{codeexample}[preamble={\usepgflibrary{fixedpointarithmetic}}]
\begin{tikzpicture}[fixed point arithmetic={scale results=10^-6}]
\draw [help lines] grid (3,2);
\draw (0,0) -- (2,2);
\draw [red, line width=4pt] (*1.0e6,0) -- (*3.0e6,*2.0e6);
\end{tikzpicture}
\end{codeexample}

    A special case of scaling involves plots of data containing large numbers
    from files. It is possible to ``pre-process'' a file, typically using the
    application that generates the data, to either precede the relevant column
    with |*| or to perform the scaling as part of the calculation process.
    However, it may be desirable for the data in a plot to appear in a table as
    well, so, two files would be required, one pre-processed for plotting, and
    one not. This extra work may be undesirable so the following keys are
    provided:

    \begin{key}{/pgf/fixed point/scale file plot x=\meta{factor}}
        This key will scale the first column of data read from a file before it
        is plotted. It is independent of the |scale results| key.
    \end{key}

    \begin{key}{/pgf/fixed point/scale file plot y=\meta{factor}}
        This key will scale the second column of data read from a file before
        it is plotted.
    \end{key}

    \begin{key}{/pgf/fixed point/scale file plot z=\meta{factor}}
        This key will scale the third column of data read from a file before it
        is plotted.
    \end{key}
\end{key}
