% \iffalse META-COMMENT
%
% The fltpoint package for use with TeX / LaTeX
% Current Version: 1.1b, dated 2004/11/12
% Copyright 2000-2004
% Eckhart Guthoehrlein
% e-mail <e_w_g@web.de>
%
% This program may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.2
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.2 or later is part of all distributions of LaTeX
% version 1999/12/01 or later.
%
% This program consists of the files 'fltpoint.dtx', 'fltpoint.ins'
% and 'README_fltpoint.txt'.
% 
% The package provides simple arithmetic with TeX. It should work with
% all formats and has been tested with plain TeX and LaTeX.
%
% Run TeX over fltpoint.ins to produce the docstripped version
% of the file. The documentation can be typeset by running
% LaTeX over fltpoint.dtx.
%
% Comments and bug-reports are welcome under the above
% e-mail address.
%
% \fi ^^A end meta-comment
% \CheckSum{1150}
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
%
% \DoNotIndex{\def,\edef,\xdef,\gdef,\let,\global,\the,^^A
%  \newcount,\if,\ifx,\else,\fi,\ifnum,\catcode,^^A
%  \@,\expandafter,\csname,\endcsname,\number^^A
%  \relax,\end,\advance,\multiply,\divide,\endinput^^A
%  \iterate,\body,\repeat,\iiterate,\ibody,\irepeat,^^A
%  \xiterate,\xbody,\xrepeat.
%  \,,\active,\AlsoImplementation,\AtBegin\Document,
%  \begin,\CodelineIndex,\CommaCheck,\CommaOrdinary,
%  \CommaPunct,\DeclareOption,\DisableCrossrefs,
%  \DocInput,\documentclass,\EnableCrossrefs,\endinput,
%  \futurelet,\long,\mathchardef,\mathcode,\mbox,
%  \NeedsTeXFormat,\newcommand,\noexpand,\number,
%  \obeyspaces,\OnlyDescription,\ProcessOptions,
%  \ProvidesPackage,\RecordChanges,\rightarrow,
%  \space,\tt,\usepackage}
%
% \MakeShortVerb{\"}
%
% \changes{v1.0a}{2000/08/23}{First public release}
% \changes{v1.0b}{2000/08/25}{Some spaces sneaked into the output.
%     Fixed.}
% \changes{v1.0c}{2000/09/05}{Changes necessary for
%     the \texttt{rccol} package.}
% \changes{v1.1}{2001/11/17}{Cleanup to freeze development.}
% \changes{v1.1b}{2004/11/12}{Some more freezing cleanup.}
% \GetFileInfo{fltpoint.sty}
% \title{The \texttt{fltpoint} package\thanks{This
%  file has version number \fileversion{} dated \filedate.}}
% \author{Eckhart Guth\"ohrlein\thanks{Send comments
%  or bug-reports to the author via e-mail
% \texttt{<e\_w\_g@web.de>}.}}
% \date{Printed \today}
% \maketitle
%
% \begin{abstract}
% This package provides commands for simple
% arithmetic with generic \TeX. At the moment, there is support for the
% basic operations addition, subtraction, multiplication and division as
% well as for rounding numbers to a given precision.
% \end{abstract}
%
% \newif\ifmulticols
% \IfFileExists{multicol.sty}{\multicolstrue}{}
% \ifmulticols
% \addtocontents{toc}{\protect\begin{multicols}{2}}
% \fi
% ^^A{\parskip0mm\tableofcontents}
%
% \section{Introduction}
% The need for calculations inside \TeX\ was encountered when working on
% some macros to convert positions on a linear scale into angle values,
% since integer values proved not to be sufficiently exact.  Although
% the capabilities of this package are currently rather limited,
% they may be of some use if you do not need more than the
% provided functions. The \texttt{rccol} package may serve as an
% example application; it uses the rounding facilities of this package.
%
% \section{User interface}
% The user commands are divided into two categories:
% the normal and the register commands. Each command
% is available in those two variants, as decribed below.
% At first, we have to agree about the syntax for floating
% point numbers.
%
% \subsection{Syntax of floating point numbers}
% In the syntax descriptions below, \meta{fp number}
% will be used to denote a number according to the following
% syntax.
% \begin{flushleft}
% $\mbox{\meta{fp number}}:=\mbox{\meta{opt signs}}
% \mbox{\meta{opt digits}}\mbox{\meta{opt dot}}
% \mbox{\meta{opt digits}}$
% \end{flushleft}
% \meta{opt signs} may be any number of `"+"' and/or `"-"'
% characters, where each `"-"' toggles the sign of
% the number. \meta{opt digits} may be any number
% of characters `"0"'\dots `"9"', and \meta{opt dot}
% is the optional decimal sign. For example, the
% following inputs for \meta{fp number} are valid,
% resulting into the specified numbers.
% \fpexample{100}, \fpexample{010,98700}, \fpexample{-,99},
% \fpexample{-+-+0001,}, \fpexample{}, \fpexample{---,50}.
% As you can see, leading and trailing zeros are removed
% as far as possible, and an `empty number' (omitting anything
% optional) is understood as zero.
%
% There is no syntax checking, so if you do not obey the
% rules above, you are likely to encounter strange error
% messages, as well as everything might work properly in
% some cases.
% Of course, it is also possible to
% use a macro as \meta{fp number} if it expands to a
% string satisfying the syntax rules.
%
% \subsection{Standard operations}
% \DescribeMacro\fpAdd\DescribeMacro\fpSub
% \DescribeMacro\fpMul\DescribeMacro\fpDiv
% The standard commands for binary operations have the following
% common syntax:
% \begin{flushleft}
% "\fp"\meta{bOp}"{"\meta{command sequence}"}{"\meta{fp number}"}"^^A
%  "{"\meta{fp number}"}".
% \end{flushleft}
% This will perform the operation specified by \meta{bOp}
% with the two given numbers, saving the result in
% \meta{command sequence}. Possibilities for
% \meta{bOp} are `"Add"', `"Sub"', `"Mul"' and `"Div"',
% specifying addition, subtraction, multiplication,
% and division. Example:
% \begin{flushleft}
% "\fpAdd{\exmplsum}{100,0}{-99,1}"\\
% "\fpMul{\exmplprod}{5}{\exmplsum}"
% \end{flushleft}
% \fpAdd{\exmplsum}{100,0}{-99,1}^^A
% \fpMul{\exmplprod}{5}{\exmplsum}^^A
% After this, the results of the computations will
% be stored in the macros "\exmplsum" and "\exmplprod",
% expanding to \exmplsum\ and \exmplprod.
%
% \DescribeMacro\fpNeg\DescribeMacro\fpAbs
% Similar to the binary operations, the unary operations
% share the common syntax
% \begin{flushleft}
% "\fp"\meta{uOp}"{"\meta{command sequence}"}{"\meta{fp number}"}".
% \end{flushleft}
% Possibilities for \meta{uOp} are `"Abs"' and `"Neg"',
% meaning absolute amount and negation.
%
% \DescribeMacro\fpRound
% With "\fpRound{"\meta{command sequence}"}{"\meta{fp number}^^A
% "}{"\meta{precision}"}",
% a number can be rounded to the desired precision (a power of ten). 
% The result
% is saved in \meta{command sequence} as usual.
%
% \subsection{Register operations}
% You may use register variants of all operations,
% which means that you perform the operation on
% a register which contains a number. A register is
% referred to using its name; the name may
% contain any characters including digits.
%
% \DescribeMacro\fpRegSet\DescribeMacro\fpRegGet
% Registers are initialized by assigning them values,
% using "\fpRegSet". They can be read out into
% command sequences using "\fpRegGet".
% \begin{flushleft}
% "\fpRegSet{"\meta{reg name}"}{"\meta{fp number}"}"\\
% "\fpRegGet{"\meta{reg name}"}{"\meta{command sequence}"}"
% \end{flushleft}
%
% \DescribeMacro\fpRegAdd\DescribeMacro\fpRegSub
% \DescribeMacro\fpRegMul\DescribeMacro\fpRegDiv
% The binary operations need two register names.
% After execution, the first register will hold
% the result of the specified computation,
% performed with its former value and the
% value of the second register.
% \begin{flushleft}
% "\fp"\meta{bOp}"{"\meta{reg name 1}"}{"\meta{reg name 2}"}"
% \end{flushleft}
% \DescribeMacro\fpRegAbs\DescribeMacro\fpRegNeg
% Consequently, the unary operations only need
% the name of the register.
% \begin{flushleft}
% "\fp"\meta{uOp}"{"\meta{reg name}"}"
% \end{flushleft}
% \DescribeMacro\fpRegRound
% Rounding of registers is also possible.
% \begin{flushleft}
% "\fpRegRound{"\meta{reg name}"}{"\meta{precision}"}"
% \end{flushleft}
% \DescribeMacro\fpRegCopy
% Furthermore, there is one binary operation only available for
% registers, this is "\fpRegCopy" which assigns the
% value of \meta{reg name 2} to register \meta{reg name 1}.
%
% For example, consider the following statements.
% \begin{flushleft}
% "\fpRegSet{test1}{36}     \fpRegSet{test2}{-3}"\\
% "\fpRegDiv{test1}{test2}  \fpRegMul{test1}{test1}"\\
% "\fpRegGet{test1}{\fpresult}"
% \end{flushleft}
% \fpRegSet{test1}{36}\fpRegSet{test2}{-3}^^A
% \fpRegDiv{test1}{test2}\fpRegMul{test1}{test1}^^A
% \fpRegGet{test1}{\fpresult}^^A
% After this, "test1" will hold the value \fpresult, which
% "\fpresult" will expand to.
%
%
% \subsection{Configuration and Parameters}
%
% \DescribeMacro\fpAccuracy
% The macro "\fpAccuracy" takes one argument (a number),
% determining the number of digits after the decimal sign,
% i.\,e., the accuracy of the computations.
% The default value is five.
% At the moment, the name promises too much.
% The command only affects "\fpDiv" and "\fpRegDiv".
%
% \DescribeMacro\fpDecimalSign
% With "\fpDecimalSign{"\meta{character}"}" you can chose any character
% for use as the decimal sign. Normally, this will be either
% a point or a comma; the default is a comma.
% You can furthermore use the package options 
% \texttt{comma} or \texttt{point}.
% The support for options like \texttt{english} or \texttt{german}
% has been removed. It will not be added again, and there will be no
% detection of packages like \texttt{babel} or \texttt{german}.
% In my view, a comma is the better choice regardless of the language
% in question (and it is the \textsc{iso} standard). On the other hand,
% many people think that a point should be used even in German texts.
% So, you have to make an explicit decision.
%
% \section{Final Remarks}
% After the first release, I intended to include the features listed
% below in the near future.
% Unfortunately, I didn't have time to do so, and maybe I will
% never have, since I am currently not interested in extending this
% package. If I continued the development some day, the
% first extensions might be what is listed here.
% \begin{itemize}
% \item Extend syntax to support numbers like $1,7\mathrm{E}{-}1$ or
% $2,765\cdot 10^5$ in input and output.
% \item Formatted, customizable output.
% \item User access to the comparison of registers.
% \item A better concept for chosing the accuracy of the computations.
% \item More operations like $\mathrm{e}^x$, $\sqrt{x}$, $\sin x$,
% $\ln x$\ldots
% \end{itemize}
%
% Some users have pointed out that the terminus \lq floating-point\rq\
% is not strictly correct for what is provided by the package. Alas! I
% happily stick to the package name.
% 
% If you encounter needs not satisfied by this package, you may
% wait for the unlikely event of an extension from my part, or you can
% have a look at the following packages and see if they do what you want:
% \begin{itemize}
% \item {\tt fp} by Michael Mehlich for calculations,
% \item {\tt numprint} by Harald Harders for formatted printing of
% numbers.
% \end{itemize}
% Finally, the license of this package is LPPL, so feel free to do
% it yourself.
%
% \StopEventually{%
% \ifmulticols
% \addtocontents{toc}{\protect\end{multicols}}
% \fi}
% \section{Implementation}
%
% \subsection{General ideas}
% The main idea was to represent numbers internally by storing their
% digits in an array/record-like construction (to be referred to as
% an array or as a register from now on) whose numbering
% reflects the decimal position factor of the digit, with
% some information about the range of the numbering
% and the sign of the number.
% An array consists of a couple of command sequences,
% sharing a common name followed by an element number.
% E.\,g., `$120.3$' means $1\cdot 10^2+2\cdot 10^1+
% 0\cdot 10^0+3\cdot 10^{-1}$. So, if the number is to be stored
% in the array "\exmpl", the command sequences
% "\exmpl@2", "\exmpl@1", "\exmpl@0" and "\exmpl@-1"
% will be defined as `"1"', `"2"', `"0"' and `"3"', respectively.
% The sign information `"+"' will be stored in "\exmpl@sig".
% "\exmpl@ul" (`upper limit') will be `"2"', "\exmpl@ll" (`lower
% limit') will be `"-1"'.
%
% The computations are performed as 
% you do it with paper and pencil.
% E.\,g., for an addition, all corresponding digits 
% are summed, taking over anything
% exceeding ten to the next pair of digits.
% Thus, there is no limit to the range of numbers or to the
% number of digits after the decimal sign, except
% \TeX's memory and, probably the limiting factor, your patience.
%
% Initially, the computations were not performed inside of
% groups, and side-effects were avoided using more
% counters and constructions like "\xloop" etc.
% This may make more efficient use of \TeX, as far as speed
% and save stack usage is concerned, but I think that further
% extensions will be much simpler now without the
% need to worry about possible side-effects and the surprising
% result when, once again, something happens you simply
% did not think of.  Furthermore, this provides
% a simple mechanism of removing temporary stuff
% from the memory.
%
% But now, let's reveal the code\dots
%
%
% \subsection{Driver file}
% The driver file can be generated from \texttt{fltpoint.dtx}
% and then be used to produce the documentation (if you don't like
% to run \LaTeX\ directly over the \texttt{dtx}-file).
%    \begin{macrocode}
%<*deccomma>
\mathchardef\CommaOrdinary="013B
\mathchardef\CommaPunct   ="613B
\mathcode`,="8000
{\catcode`\,=\active
 \gdef ,{\obeyspaces\futurelet\next\CommaCheck}}
