%
% Base arithmetic functions
%

\newdimen\MFF@dimenA
\newdimen\MFF@dimenB
\newdimen\MFF@dimenC
\newdimen\MFF@dimenD

%
%  this code convert dimen (pt) into real value assigned to \@tempa
%
\def\MFF@convert#1{\@ovxx=#1\relax \@negargfalse
    \ifdim \@ovxx<0pt \@ovxx=-\@ovxx \@negargtrue \fi
    \@xarg=\@ovxx \@yarg=\@xarg
    \divide\@xarg by 65536\relax
    \@yyarg=\@xarg \multiply\@yyarg by 65536\relax
    \advance\@yarg by -\@yyarg
    \multiply\@yarg by 3125 \divide\@yarg by 2048
    \ifnum \@yarg > 9999 \def\@tempa{}%
       \else \ifnum \@yarg > 999 \def\@tempa{0}%
          \else \ifnum \@yarg > 99 \def\@tempa{00}%
             \else \ifnum \@yarg > 99 \def\@tempa{000}%
                \else \def\@tempa{0000}%
    \fi\fi\fi\fi
    \edef\@tempa{\if@negarg -\fi \the\@xarg.\@tempa\the\@yarg}%
}

% ************************************************************
% *** The following macros are partially taken from PiCTeX ***
% ************************************************************

% DIVISION  (Does long division of dimension registers)
% **   \MFF@divide{DIVIDEND}{DIVISOR}{RESULT}

% **  \MFF@divide DIVIDEND [by] DIVISOR [to get] ANSWER
% **  Divides the dimension DIVIDEND by the dimension DIVISOR, placing the
% **  quotient in the dimension register ANSWER.  Values are understood to
% **  be in points.  E.g.  12.5pt/1.4pt=8.92857pt.
% **  Quotient is accurate to 1/65536pt=2**[-16]pt
% **  |DIVISOR| should be < 8192pt = 113.36in
% **      --- otherwise acciracy is decreased in 2 times
\def\MFF@divide#1#2#3{%
\ifdim #2=\z@ #3=\z@\relax
\else
  \MFF@dimenB=#1\relax%             **  dimB  holds current remainder (r)
  \MFF@dimenC=#2\relax%             **  dimC  holds divisor (d)
  \ifdim\MFF@dimenC<\z@
        \MFF@dimenB=-\MFF@dimenB \MFF@dimenC=-\MFF@dimenC
  \fi
  \@negargfalse
  \ifdim \MFF@dimenB<\z@ \MFF@dimenB=-\MFF@dimenB \@negargtrue \fi
  \ifdim \MFF@dimenC<8192pt\relax
  \else
         \MFF@dimenB=0.5\MFF@dimenB
         \MFF@dimenC=0.5\MFF@dimenC
  \fi
  \MFF@dimenD=\MFF@dimenB%          **  dimD  holds quotient q=r/d for this
  \divide \MFF@dimenD \MFF@dimenC%  **    step, in units of scaled pts
  \MFF@dimenA=\MFF@dimenD%          **  dimA  eventually holds answer (a)
  \multiply\MFF@dimenD \MFF@dimenC% **  r <-- r - dq
  \advance\MFF@dimenB -\MFF@dimenD% **  First step complete. Have integer part
%                                   **  of a, and corresponding remainder.
  \MFF@dimenD=\MFF@dimenC%          **  Temporarily use dimD to hold |d|
  \ifdim\MFF@dimenD<64pt%           **  Branch on the magnitude of |d|
    \MFF@divstep[256]\MFF@divstep[256]%
  \else
% **  The following code handles divisors  d  with
% **    (1)  .88in  =  64pt  <= d <  256pt =  3.54in
% **    (2) 3.54in  = 256pt  <= d < 2048pt = 28.34in
% **    (3) 28.34in = 2048pt <= d < 8192pt = 113.36in
% **  Anything bigger than that may result in an overflow condition.
% **  For our purposes, we should never even see case (2) or (3).
     \ifdim\MFF@dimenD<256pt
       \MFF@divstep[64]\MFF@divstep[32]\MFF@divstep[32]%
     \else
       \ifdim\MFF@dimenD<2048pt
          \MFF@divstep[8]\MFF@divstep[8]\MFF@divstep[8]%
          \MFF@divstep[8]\MFF@divstep[4]\MFF@divstep[4]%
       \else
          \MFF@divstep[2]\MFF@divstep[2]\MFF@divstep[2]\MFF@divstep[2]%
          \MFF@divstep[2]\MFF@divstep[2]\MFF@divstep[2]\MFF@divstep[2]%
          \MFF@divstep[2]\MFF@divstep[2]\MFF@divstep[2]\MFF@divstep[2]%
          \MFF@divstep[2]\MFF@divstep[2]\MFF@divstep[2]\MFF@divstep[2]%
       \fi
     \fi
  \fi
  \if@negarg \MFF@dimenA=-\MFF@dimenA \fi
  #3=\MFF@dimenA
