% Copyright 2006 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.


\pgfkeys{/pgf/.cd,
	fixed point arithmetic/.code={%
		\pgfmathfp@plots@install%
		\pgfmathfp@parser@install%
		\let\pgfmathparse=\pgfmathfpparse%
		\pgfkeys{/pgf/fixed point/.cd, #1}%
	},%
	fixed point/.cd,
	scale results/.code={%
		\pgfmathfpparse{#1}%
		\let\pgfmathfpscale=\pgfmathresult%
	}%		
}

\def\pgfmathfpscale{1}

\def\pgfmathfpparse{%
	\begingroup%
		\let\pgfmathpostparse=\relax%
		\pgfmath@catcodes%
		\pgfmath@quickparsefalse%
		\pgfmathfpparse@}

\def\pgfmathfpparse@#1{%
	\edef\pgfmathfp@expression{#1}%
	\expandafter\pgfmathfpparse@@\pgfmathfp@expression\pgfmathfp@}

\def\pgfmathfp@char@asterisk{*}
\def\pgfmathfpparse@@#1#2\pgfmathfp@{%
	\def\pgfmathfp@test{#1}%
	\ifx\pgfmathfp@test\pgfmathfp@char@asterisk%
		\edef\pgfmathfp@expression{\pgfmathfpscale#1#2}%
	\else%
		\edef\pgfmathfp@expression{#1#2}%
	\fi%
	\expandafter\pgfmathparse@\expandafter{\pgfmathfp@expression}%
	% \endgroup provided by \pgfpathmarse@end
}

% Crude handling of file plots
%
\pgfkeys{/pgf/fixed point/.cd,
  scale file plot x/.code=\pgfmathfpparse{#1}\edef\pgfmathfpplotscalex{\pgfmathresult*},
  scale file plot y/.code=\pgfmathfpparse{#1}\edef\pgfmathfpplotscaley{\pgfmathresult*},
  scale file plot z/.code=\pgfmathfpparse{#1}\edef\pgfmathfpplotscalez{\pgfmathresult*}
}

\def\pgfmathfp@plots@install{%
	\let\pgfmathfpplotscalex=\pgfutil@empty
	\let\pgfmathfpplotscaley=\pgfutil@empty
	\let\pgfmathfpplotscalez=\pgfutil@empty
	\let\pgf@parsexyline=\pgfmathfp@parsexyline%
	\let\pgf@parsexyzline=\pgfmathfp@parsexyzline%
}

\def\pgfmathfp@parsexyline#1 #2 #3\pgf@stop{%
	\edef\pgfmathfp@marshal{%
		\noexpand\pgfplotstreampoint{\noexpand\pgfpointxy{\pgfmathfpplotscalex#1}{\pgfmathfpplotscaley#2}}%
	}%
	\pgfmathfp@marshal%
}

\def\pgfmathfp@parsexyzline#1 #2 #3 #4\pgf@stop{%
  \edef\pgfmathfp@marshal{%
		\noexpand\pgfplotstreampoint{%
			\noexpand\pgfpointxyz{\pgfmathfpplotscalex#1}{\pgfmathfpplotscaley#2}{\pgfmathfpplotscalez#3}%
		}%
	}%
	\pgfmathfp@marshal%
}

% 
\def\pgfmathfp@parser@install{%
	%
	\expandafter\ifx\csname FP@version\endcsname\relax%
		\PackageError{pgf}{You need to say `\string\usepackage{fp}' to use %
		  fixed point arithmetic}{}%
	\else%
	  %
		% Don't want messages.
		%
		\FPmessagesfalse%
		\FPdebugfalse%
		%
		% Install float commands...
		%
		\let\pgfmathadd@=\pgfmathfpadd@%
		\let\pgfmathsubtract@=\pgfmathfpsubtract@%
		\let\pgfmathmultiply@=\pgfmathfpmultiply@%
		\let\pgfmathdivide@=\pgfmathfpdivide@%
		\let\pgfmathabs@=\pgfmathfpabs@%
		\let\pgfmathround@=\pgfmathfpround@%
		\let\pgfmathfloor@=\pgfmathfpfloor@%
		\let\pgfmathceil@=\pgfmathfpceil@%
		\let\pgfmathmod@=\pgfmathfpmod@%
		\let\pgfmathmax@=\pgfmathfpmax@%
		\let\pgfmathmin@=\pgfmathfpmin@%
		\let\pgfmathsin@=\pgfmathfpsin@%
		\let\pgfmathcos@=\pgfmathfpcos@%
		\let\pgfmathtan@=\pgfmathfptan@%
		\let\pgfmathdeg@=\pgfmathfpdeg@%
		\let\pgfmathrad@=\pgfmathfprad@%
		\let\pgfmathatan@=\pgfmathfpatan@%
		\let\pgfmathasin@=\pgfmathfpasin@%
		\let\pgfmathacos@=\pgfmathfpacos@%
		\let\pgfmathcot@=\pgfmathfpcot@%
		\let\pgfmathsec@=\pgfmathfpsec@%
		\let\pgfmathcosec@=\pgfmathfpcosec@%
		\let\pgfmathpow@=\pgfmathfppow@%
		\let\pgfmathexp@=\pgfmathfpexp@%
		\let\pgfmathln@=\pgfmathfpln@%
		\let\pgfmathsqrt@=\pgfmathfpsqrt@%
		\let\pgfmath@pi=\pgfmathfppi@%
		\let\pgfmathveclen@=\pgfmathfpveclen@%
		\let\pgfmathe@=\pgfmathfpe@%
		%
		\let\pgfmathlessthan@=\pgfmathfplessthan@%
		\let\pgfmathgreaterthan@=\pgfmathfpgreaterthan@%
		\let\pgfmathequalto@=\pgfmathfpequalto@%
		%
		\let\pgfmathrnd=\pgfmathfprnd%
		\let\pgfmathrand=\pgfmathfprand%
		\let\pgfmathsetseed=\pgfmathfpsetseed%
		%
		\let\pgfmathscientific=\pgfmathfpscientific%
	\fi%
}%

\def\pgfmathfpe@{let\pgfmathresult=\FPe}%
\def\pgfmathfppi@{let\pgfmathresult=\FPpi}%


% Scientific notation.

\def\pgfmathfpscientific#1#2{%
	\begingroup%
		\FPpow\pgfmathresult{10}{#2}\unskip% Needed.
		\FPmul\pgfmathresult{#1}{\pgfmathresult}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% Comparison stuff...

% lessthan
%
\def\pgfmathfplessthan#1#2{%
	\pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
	\pgfmathfpparse{#1}%
	\pgfmathfplessthan@{\pgfmathresult}{\pgfmath@result}%
}
\def\pgfmathfplessthan@#1#2{%
	\begingroup%
		\FPiflt{#1}{#2}%
			\def\pgfmathresult{1.0}%
		\else%
			\def\pgfmathresult{0.0}%
		\fi%
  	\pgfmath@smuggleone\pgfmathresult%
  \endgroup%
}

% greaterthan
%
\def\pgfmathfpgreaterthan#1#2{%
	\pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
	\pgfmathfpparse{#1}%
	\pgfmathfpgreaterthan@{\pgfmathresult}{\pgfmath@result}%
}
\def\pgfmathfpgreaterthan@#1#2{%
	\begingroup%
		\FPifgt{#1}{#2}%
			\def\pgfmathresult{1.0}%
		\else%
			\def\pgfmathresult{0.0}%
		\fi%
  	\pgfmath@smuggleone\pgfmathresult%
  \endgroup%
}

% equalto
%
\def\pgfmathfpequalto#1#2{%
	\pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
	\pgfmathfpparse{#1}%
	\pgfmathfpequalto@{\pgfmathresult}{\pgfmath@result}%
}
\def\pgfmathfpequalto@#1#2{%
	\begingroup%
		\FPifeq{#1}{#2}%
			\def\pgfmathresult{1.0}%
		\else%
			\def\pgfmathresult{0.0}%
		\fi%
  	\pgfmath@smuggleone\pgfmathresult%
  \endgroup%
}

		
% Basic arithmetic stuff...

% add
%
\def\pgfmathfpadd#1#2{%
	\pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
	\pgfmathfpparse{#1}%
	\pgfmathfpadd@{\pgfmathresult}{\pgfmath@result}%
}
\def\pgfmathfpadd@#1#2{%
	\begingroup%
		\FPadd\pgfmathresult{#1}{#2}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% subtract
%
\def\pgfmathfpsubtract#1#2{%
	\pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
	\pgfmathfpparse{#1}%
	\pgfmathfpsubtract@{\pgfmathresult}{\pgfmath@result}%
}
\def\pgfmathfpsubtract@#1#2{%
	\begingroup%
		\FPsub\pgfmathresult{#1}{#2}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% multiply
%
\def\pgfmathfpmultiply#1#2{%
	\pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
	\pgfmathfpparse{#1}%
	\pgfmathfpmultiply@{\pgfmathresult}{\pgfmath@result}%
}
\def\pgfmathfpmultiply@#1#2{%
	\begingroup%
		\FPmul\pgfmathresult{#1}{#2}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% divide
%
\def\pgfmathfpdivide#1#2{%
	\pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
	\pgfmathfpparse{#1}%
	\pgfmathfpdivide@{\pgfmathresult}{\pgfmath@result}%
}
\def\pgfmathfpdivide@#1#2{%
	\begingroup%
		\FPdiv\pgfmathresult{#1}{#2}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% abs
%
\def\pgfmathfpabs#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpabs@{\pgfmathresult}%
}
\def\pgfmathfpabs@#1{%
	\begingroup%
		\FPabs\pgfmathresult{#1}
	\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% round
%
\def\pgfmathfpround#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpround@{\pgfmathresult}%
}
\def\pgfmathfpround@#1{%
	\begingroup%
		\FPround\pgfmathresult{#1}{0}%
		\edef\pgfmathresult{\pgfmathresult.0}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% floor
%
\def\pgfmathfpfloor#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpfloor@{\pgfmathresult}%
}
\def\pgfmathfpfloor@#1{%
	\begingroup%
		\FPtrunc\pgfmathresult{#1}{0}%
		\FPifneg{#1}%
			\FPsub\pgfmathresult{\pgfmathresult}{1}%
		\fi%
		\edef\pgfmathresult{\pgfmathresult.0}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% ceil
%
\def\pgfmathfpceil#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpceil@{\pgfmathresult}%
}
\def\pgfmathfpceil@#1{%
	\begingroup%
		\FPtrunc\pgfmathresult{#1}{0}%
		\FPifpos{#1}%
			\FPadd\pgfmathresult{\pgfmathresult}{1}%
		\fi%
		\edef\pgfmathresult{\pgfmathresult.0}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% mod
%
\def\pgfmathfpmod#1#2{%
	\pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
	\pgfmathfpparse{#1}%
	\pgfmathfpmod@{\pgfmathresult}{\pgfmath@result}%
}
\def\pgfmathfpmod@#1#2{%
	\begingroup%
		\FPdiv\pgfmathresult{#1}{#2}%
		\FPtrunc\pgfmathresult{\pgfmathresult}{0}%
		\FPmul\pgfmathresult{\pgfmathresult}{#2}%
		\FPsub\pgfmathresult{#1}{\pgfmathresult}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% max
%
\def\pgfmathfpmax#1#2{%
	\pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
	\pgfmathfpparse{#1}%
	\pgfmathfpmax@{\pgfmathresult}{\pgfmath@result}%
}
\def\pgfmathfpmax@#1#2{%
	\begingroup%
		\FPifgt{#1}{#2}%
			\def\pgfmathresult{#1}%
		\else%
			\def\pgfmathresult{#2}%
		\fi%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% min
%
\def\pgfmathfpmin#1#2{%
	\pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
	\pgfmathfpparse{#1}%
	\pgfmathfpmin@{\pgfmathresult}{\pgfmath@result}%
}
\def\pgfmathfpmin@#1#2{%
	\begingroup%
		\FPiflt{#1}{#2}%
			\def\pgfmathresult{#1}%
		\else%
			\def\pgfmathresult{#2}%
		\fi%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% Functions...

% pow
%
\def\pgfmathfppow#1#2{%
	\pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
	\pgfmathfpparse{#1}%
	\pgfmathfppow@{\pgfmathresult}{\pgfmath@result}%
}
\def\pgfmathfppow@#1#2{%
	\begingroup%
		\FPpow\pgfmathresult{#1}{#2}\unskip%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% exp
%
\def\pgfmathfpexp#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpexp@{\pgfmathresult}%
}
\def\pgfmathfpexp@#1{%
	\begingroup%
		\FPexp\pgfmathresult{#1}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% ln
%
\def\pgfmathfpln#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpln@{\pgfmathresult}%
}
\def\pgfmathfpln@#1{%
	\begingroup%
		\FPln\pgfmathresult{#1}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% sqrt
%
\def\pgfmathfpsqrt#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpsqrt@{\pgfmathresult}%
}
\def\pgfmathfpsqrt@#1{%
	\begingroup%
		\FProot\pgfmathresult{#1}{2}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% veclen
%
\def\pgfmathfpveclen#1#2{%
	\pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
	\pgfmathfpparse{#1}%
	\pgfmathfpveclen@{\pgfmathresult}{\pgfmath@result}%
}
\def\pgfmathfpveclen@#1#2{%
	\begingroup%
	  \FPmul\pgfmath@result{#1}{#1}%
	  \FPmul\pgfmath@@result{#2}{#2}%
	  \FPadd\pgfmathresult{\pgfmath@result}{\pgfmath@@result}%
	  \FProot\pgfmathresult{\pgfmathresult}{2}%
	  \pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% Trigonometric stuff...

% sin
%
\def\pgfmathfpsin#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpsin@{\pgfmathresult}%
}
\def\pgfmathfpsin@#1{%
	\begingroup%
		\FPmul\pgfmathresult{#1}{0.017453292519943295}%
		\FPsin\pgfmathresult{\pgfmathresult}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% cos
%
\def\pgfmathfpcos#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpcos@{\pgfmathresult}%
}
\def\pgfmathfpcos@#1{%
	\begingroup%
		\FPmul\pgfmathresult{#1}{0.017453292519943295}%
		\FPcos\pgfmathresult{\pgfmathresult}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% tan
%
\def\pgfmathfptan#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfptan@{\pgfmathresult}%
}
\def\pgfmathfptan@#1{%
	\begingroup%
		\FPmul\pgfmathresult{#1}{0.017453292519943295}%
		\FPtan\pgfmathresult{\pgfmathresult}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% acos
%
\def\pgfmathfpacos#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpacos@{\pgfmathresult}%
}
\def\pgfmathfpacos@#1{%
	\begingroup%
		\FParccos\pgfmathresult{#1}%
		\FPmul\pgfmathresult{\pgfmathresult}{57.295779513082320885}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% asin
%
\def\pgfmathfpasin#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpasin@{\pgfmathresult}%
}
\def\pgfmathfpasin@#1{%
	\begingroup%
		\FParcsin\pgfmathresult{#1}%
		\FPmul\pgfmathresult{\pgfmathresult}{57.295779513082320885}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% atan
%
\def\pgfmathfpatan#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpatan@{\pgfmathresult}%
}
\def\pgfmathfpatan@#1{%
	\begingroup%
		\FParctan\pgfmathresult{#1}%
		\FPmul\pgfmathresult{\pgfmathresult}{57.295779513082320885}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% cot
%
\def\pgfmathfpcot#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpcot@{\pgfmathresult}%
}
\def\pgfmathfpcot@#1{%
	\begingroup%
		\FPmul\pgfmathresult{#1}{0.017453292519943295}%
		\FPcot\pgfmathresult{\pgfmathresult}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% sec
%
\def\pgfmathfpsec#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpsec@{\pgfmathresult}%
}
\def\pgfmathfpsec@#1{%
	\begingroup%
		\FPmul\pgfmathresult{#1}{0.017453292519943295}%
		\FPcos\pgfmathresult{\pgfmathresult}%
		\FPdiv\pgfmathresult{1}{\pgfmathresult}		
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% cosec
%
\def\pgfmathfpcosec#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpcosec@{\pgfmathresult}%
}
\def\pgfmathfpcosec@#1{%
	\begingroup%
		\FPmul\pgfmathresult{#1}{0.017453292519943295}%
		\FPsin\pgfmathresult{\pgfmathresult}%
		\FPdiv\pgfmathresult{1}{\pgfmathresult}		
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% deg
%
\def\pgfmathfpdeg#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfpdeg@{\pgfmathresult}%
}
\def\pgfmathfpdeg@#1{%
	\begingroup%
		\FPmul\pgfmathresult{#1}{57.295779513082320885}%
	\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% rad
%
\def\pgfmathfprad#1{%
	\pgfmathfpparse{#1}%
	\pgfmathfprad@{\pgfmathresult}%
}
\def\pgfmathfprad@#1{%
	\begingroup%
		\FPmul\pgfmathresult{#1}{0.01745329251994325}%
	\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% Random stuff...

\def\pgfmathfpsetseed#1{%
	\pgfmathfpparse{#1}%
	\afterassignment\pgfmath@gobbletilpgfmath@%
	\FPseed\pgfmathresult\relax\pgfmath@%
}

% rnd
%
\def\pgfmathfprnd{%
	\begingroup%
		\FPrandom\pgfmathresult%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

% rand
%
\def\pgfmathfprand{%
	\begingroup%
		\FPrandom\pgfmathresult%
		\FPmul\pgfmathresult{2}{\pgfmathresult}%
		\FPsub\pgfmathresult{\pgfmathresult}{1}%
		\pgfmath@smuggleone\pgfmathresult%
	\endgroup%
}