\def\CommaCheck{\if\space\next\CommaPunct\else\CommaOrdinary\fi}
%</deccomma>
%<*driver>
\documentclass{ltxdoc}
\usepackage{deccomma,fltpoint}
%\OnlyDescription
\AlsoImplementation
\EnableCrossrefs % disable if index is ready
\CodelineIndex
\RecordChanges
%\DisableCrossrefs
\newcommand{\fpexample}[1]{%
   \fpRegSet{fptemp}{#1}%
   \fpRegGet{fptemp}{\fptemp}%
   $\mbox{\tt`#1'}\rightarrow\fptemp$}
\begin{document}
   \DocInput{fltpoint.dtx}
\end{document}
%</driver>
%    \end{macrocode}
%
%
% \subsection{\LaTeX\ package definitions}
% If used as a \LaTeX\ package, the usual \LaTeX\ preliminaries
% and some option declarations are necessary.
%    \begin{macrocode}
%<*package>
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{fltpoint}[2004/11/12 v1.1b floating point arithmetic]
\DeclareOption{comma}{\AtBeginDocument{\fpDecimalSign,}}
\DeclareOption{point}{\AtBeginDocument{\fpDecimalSign.}}
\ProcessOptions*\relax
\input{fltpoint}
%</package>
%    \end{macrocode}
%
% \iffalse
%<*fltmain>
% \fi
% \subsection{Private letters}
%
% \begin{macro}{\atcatcode}
% `"@"' is used for private command sequences. Its catcode is saved
% in "\atcatcode" to be restored just before "\endinput".
%    \begin{macrocode}
\edef\atcatcode{\the\catcode`\@}
\catcode`\@=11
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{\LaTeX\ or not?}
%
% Check for \LaTeX, otherwise provide the "\@ifnextchar" mechanism
% copied from the \LaTeX\ source, see there for explanation.
%    \begin{macrocode}
\ifx\documentclass\relax
\long\def\@ifnextchar#1#2#3{%
  \let\reserved@d=#1%
  \def\reserved@a{#2}%
  \def\reserved@b{#3}%
  \futurelet\@let@token\@ifnch}
\def\@ifnch{%
  \ifx\@let@token\@sptoken
    \let\reserved@c\@xifnch
  \else
    \ifx\@let@token\reserved@d
      \let\reserved@c\reserved@a
    \else
      \let\reserved@c\reserved@b
    \fi
  \fi
  \reserved@c}
\def\:{\let\@sptoken= } \:
\def\:{\@xifnch} \expandafter\def\: {\futurelet\@let@token\@ifnch}
\fi
%    \end{macrocode}
% \subsection{Additional loop structures}
%
% \begin{macro}{\iloop}
% \begin{macro}{\xloop}
% To be able to nest loop structures without the need for
% hiding the inner loop(s) in grouped blocks, the constructions
% "\iloop...\irepeat" and "\xloop...\xrepeat" are defined
% analogously to \PlainTeX's "\loop...\repeat".
% "\iloop" will be used `internally' by macros which are
% to be used in ordinary "\loop"s or in "\xloop"s.
% "\xloop" will be used
% `externally', surrounding ordinary "\loop"s.
%    \begin{macrocode}
\def\iloop#1\irepeat{\def\ibody{#1}\iiterate}
\def\iiterate{\ibody\let\inext=\iiterate\else\let\inext=\relax\fi
   \inext}
\def\xloop#1\xrepeat{\def\xbody{#1}\xiterate}
\def\xiterate{\xbody\let\xnext\xiterate\else\let\xnext\relax\fi\xnext}
%    \end{macrocode}
% The following assignments are necessary to make 
% "\loop"\dots"\if"\dots"\repeat"
% constructions skippable inside another "\if".
%    \begin{macrocode}
\let\repeat\fi
\let\irepeat\fi
\let\xrepeat\fi
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \subsection{Allocation of registers}
%
% \begin{macro}{\fp@loopcount}
% \begin{macro}{\fp@loopcountii}
% \begin{macro}{\fp@result}
% \begin{macro}{\fp@carryover}
% \begin{macro}{\fp@tempcount}
% \begin{macro}{\fp@tempcountii}
% Several count registers are needed. I have tried to keep this
% number small, which means that, at some points, I may have chosen a 
% less logical or less readable usage of counts.
% Nevertheless, I do not claim to have minimized the number
% as far as possible\dots
%
% "\fp@loopcount" and "\fp@loopcountii" are often, but not always, used
% for "\loop"s, "\fp@loopcountii" sometimes just stores the finishing
% number. "\fp@result" and "\fp@carryover"
% are used to store the intermediate results of computations.
% "\fp@tempcount" and "\fp@tempcountii" are scratch registers
% whose values should not be considered to be the same
% after the use of any macro, except the simple array
% accession abbreviations starting whith "\ar@", as explained below.
%    \begin{macrocode}
\newcount\fp@loopcount
\newcount\fp@loopcountii
\newcount\fp@result
\newcount\fp@carryover
\newcount\fp@tempcount
\newcount\fp@tempcountii
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsection{Communication between macros and groups}
%
% \begin{macro}{\fp@setparam}
% \begin{macro}{\fp@param}
% To pass information from one macro to another, or from
% inside a group to the outer world, the construction
% "\fp@setparam{"\meta{information}"}" is used. It saves
% \meta{information} globally in the command sequence "\fp@param".
% This mechanism is used, e.\,g., by "\fp@regcomp",
% "\fp@getdigit" to pass their result to the calling macro,
% or by "\fp@regadd" etc.\ to make \meta{information} survive the end
% of the current group. Since "\xdef" is used, \meta{information}
% will be fully expanded.
%    \begin{macrocode}
\def\fp@setparam#1{\xdef\fp@param{#1}}%
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsection{Array accession}
%
% \begin{macro}{\ar@set}
% \begin{macro}{\ar@get}
% \begin{macro}{\ar@setsig}
% \begin{macro}{\ar@getsig}
% \begin{macro}{\ar@setul}
% \begin{macro}{\ar@getul}
% \begin{macro}{\ar@setll}
% \begin{macro}{\ar@getll}
% The idea of arrays using command sequences like
% "\exmpl@-1" means typing a lot of unreadable
% "\expandafter"s and "\csname"s, so the following
% abbreviations were introduced. They take the base name of
% the array as the first argument, if needed followed by
% an element number, for the "set"-commands followed by
% the third argument to be the (new) value.
% No checks are performed if the element number
% is inside the boundaries of the array, nor anything
% else to ensure the validity of the operation.
%
% "\ar@set" is used to save digits.
% "\ar@setsig", "\ar@setul" and "\ar@setll" set sign,
% upper and lower limit of the array.
% "\ar@get", "\ar@getsig", "\ar@getul" and "\ar@getll"
% are used to access the respective command sequences.
%    \begin{macrocode}
\def\ar@set#1#2#3{\expandafter\edef\csname#1@\number#2\endcsname{%
   \number#3}}
\def\ar@get#1#2{\csname#1@\number#2\endcsname}
\def\ar@setsig#1#2{\expandafter\edef\csname#1@sig\endcsname{#2}}
\def\ar@getsig#1{\csname#1@sig\endcsname}
\def\ar@getul#1{\csname#1@ul\endcsname}
\def\ar@getll#1{\csname#1@ll\endcsname}
\def\ar@setul#1#2{\expandafter\edef\csname#1@ul\endcsname{\number#2}}
\def\ar@setll#1#2{\expandafter\edef\csname#1@ll\endcsname{\number#2}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsection{Miscellaneous}
%
% \begin{macro}{\fp@settomax}
% The macro "\fp@settomax" assigns the maximum of the two
% numbers given as "#2" and "#3" to the counter "#1".
%    \begin{macrocode}
\def\fp@settomax#1#2#3{%
   \ifnum#2<#3\relax
      #1=#3\relax
   \else
      #1=#2\relax
   \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@settomin}
% The macro "\fp@settomin" does the same with the minimum.
%    \begin{macrocode}
\def\fp@settomin#1#2#3{%
   \ifnum#2<#3\relax
      #1=#2\relax
   \else
      #1=#3\relax
   \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@modulo}
% The macro "\fp@modulo" computes the result of $\mbox{\#1}\bmod
% \mbox{\#2}$ and saves it in "\fp@param".
%    \begin{macrocode}
\def\fp@modulo#1#2{%
   \fp@tempcount=#1\relax
   \fp@tempcountii=#1\relax
   \divide\fp@tempcountii#2\relax
   \multiply\fp@tempcountii#2\relax
   \advance\fp@tempcount-\fp@tempcountii
   \edef\fp@param{\number\fp@tempcount}}
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{Setting and getting register contents}
%
% \begin{macro}{\fp@regread}
% \begin{macro}{\fp@regread@raw}
% The macro "\fp@regread" reads the string or command sequence
% (after expansion) given as "#2" into register "#1".
% The main work is done by the subroutine
% "\fp@readchars", where "\fp@tempcount" is used to indicate
% the current position. "\fp@arrayname" is used to pass
% "#1" to "\fp@readchars".
%    \begin{macrocode}
\def\fp@regread#1#2{%
   \fp@regread@raw{#1}{#2}%
   \fp@cleanreg{#1}}
\def\fp@regread@raw#1#2{%
%    \end{macrocode}
% Initialize "\fp@tempcount".
% Initialize "\fp@arrayname".
% Make "#1" positive by default.
%    \begin{macrocode}
   \fp@tempcount=0
   \edef\fp@arrayname{#1}%
   \ar@setsig{#1}{+}%
%    \end{macrocode}
% Now call "\fp@readchars" with "#2" fully expanded,
% followed by a decimal sign. The decimal sign is necessary because
% "\fp@readchars" expects at least one decimal sign to occur in the
% given string, so if "#2" is, say, "100", this will make it
% readable. On the other hand, a superficial decimal sign at the end
% of a number like $1.34$ will be ignored.
%    \begin{macrocode}
   \edef\fp@scratch{#2\fp@decimalsign}%
   \expandafter\fp@readchars\fp@scratch\end
%    \end{macrocode}
% If the first character of "#2" has been a decimal sign, the upper
% limit will be wrong, no pre-point digits will be present.
% This does not conform the internal syntax and is
% corrected now.
%    \begin{macrocode}
   \ifnum\ar@getul{#1}=-1
      \ar@setul{#1}{0}%
      \ar@set{#1}{0}{0}%
   \fi
%    \end{macrocode}
% The $n$ digits before the decimal sign (if any) have been
% read in from left to right, assigning positions from
% $0\ldots n$, so they have to be swapped to
% their correct positions. This is done with two counters,
% one starting as $0$, the other as $n$, using
% "\fp@scratch" for temporary storage.
%    \begin{macrocode}
   \fp@tempcount=0
   \fp@tempcountii=\ar@getul{#1}\relax
   \iloop
   \ifnum\fp@tempcount<\fp@tempcountii
      \edef\fp@scratch{\ar@get{#1}{\fp@tempcountii}}%
      \ar@set{#1}{\fp@tempcountii}{\ar@get{#1}{\fp@tempcount}}%
      \ar@set{#1}{\fp@tempcount}{\fp@scratch}%
      \advance\fp@tempcount by 1
      \advance\fp@tempcountii by -1
   \irepeat
}% end \fp@regread@raw
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\fp@readchars}
% As mentioned above, this subroutine is called by
% "\fp@regread" to do the actual work of reading
% the given number character after character into the register
% passed using "\fp@arrayname". It will stop if it sees
% an \fbox{\tt end} token.
%    \begin{macrocode}
\def\fp@readchars#1{%
   \ifx#1\end
%    \end{macrocode}
% If the condition is true, the token read before has been the final
% one. So at the end, do not call "\fp@readchars" any more, and use
% the current value of "\fp@tempcount" to assign the correct
% lower limit to the register.
%    \begin{macrocode}
      \let\inext=\relax
      \ifnum\fp@tempcount<0
         \advance\fp@tempcount by 1
         \ar@setll{\fp@arrayname}{\fp@tempcount}%
      \else
         \ar@setll{\fp@arrayname}{0}%
      \fi
   \else % \ifx#1\end
%    \end{macrocode}
% If the condition is false, further characters will
% follow, so "\fp@readchars" will have to be called
% again after finishing this character.
%    \begin{macrocode}
      \let\inext=\fp@readchars
%    \end{macrocode}
% Now check the character and perform the respective actions.
%    \begin{macrocode}
      \ifx#1+%
%    \end{macrocode}
% An optional `"+"' has been encountered, nothing to do.
%    \begin{macrocode}
      \else
         \ifx#1-%
%    \end{macrocode}
% `"-"' sign, toggle sign.
%    \begin{macrocode}
            \if\ar@getsig{\fp@arrayname}-%
               \ar@setsig{\fp@arrayname}{+}%
            \else
               \ar@setsig{\fp@arrayname}{-}%
            \fi
         \else
            \if\noexpand#1\fp@decimalsign%
%    \end{macrocode}
% A decimal sign has been encountered. So, if it is the first
% one, switch to reading afterpoint digits, otherwise ignore it.
%    \begin{macrocode}
               \ifnum\fp@tempcount>-1
                  \advance\fp@tempcount by -1
                  \ar@setul{\fp@arrayname}{\fp@tempcount}%
                  \fp@tempcount=-1
               \fi
            \else
%    \end{macrocode}
% None of the above characters was encountered, so assume
% a digit, and read it into the current position. Then step
% "\fp@tempcount" by $+1$ if prepoint digits are read in,
% or by $-1$ if the decimal sign has already been seen.
%    \begin{macrocode}
               \ar@set{\fp@arrayname}{\fp@tempcount}{#1}%
               \ifnum\fp@tempcount<0
                  \advance\fp@tempcount by -1
               \else
                  \advance\fp@tempcount by 1
               \fi
            \fi% end \if\noexpand#1\fp@decimalsign
         \fi% end \ifx#1-
      \fi% end \ifx#1+
   \fi% end \ifx#1\end
%    \end{macrocode}
% That's all, call "\inext".
%    \begin{macrocode}
   \inext
}% end \fp@readchars
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@regget}
% The macro "\fp@regget" is used to read the contents of the
% register "#1" into the command sequence "#2".
%    \begin{macrocode}
\def\fp@regget#1#2{%
%    \end{macrocode}
% First, we get the sign of the number. If negative,
% "#2" is initialized as `"-"', otherwise as empty.
%    \begin{macrocode}
   \if\ar@getsig{#1}-%
      \def#2{-}%
   \else
      \def#2{}%
   \fi
%    \end{macrocode}
% Then we set up "\fp@tempcount" as the counter for an "\iloop",
% starting at the upper limit of "#1".
%    \begin{macrocode}
   \fp@tempcount=\ar@getul{#1}\relax
   \iloop
%    \end{macrocode}
% If the "\fp@tempcount" is $-1$, we have to append a decimal sign.
%    \begin{macrocode}
      \ifnum\fp@tempcount=-1
         \edef#2{#2\fp@decimalsign}%
      \fi
%    \end{macrocode}
% Now append the corresponding digit.
%    \begin{macrocode}
      \edef#2{#2\ar@get{#1}{\fp@tempcount}}%
%    \end{macrocode}
% And repeat if the lower limit of "#1" is not yet reached.
%    \begin{macrocode}
   \ifnum\fp@tempcount>\ar@getll{#1}\relax
      \advance\fp@tempcount by -1
   \irepeat
}% end \def\fp@regget
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@cleanreg}
% The macro "\fp@cleanreg" will clean up the given register.
% This means that leading and trailing zeros will be
% removed, and that $-0$ will be turned into $+0$
% to be recognised as equal later on.
%    \begin{macrocode}
\def\fp@cleanreg#1{%
%    \end{macrocode}
% First, we will iterate until all leading zeros
% have been removed, except for digit $0$ that it is
% expected to be `"0"' for all numbers $n$ with $-1<n<1$.
%    \begin{macrocode}
   \fp@tempcount=\ar@getul{#1}\relax
   \iloop
   \ifnum\fp@tempcount>0
      \ifnum\ar@get{#1}{\fp@tempcount}=0
%    \end{macrocode}
% If this is true, the first digit is a zero and is `removed'
% by changing the upper limit. It is not necessary to
% erase it by setting the array element to "\empty" or something
% like that, because it will not be looked at any more.
%    \begin{macrocode}
         \advance\fp@tempcount by -1
         \ar@setul{#1}{\fp@tempcount}%
      \else
%    \end{macrocode}
% So the condition is false, the first digit is not a zero
% and the following ones need not to be looked at.
%    \begin{macrocode}
         \fp@tempcount=0
      \fi
   \irepeat
%    \end{macrocode}
% Similarly, the trailing zeros are removed.
%    \begin{macrocode}
   \fp@tempcount=\ar@getll{#1}\relax
   \iloop
   \ifnum\fp@tempcount<0
      \ifnum\ar@get{#1}{\fp@tempcount}=0
         \advance\fp@tempcount by 1
         \ar@setll{#1}{\fp@tempcount}%
      \else
         \fp@tempcount=0
      \fi
   \irepeat
%    \end{macrocode}
% Now check if the number is zero, using
% $(\mbox{x@ll}=\mbox{x@ul})\wedge(\mbox{x@0}=0)\Longleftrightarrow
% \rm x=0$, and set the sign to `"+"' if this is the case.
%    \begin{macrocode}
   \ifnum\ar@getll{#1}=\ar@getul{#1}\relax
      \ifnum\ar@get{#1}{0}=0\relax
         \ar@setsig{#1}{+}%
      \fi
   \fi
}% end \fp@regclean
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@getdigit}
% The macro "\fp@getdigit" will return the digit number "#2" of
% register "#1" using "\fp@setparam". If "#2" is outside the
% boundaries of the array, `"0"' is returned. (Which is not only
% sensible, but also mathematically correct.)
%    \begin{macrocode}
\def\fp@getdigit#1#2{%
   \ifnum#2<\ar@getll{#1}\relax
      \fp@setparam0%
   \else
      \ifnum#2>\ar@getul{#1}\relax
         \fp@setparam0%
      \else
         \fp@setparam{\ar@get{#1}{#2}}%
      \fi
   \fi
}% end \fp@getdigit
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@shiftright}
% The macro "\fp@shiftright" takes register "#1" and shifts the decimal
% sign "#2" digits to the right ("#2" may be negative or zero, too,
% so there is no need for a "\fp@shiftleft").
% The digits are read into "\fp@shiftnum", inserting the decimal
% sign at the new place. Then, "\fp@shiftnum" is read
% into "#1" via "\fp@regread".
%    \begin{macrocode}
\def\fp@shiftright#1#2{%
%    \end{macrocode}
% First, save the value of "#2" in "\fp@shiftamount".
% This makes it possible to say, e.\,g., 
% "\fpshiftright{exmpl}{\fp@tempcount}" without side-effects.
%    \begin{macrocode}
   \edef\fp@shiftamount{\number#2}%
%    \end{macrocode}
% Now, determine the start position.
% The maximum of the upper limit and "-\fp@shiftamount" is used
% in order to allow the decimal sign of, e.\,g.,
% $1.1$ to be shifted $-5$ digits to the right.
%    \begin{macrocode}
   \fp@settomax{\fp@tempcount}{\ar@getul{#1}}{-\fp@shiftamount}%
%    \end{macrocode}
% Similarly, determine the stop position.
%    \begin{macrocode}
   \fp@settomin{\fp@tempcountii}{\ar@getll{#1}}{-\fp@shiftamount}%
%    \end{macrocode}
% Now, initialize "\fp@shiftnum" and begin the "\iloop".
% Read digit after digit using "\fp@getdigit", therefore
% getting a `"0"' outside the boundaries. Insert the
% decimal sign at the new position given by
% "-\fp@shiftamount".
%    \begin{macrocode}
   \def\fp@shiftnum{}%
   \iloop
      \fp@getdigit{#1}{\fp@tempcount}%
      \edef\fp@shiftnum{\fp@shiftnum\fp@param}%
      \ifnum\fp@tempcount=-\fp@shiftamount\relax
         \edef\fp@shiftnum{\fp@shiftnum\fp@decimalsign}%
      \fi
   \ifnum\fp@tempcount>\fp@tempcountii
      \advance\fp@tempcount by -1
   \irepeat
%    \end{macrocode}
% Finally, assign the value to "#1".
%    \begin{macrocode}
   \fp@regread{#1}{\fp@shiftnum}%
}% end \fp@shiftright
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@firstnonzero}
% The macro "\fp@firstnonzero" returns the first non-zero
% digit of register "#1" via "\fp@setparam".
%    \begin{macrocode}
\def\fp@firstnonzero#1{%
%    \end{macrocode}
% If "#1" is zero, the "\iloop" below will run infinitely,
% so this case has to be checked separately by comparing
% "#1" to the internal register "@0" which holds zero.
% `"0"' is returned if "#1" is zero.
%    \begin{macrocode}
   \fp@regcomp{#1}{@0}%
   \if\fp@param=%
      \fp@setparam0%
%    \end{macrocode}
% Otherwise, each digit is checked, starting at the upper limit,
% and the position of first digit differing from zero is 
% returned in "\fp@param".
%    \begin{macrocode}
   \else
      \fp@tempcount=\ar@getul{#1}\relax%
      \fp@tempcountii=\ar@getll{#1}\relax%
      \iloop
         \ifnum\ar@get{#1}{\fp@tempcount}>0
            \fp@setparam{\number\fp@tempcount}%
            \fp@tempcount=\fp@tempcountii
         \fi
      \ifnum\fp@tempcount>\fp@tempcountii
         \advance\fp@tempcount by -1
      \irepeat
   \fi
}% end \fp@firstnonzero
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{Comparison of registers}
%
% \begin{macro}{\fp@regcomp}
% The macro "\fp@regcomp" compares the two specified registers.
% It saves the result of the comparison (either `"<"', `">"',
% or `"="') in "\fp@param". First, it checks whether the
% two numbers have the same sign or not. If not,
% the comparison is very easy, otherwise "\fp@regcomp@main"
% is called to do the work.
%    \begin{macrocode}
\def\fp@regcomp#1#2{%
   {%
      \if\ar@getsig{#1}-%
         \if\ar@getsig{#2}-%
            \fp@regcomp@main{#1}{#2}<>%
         \else
            \fp@setparam{<}%
         \fi
      \else
         \if\ar@getsig{#2}-%
            \fp@setparam{>}%
         \else
            \fp@regcomp@main{#1}{#2}><%
         \fi
      \fi
   }%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@regcomp@main}
% The macro "\fp@regcomp@main" takes four parameters:
% The two registers to be compared, and two tokens
% to be used as result. This is needed because
% if, e.\,g., two numbers have the same sign and
% are equal for all positions greater than
% $10^2$, and number~1 has `"9"' at position $10^2$ and number~2
% has `"5"', then the result must be `"<"' if $n_1<n_2<0$,
% but `">"' if $n_1>n_2>0$.
%
% First, the range of digits to compare is determined.
% Then, each pair of digits is compared. If different,
% "\fp@param" is set and the loop is terminated by
% setting the loop counter to the stop position.
% If the digits are equal and there are no more digits
% to compare, the numbers are equal.
%    \begin{macrocode}
\def\fp@regcomp@main#1#2#3#4{%
   \fp@settomax{\fp@loopcount}{\ar@getul{#1}}{\ar@getul{#2}}%
   \fp@settomin{\fp@loopcountii}{\ar@getll{#1}}{\ar@getll{#2}}%
   \loop
      \fp@getdigit{#1}{\fp@loopcount}%
      \fp@tempcount=\fp@param\relax
      \fp@getdigit{#2}{\fp@loopcount}%
      \fp@tempcountii=\fp@param\relax
      \ifnum\fp@tempcount<\fp@tempcountii
         \fp@setparam{#4}%
         \fp@loopcount=\fp@loopcountii
      \else
         \ifnum\fp@tempcount>\fp@tempcountii
            \fp@setparam{#3}%
            \fp@loopcount=\fp@loopcountii
         \else
            \ifnum\fp@loopcount=\fp@loopcountii
               \fp@setparam{=}%
            \fi
         \fi
      \fi
   \ifnum\fp@loopcount>\fp@loopcountii
      \advance\fp@loopcount by -1
   \repeat
}% end \fp@regcomp@main
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{Unary Operations}
%
% \begin{macro}{\fp@regabs}
% The macro "\fp@regabs" turns register "#1" into its amount.
% This is rather trivial: just set the sign to `"+"'.
%    \begin{macrocode}
\def\fp@regabs#1{%
   \ar@setsig{#1}{+}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@regneg}
% The macro "\fp@regneg" negates register "#1". It checks
% whether the actual sign is `"+"' or `"-"' and sets it
% to its opposite, except that nothing is done if the
% number is zero.
%    \begin{macrocode}
\def\fp@regneg#1{%
   \if\ar@getsig{#1}-%
      \ar@setsig{#1}{+}%
   \else
      \fp@regcomp{#1}{@0}%
      \if\fp@param=%
      \else
         \ar@setsig{#1}{-}%
      \fi
   \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@reground}
% The macro "\fp@reground" rounds register "#1" with a target accuracy
% given as "#2" (as a power of ten).
%    \begin{macrocode}
\def\fp@reground#1#2{%
%    \end{macrocode}
% Fist, if the desired accuracy is smaller than the lower limit of 
% "#1", nothing has to be done.
%    \begin{macrocode}
   \ifnum#2>\ar@getll{#1}\relax
      {%
%    \end{macrocode}
% Otherwise, we check the following digit. If it is greater than four, 
% we have to advance digit "#2" before truncating the number. This 
% means adding $10^{\mathtt{\#2}}$ for positive "#1" and subtracting
% $10^{\mathtt{\#2}}$ for negative "#1".
%    \begin{macrocode}
         \fp@tempcount=#2\relax
         \advance\fp@tempcount by -1
         \fp@getdigit{#1}{\fp@tempcount}%
         \ifnum\fp@param>4
            \fp@regcopy{fp@temp}{@1}%
            \fp@shiftright{fp@temp}{#2}%
            \fp@regcomp{#1}{@0}%
            \if\fp@param<%
               \fp@regneg{fp@temp}%
            \fi
            \fp@regadd{#1}{fp@temp}%
         \fi
%    \end{macrocode}
% Afterwards, we set the lower limit to "#2". If "#2" is greater than 
% zero,
% we set the lower limit and all digits~$n$ with $0\leq n<\texttt{\#2}$
% to zero. Then we read the number using
% "\fp@regget", make it globally available and read it into "#1"
% after finishing the local group.
%    \begin{macrocode}
         \ifnum#2>0
            \fp@loopcount=#2\relax
            \iloop
               \ifnum\fp@loopcount>0
                  \advance\fp@loopcount by -1
                  \ar@set{#1}{\fp@loopcount}{0}%
            \irepeat
            \ar@setll{#1}{0}%
         \else
            \ar@setll{#1}{#2}%
         \fi
         \fp@regget{#1}{\fp@scratch}%
         \fp@setparam\fp@scratch
      }%
      \fp@regread{#1}{\fp@param}%
   \fi
} % end \fp@reground
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{Binary operations}
%
% \begin{macro}{\fp@regcopy}
% The macro "\fp@regcopy" assigns the value of register
% "#2" to register "#1". This is done simply by reading
% register "#2" into a scratch control sequence
% and then reading this into register "#1".
%    \begin{macrocode}
\def\fp@regcopy#1#2{%
   \fp@regget{#2}{\fp@scratch}%
   \fp@regread{#1}{\fp@scratch}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@regadd}
% The macro "\fp@regadd" adds the value of register "#2" to
% register "#1".
%    \begin{macrocode}
\def\fp@regadd#1#2{%
   {%
%    \end{macrocode}
% First, check whether the two numbers have the same sign.
%    \begin{macrocode}
      \if\ar@getsig{#1}\ar@getsig{#2}%
%    \end{macrocode}
% If the two numbers have the same sign, the addition can be
% done by adding each two corresponding digits and a possible
% carryover, starting at $\min(\mbox{ll1},\mbox{ll2})$,
% ending at $\max(\mbox{ul1},\mbox{ul2})$. Those values
% are saved in "\fp@add@start" and "\fp@add@finish".
%    \begin{macrocode}
         \fp@settomin{\fp@loopcount}{\ar@getll{#1}}{\ar@getll{#2}}%
         \edef\fp@add@start{\number\fp@loopcount}%
         \fp@settomax{\fp@tempcount}{\ar@getul{#1}}{\ar@getul{#2}}%
         \edef\fp@add@finish{\number\fp@tempcount}%
%    \end{macrocode}
% Initialize "\fp@carryover".
%    \begin{macrocode}
         \fp@carryover=0
%    \end{macrocode}
% Now start the main loop. Each digit is computed
% in counter "\fp@result" as the
% sum of the corresponding digits plus the carryover from
% the previous pair. If the sum is greater than 10,
% it is reduced by 10 and "\fp@carryover" is set to 1.
% (No sum greater than 19 is possible.)
%    \begin{macrocode}
         \loop
            \fp@getdigit{#1}{\fp@loopcount}%
            \fp@result=\fp@param\relax
            \fp@getdigit{#2}{\fp@loopcount}%
            \advance\fp@result by \fp@param\relax
            \advance\fp@result by \fp@carryover
            \ifnum\fp@result>9
               \fp@carryover=1
               \advance\fp@result by -10
            \else
               \fp@carryover=0
            \fi
            \ar@set{#1}{\fp@loopcount}{\fp@result}%
         \ifnum\fp@loopcount<\fp@add@finish\relax
            \advance\fp@loopcount by 1
         \repeat
%    \end{macrocode}
% If the last pair had a carryover, take it into account.
% Then adjust the lower and upper limit of the result.
%    \begin{macrocode}
         \ifnum\fp@carryover>0
            \advance\fp@loopcount by 1
            \ar@set{#1}{\fp@loopcount}{\fp@carryover}%
         \fi
         \ar@setll{#1}{\fp@add@start}%
         \ar@setul{#1}{\fp@loopcount}%
%    \end{macrocode}
% Finally, save the result in "\fp@param" to make it survive
% the endgroup character after "\fi".
%    \begin{macrocode}
         \fp@regget{#1}{\fp@scratch}%
         \fp@setparam\fp@scratch
%    \end{macrocode}
% That's it. But if the two numbers have different signs,
% the situation is a bit more complicated. In this case,
% the amounts of "#1" and "#2" are saved in two temporary registers
% ("fp@tempi" and "fp@tempii"). The smaller one is subtracted
% from the larger one, and the sign of the result is
% adjusted according to the sign of "#1" and "#2".
% This is done by the subroutine "\fp@regadd@sub", which also takes 
% care of saving the result in "\fp@param".
%    \begin{macrocode}
      \else % \if sign
         \fp@regcopy{fp@tempi}{#1}%
         \fp@regcopy{fp@tempii}{#2}%
         \fp@regabs{fp@tempi}%
         \fp@regabs{fp@tempii}%
         \fp@regcomp{fp@tempi}{fp@tempii}%
         \if\fp@param>%
            \fp@regadd@sub{#1}{fp@tempi}{fp@tempii}%
         \else
            \fp@regadd@sub{#2}{fp@tempii}{fp@tempi}%
         \fi
      \fi % end \if sign
%    \end{macrocode}
% Now end the group to keep everything local, and read
% the result in "\fp@param" into register "#1".
%    \begin{macrocode}
   }%
   \fp@regread{#1}{\fp@param}%
}% end \fp@regadd
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@regadd@sub}
% The macro "\fp@regadd@sub" is a subroutine of
% "\fp@regadd".
%    \begin{macrocode}
\def\fp@regadd@sub#1#2#3{%
%    \end{macrocode}
% First, subtract "#3" from "#2". The restriction $\mbox{\tt\#2}>
% \mbox{\tt\#3}$ is ensured by the calling "\fp@regadd".
%    \begin{macrocode}
   \fp@regsub@restricted{#2}{#3}%
%    \end{macrocode}
% "#1" is the original number of which "#2" is the amount.
% So, if it is negative, the final result also has to be negative.
% This is done by the following four lines.
%    \begin{macrocode}
   \fp@regcomp{#1}{@0}%
   \if\fp@param<%
      \fp@regneg{#2}%
   \fi
%    \end{macrocode}
% Now, the final result is stored in "#2". Make it
% globally available using "\fp@setparam".
%    \begin{macrocode}
   \fp@regget{#2}{\fp@scratch}%
   \fp@setparam\fp@scratch
}% end \fp@regadd@sub
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@regsub@restricted}
% The macro "\fp@regsub@restricted" does the actual
% work of subtracting "#2" from "#1", provided that
% "#1" is greater than "#2". It is called by
% "\fp@regadd@sub" and by "\fp@regdiv".
%    \begin{macrocode}
\def\fp@regsub@restricted#1#2{%
%    \end{macrocode}
% First, we start a group to keep counters etc.\ local.
% Then, we determine the start and end position for the
% loop, as above for "\fp@regadd".
%    \begin{macrocode}
   {%
      \fp@settomin{\fp@loopcount}{\ar@getll{#1}}{\ar@getll{#2}}%
      \edef\fp@lowermin{\number\fp@loopcount}%
      \fp@settomax{\fp@tempcount}{\ar@getul{#1}}{\ar@getul{#2}}%
      \edef\fp@uppermin{\number\fp@tempcount}%
%    \end{macrocode}
% Now subtract the corresponding digits, taking into
% account a possible carryover.
%    \begin{macrocode}
      \fp@carryover=0
      \loop
         \fp@getdigit{#1}{\fp@loopcount}%
         \fp@result=\fp@param\relax
         \fp@getdigit{#2}{\fp@loopcount}%
         \advance\fp@result by -\fp@param\relax
         \advance\fp@result by \fp@carryover
%    \end{macrocode}
% If the result is $<0$, add 10 to the result
% and set the carryover to $-1$.
%    \begin{macrocode}
         \ifnum\fp@result<0
            \fp@carryover=-1
            \advance\fp@result by 10
         \else
            \fp@carryover=0
         \fi
%    \end{macrocode}
% Now save the result and repeat if there are further
% digits.
%    \begin{macrocode}
         \ar@set{#1}{\fp@loopcount}{\fp@result}%
      \ifnum\fp@loopcount<\fp@uppermin\relax
         \advance\fp@loopcount by 1
      \repeat
%    \end{macrocode}
% If there is a carryover for the last two digits,
% take it into account.
%    \begin{macrocode}
      \ifnum\fp@carryover=-1
         \advance\fp@loopcount by 1
         \ar@set{#1}{\fp@loopcount}{-1}%
      \fi
%    \end{macrocode}
% Now adjust the upper and lower limit of the result,
% and save it in "\fp@param".
%    \begin{macrocode}
      \ar@setll{#1}{\fp@lowermin}%
      \ar@setul{#1}{\fp@loopcount}%
   \fp@regget{#1}{\fp@scratch}%
   \fp@setparam\fp@scratch
   }%
%    \end{macrocode}
% Finally, assign the result to "#1" inside the current group.
%    \begin{macrocode}
   \fp@regread{#1}{\fp@param}%
}% end \fp@regsub@restricted
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fp@regsub}
% The macro "\fp@regsub" subtracts register "#2" from
% register "#1". This is done by negating "#2" inside
% a group and calling "\fp@regadd".
%    \begin{macrocode}
\def\fp@regsub#1#2{%
   {%
      \fp@regneg{#2}%
      \fp@regadd{#1}{#2}%
      \fp@regget{#1}{\fp@scratch}%
      \fp@setparam\fp@scratch
   }%
   \fp@regread{#1}{\fp@param}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@regmul}
% The macro "\fp@regmul" multiplies the value
% of register "#1" with the value of register "#2".
%    \begin{macrocode}
\def\fp@regmul#1#2{%
   {%
%    \end{macrocode}
% First, we initialize the temporary register "fp@temp1"
% as zero; it will be used to hold the results so far.
% Then we start the outer "\xloop" which will
% run through all digits of "#2", beginning at the lower limit.
%    \begin{macrocode}
      \fp@regcopy{fp@temp1}{@0}%
      \fp@loopcountii=\ar@getll{#2}\relax
      \xloop
%    \end{macrocode}
% Then we initialize the inner loop, which multplies the
% current digit of "#2" with "#1" digit after digit,
% saving the result in "\fp@newnum".
%    \begin{macrocode}
         \fp@loopcount=\ar@getll{#1}\relax
         \fp@carryover=0
         \def\fp@newnum{}%
         \loop
            \fp@result=\ar@get{#2}{\fp@loopcountii}\relax
            \multiply\fp@result by \ar@get{#1}{\fp@loopcount}\relax
            \advance\fp@result by \fp@carryover
%    \end{macrocode}
% If the result is greater than~9, we set the carryover
% as $(\mbox{\tt\bslash fp@result}\bmod 10)$ and
% the result to $(\mbox{\tt\bslash fp@result}\mathop{\mbox{div}}10)$.
%    \begin{macrocode}
            \ifnum\fp@result>9
               \fp@carryover=\fp@result
               \divide\fp@carryover by 10
               \fp@tempcount=\fp@carryover
               \multiply\fp@tempcount by 10
               \advance\fp@result by -\fp@tempcount
            \else
               \fp@carryover=0
            \fi
            \edef\fp@newnum{\number\fp@result\fp@newnum}%
         \ifnum\fp@loopcount<\ar@getul{#1}\relax
            \advance\fp@loopcount by 1
         \repeat
         \edef\fp@newnum{\number\fp@carryover\fp@newnum}%
         \fp@regread{fp@temp2}{\fp@newnum}%
%    \end{macrocode}
% Now "fp@temp2" holds the partial result for this digit of
% "#2". We have to multiply it with $10^n$, if $n$ is the
% number of digits of "#2" completed so far.
% This is done by calling "\fp@shiftright" with $-n$ as
% second argument.
%    \begin{macrocode}
         \fp@tempcount=\fp@loopcountii
         \advance\fp@tempcount by -\number\ar@getll{#2}\relax
         \fp@shiftright{fp@temp2}{\fp@tempcount}%
%    \end{macrocode}
% Now we add "fp@temp2" to the results so far and iterate
% if there are further digits.
%    \begin{macrocode}
         \fp@regadd{fp@temp1}{fp@temp2}%
      \ifnum\fp@loopcountii<\ar@getul{#2}\relax
         \advance\fp@loopcountii by 1
      \xrepeat
%    \end{macrocode}
% The final result of the multiplication will have
% as much afterpoint digits as "#1" and "#2" have together.
% Adjust this.
%    \begin{macrocode}
      \fp@tempcount=\ar@getll{#1}\relax
      \advance\fp@tempcount by \ar@getll{#2}\relax
      \fp@shiftright{fp@temp1}{\fp@tempcount}%
%    \end{macrocode}
% If "#1" and "#2" have different signs, the result is negative,
% otherwise positive.
%    \begin{macrocode}
      \if\ar@getsig{#1}\ar@getsig{#2}%
      \else
         \fp@regneg{fp@temp1}%
      \fi
%    \end{macrocode}
% Finally, save the result via "\fp@setparam" and assign it
% to "#1" after the end of the group.
%    \begin{macrocode}
   \fp@regget{fp@temp1}{\fp@scratch}%
   \fp@setparam\fp@scratch
   }%
   \fp@regread{#1}{\fp@param}%
} % end \fp@regmul
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@regdiv}
% The macro "\fp@regdiv" divides register "#1" by register "#2".
% It works by repeated subtraction.
%    \begin{macrocode}
\def\fp@regdiv#1#2{%
   {%
%    \end{macrocode}
% The amount of the two numbers is read into the two
% temporary registers "fp@temp1" and "fp@temp2".
%    \begin{macrocode}
      \fp@regcopy{fp@temp1}{#1}%
      \fp@regcopy{fp@temp2}{#2}%
      \fp@regabs{fp@temp1}%
      \fp@regabs{fp@temp2}%
%    \end{macrocode}
% First, we determine the initial shift for "fp@temp2".
% This is the shift which will make "fp@temp2" have as many
% digits before the decimal sign as "fp@temp1".
% "\fp@firstnonzero" is used, because the upper limit
% need not be the first non-zero digit.
%    \begin{macrocode}
      \fp@firstnonzero{fp@temp1}%
      \fp@loopcountii=\fp@param\relax
      \fp@firstnonzero{fp@temp2}%
      \advance\fp@loopcountii by -\fp@param\relax
      \fp@shiftright{fp@temp2}{\fp@loopcountii}%
%    \end{macrocode}
% Now we initialize "\fp@divnum" which will hold the result.
% If "\fp@loopcountii" is smaller than zero, i.\,e., if
% the first digit of the result that will be computed
% is after the decimal sign, we have to
% initialize "\fp@divnum" with the decimal sign as well
% as with an appropriate number of zeros following it.
%    \begin{macrocode}
      \def\fp@divnum{}%
      \ifnum\fp@loopcountii<0
         \fp@tempcount=\fp@loopcountii
         \loop
         \ifnum\fp@tempcount<-1
            \edef\fp@divnum{0\fp@divnum}%
            \advance\fp@tempcount by 1
         \repeat
         \edef\fp@divnum{\fp@decimalsign\fp@divnum}%
      \fi
%    \end{macrocode}
% The main loop follows. Each digit is determined by
% subtracting the divisor $n$ times from the dividend until
% the result is smaller than the divisor.
% This is done only if "\fp@loopcountii" plus one
% is greater than "-\fp@accuracy". 
% If the divisor is equal to the dividend, the division is complete
% and the "\xloop" is terminated. Therefore, "\fp@accuracy" is locally
% set to `"0"', so that possibly following zeros are computed
% until the digit representing $10^0$.
% At the end, the divisor is divided
% by 10, and the next digit follows.
%    \begin{macrocode}
      \xloop
      \fp@tempcount=\fp@loopcountii
      \advance\fp@tempcount by 1
      \ifnum\fp@tempcount>-\fp@accuracy\relax
         \fp@loopcount=0
         \loop
            \fp@regcomp{fp@temp2}{fp@temp1}%
            \if\fp@param=%
               \def\fp@accuracy{0}%
               \gdef\fp@param{<}%
            \fi
         \if\fp@param<%
            \fp@regsub@restricted{fp@temp1}{fp@temp2}%
            \advance\fp@loopcount by 1
         \repeat
         \ifnum\fp@loopcountii=-1
            \edef\fp@divnum{\fp@divnum\fp@decimalsign}%
         \fi
         \edef\fp@divnum{\fp@divnum\number\fp@loopcount}%
         \fp@shiftright{fp@temp2}{-1}%
         \advance\fp@loopcountii by -1
      \xrepeat
%    \end{macrocode}
% The sign of the result is set according to the
% signs of "#1" and "#2".
%    \begin{macrocode}
      \if\ar@getsig{#1}\ar@getsig{#2}%
         \fp@regread{fp@temp1}{\fp@divnum}%
      \else
         \fp@regread{fp@temp1}{-\fp@divnum}%
      \fi
%    \end{macrocode}
% Now save the result in "\fp@param". After endgroup,
% read it into "#1".
%    \begin{macrocode}
      \fp@regget{fp@temp1}{\fp@scratch}%
      \fp@setparam\fp@scratch
   }%
   \fp@regread{#1}{\fp@param}%
}
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{User interface}
%
% \begin{macro}{\fp@call@bin}
% The macro "\fp@call@bin" is a common calling command
% used by the user commands for binary operations. It reads
% the values given in "#2" and "#3" into temporary registers,
% performs the operation specified in "#4",
% and finally assigns the result to the command sequence
% given as "#1".
%    \begin{macrocode}
\def\fp@call@bin#1#2#3#4{%
   {%
      \fp@regread{fp@user1}{#2}%
      \fp@regread{fp@user2}{#3}%
      \csname fp@reg#4\endcsname{fp@user1}{fp@user2}%
      \fp@regget{fp@user1}{\fp@scratch}%
      \fp@setparam\fp@scratch
   }%
   \edef#1{\fp@param}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpAdd}
% As described above, the main work is done by "\fp@call@bin",
% so this macro reduces to passing the parameters and
% specifying the desired operation.
%    \begin{macrocode}
\def\fpAdd#1#2#3{\fp@call@bin{#1}{#2}{#3}{add}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpSub}
% Just like "\fpAdd".
%    \begin{macrocode}
\def\fpSub#1#2#3{\fp@call@bin{#1}{#2}{#3}{sub}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpMul}
% Just like "\fpAdd".
%    \begin{macrocode}
\def\fpMul#1#2#3{\fp@call@bin{#1}{#2}{#3}{mul}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpDiv}
% Just like "\fpAdd".
%    \begin{macrocode}
\def\fpDiv#1#2#3{\fp@call@bin{#1}{#2}{#3}{div}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp@call@un}
% Similarly, the unary operations "\fpAbs" and "\fpNeg"
% refer to the common macro "\fp@call@un".
%    \begin{macrocode}
\def\fp@call@un#1#2#3{%
   {%
      \fp@regread{fp@user1}{#2}%
      \csname fp@reg#3\endcsname{fp@user1}%
      \fp@regget{fp@user1}{\fp@scratch}%
      \fp@setparam\fp@scratch
   }%
   \edef#1{\fp@param}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpAbs}
% Pass the information and specify the action.
%    \begin{macrocode}
\def\fpAbs#1#2{\fp@call@un{#1}{#2}{abs}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpNeg}
% Just like "\fpAbs".
%    \begin{macrocode}
\def\fpNeg#1#2{\fp@call@un{#1}{#2}{neg}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpRound}
% This macro does not fit into the scheme, so it has to be defined
% seperately.
%    \begin{macrocode}
\def\fpRound#1#2#3{%
   {%
      \fpRegSet{fp@user1}{#2}%
      \fpRegRound{fp@user1}{#3}%
      \fpRegGet{fp@user1}{\fp@scratch}%
      \fp@setparam\fp@scratch
   }%
   \edef#1{\fp@param}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpRegSet}
% The register operations "\fpRegSet", "\fpRegGet",
% "\fpRegAdd", "\fpRegSub", "\fpRegMul", "\fpRegDiv",
% "\fpRegAbs", "\fpRegNeg", "\fpRegCopy" and "\fpRegRound"
% have the same syntax as the internal variants, so their
% definitions reduce to passing the parameters. The register name
% is always given as the first parameter.
%    \begin{macrocode}
\def\fpRegSet#1#2{\fp@regread{#1}{#2}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpRegGet}
% As described above.
%    \begin{macrocode}
\def\fpRegGet#1#2{\fp@regget{#1}{#2}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpRegAdd}
% As described above.
%    \begin{macrocode}
\def\fpRegAdd#1#2{\fp@regadd{#1}{#2}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpRegSub}
% As described above.
%    \begin{macrocode}
\def\fpRegSub#1#2{\fp@regsub{#1}{#2}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpRegMul}
% As described above.
%    \begin{macrocode}
\def\fpRegMul#1#2{\fp@regmul{#1}{#2}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpRegDiv}
% As described above.
%    \begin{macrocode}
\def\fpRegDiv#1#2{\fp@regdiv{#1}{#2}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpRegAbs}
% As described above.
%    \begin{macrocode}
\def\fpRegAbs#1{\fp@regabs{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpRegNeg}
% As described above.
%    \begin{macrocode}
\def\fpRegNeg#1{\fp@regneg{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpRegCopy}
% As described above.
%    \begin{macrocode}
\def\fpRegCopy#1#2{\fp@regcopy{#1}{#2}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpRegRound}
% As described above.
%    \begin{macrocode}
\def\fpRegRound#1#2{\fp@reground{#1}{#2}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fpAccuracy}
% \begin{macro}{\fp@accuracy}
% The user command "\fpAccuracy" "\edef"s the internal
% parameter "\fp@accuracy", which stores the maximum
% number of digits after the decimal sign, i.\,e.,
% the minimum for the lower limit of fp numbers.
% At the moment, "\fp@accuracy" does not affect the accuracy
% of any operation except "\fp@regdiv". In fact, it was
% introduced when the definition of a termination condition
% for the loop was not possible without an externally given limit.
% "\fp@accuracy" is initialized to `"5"' digits after
% the decimal sign. 
%    \begin{macrocode}
\def\fpAccuracy#1{\edef\fp@accuracy{#1}}
\fpAccuracy{5}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\fpDecimalSign}
% \begin{macro}{\fp@decimalsign}
% The command "\fpDecimalSign" allows the user to select any character
% for use as the decimal sign. The character is stored in
% "\fp@decimalsign". Normally, the decimal sign will be either `"."' or
% `","'; a comma is the default. (Take a look at ISO~31-0, part 3.3.2,
% if you dislike this.)
%    \begin{macrocode}
\def\fpDecimalSign#1{\edef\fp@decimalsign{#1}}
\fpDecimalSign{,}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\fpThousandsep}
% \begin{macro}{\fp@thousandsep}
% Those macros are used to define and store a thousand seperator
% used by "\fp@regoutput". By default, there is none.
%    \begin{macrocode}
\def\fpThousandSep#1{\edef\fp@thousandsep{#1}}
\fpThousandSep{}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsection{Constants}
%
% \begin{macro}{@0}
% \begin{macro}{@1}
% The number zero ist stored
% in register "@0", the number one in register "@1".
%    \begin{macrocode}
\fp@regread{@0}{0}
\fp@regread{@1}{1}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \subsection{Finish}
% Finally, restore the catcode of `"@"' and "\endinput".
%    \begin{macrocode}
\catcode`\@=\atcatcode\relax
\endinput
%</fltmain>
%    \end{macrocode}
% \Finale
% \PrintIndex
% \PrintChanges