\fi\ignorespaces}

% **  The following macro does the real long division work.
\def\MFF@divstep[#1]{%                  **  #1 = "B"
  \MFF@dimenB=#1\MFF@dimenB%            **  r <-- B*r
  \MFF@dimenD=\MFF@dimenB%              **  dimD  holds quotient q=r/d for this
    \divide \MFF@dimenD by \MFF@dimenC% **    step, in units of scaled pts
  \MFF@dimenA=#1\MFF@dimenA%            **  a <-- B*a + q
    \advance\MFF@dimenA by \MFF@dimenD%
  \multiply\MFF@dimenD by \MFF@dimenC%  **  r <-- r - dq
    \advance\MFF@dimenB by -\MFF@dimenD}


% MULTIPLICATION  (Does long multiplication of dimension registers)
% **   \MFF@multiply{FACTOR1}{FACTOR2}{RESULT}
% **  Result is accurate to 1/65536pt=2**[-16]pt
% **  |FACTOR2| should be < 8192pt = 113.36in
% **      --- otherwise acciracy is decreased in 2 times

\def\MFF@multiply#1#2#3{%
  \MFF@dimenB=#1\relax \MFF@dimenC=#2\relax
  \ifdim\MFF@dimenC<\z@
        \MFF@dimenB=-\MFF@dimenB \MFF@dimenC=-\MFF@dimenC
  \fi
  \@negargfalse
  \ifdim \MFF@dimenB<\z@ \MFF@dimenB=-\MFF@dimenB \@negargtrue \fi
  \ifdim \MFF@dimenC<8192pt\relax
  \else
         \MFF@dimenB=2\MFF@dimenB
         \MFF@dimenC=0.5\MFF@dimenC
  \fi
  % calculate integer part
  \@yarg=\MFF@dimenC \@xarg=65536
  \@yyarg=\@yarg \divide\@yyarg by \@xarg
  % multiplication by integer part
  \MFF@dimenA=\MFF@dimenB \multiply\MFF@dimenA by \@yyarg
  % prepare fraction part
  \multiply\@yyarg by \@xarg \advance\@yarg by -\@yyarg
  % multiplication cycle
  \ifdim\MFF@dimenB<64pt%
    \MFF@mulstep[256]\MFF@mulstep[256]%
  \else
     \ifdim\MFF@dimenB<256pt
       \MFF@mulstep[64]\MFF@mulstep[32]\MFF@mulstep[32]%
     \else
       \ifdim\MFF@dimenB<2048pt
          \MFF@mulstep[8]\MFF@mulstep[8]\MFF@mulstep[8]%
          \MFF@mulstep[8]\MFF@mulstep[4]\MFF@mulstep[4]%
       \else
          \MFF@mulstep[2]\MFF@mulstep[2]\MFF@mulstep[2]\MFF@mulstep[2]%
          \MFF@mulstep[2]\MFF@mulstep[2]\MFF@mulstep[2]\MFF@mulstep[2]%
          \MFF@mulstep[2]\MFF@mulstep[2]\MFF@mulstep[2]\MFF@mulstep[2]%
          \MFF@mulstep[2]\MFF@mulstep[2]\MFF@mulstep[2]\MFF@mulstep[2]%
       \fi
     \fi
  \fi
  % assign result
  \if@negarg \MFF@dimenA=-\MFF@dimenA \fi
  #3=\MFF@dimenA
\ignorespaces}

% perform partial multiplication
\def\MFF@mulstep[#1]{\divide\@xarg by #1
  \@yyarg=\@yarg \divide\@yyarg by \@xarg
  % calculate new additive component
  \MFF@dimenC=\MFF@dimenB \multiply\MFF@dimenC by \@yyarg
  \divide\MFF@dimenC by #1 \advance\MFF@dimenA by \MFF@dimenC
  % update fraction data
  \multiply\@yyarg by \@xarg \advance\@yarg by -\@yyarg
  \divide\MFF@dimenB by #1
}

% *********************************************
% ******** End of PiCTeX arith macros *********
% *********************************************

