% !TeX root = forth.tex
\chapter{The optional Double-Number word set} % 8
\wordlist{double}

\section{Introduction} % 8.1

Sixteen-bit Forth systems often use double-length numbers. However,
many Forths on small embedded systems do not, and many users of Forth
on systems with a cell size of 32 bits or more find that the use of
double-length numbers is much diminished. Therefore, the words that
manipulate double-length entities have been placed in this optional
word set.

\section{Additional terms and notation} % 8.2

None.

\section{Additional usage requirements} % 8.3

\subsection{Text interpreter input number conversion} % 8.3.2

When the text interpreter processes a number, except a \arg{cnum},
that is immediately followed by a decimal point and is not found
as a definition name, the text interpreter shall convert it to a
double-cell number.

For example, entering \word[core]{DECIMAL} \texttt{1234} leaves the
single-cell number \texttt{1234} on the stack, and entering
\word[core]{DECIMAL} \texttt{1234.} leaves the double-cell number
\texttt{1234} \texttt{0} on the stack.

See: \xref[3.4.1.3 Text interpreter input number conversion]{usage:numbers}.


\section{Additional documentation requirements} % 8.4

\subsection{System documentation} % 8.4.1

\subsubsection{Implementation-defined options} % 8.4.1.1

\begin{itemize}
\item no additional requirements.
\end{itemize}

\subsubsection{Ambiguous conditions} % 8.4.1.2

\begin{itemize}
\item \param{d} outside range of \param{n} in \wref{double:DtoS}{D>S}.
\end{itemize}

\subsubsection{Other system documentation} % 8.4.1.3

\begin{itemize}
\item no additional requirements.
\end{itemize}

\subsection{Program documentation} % 8.4.2

\begin{itemize}
\item no additional requirements.
\end{itemize}


\section{Compliance and labeling} % 8.5

\subsection{Forth-\snapshot{} systems} % 8.5.1

The phrase ``Providing the Double-Number word set'' shall be
appended to the label of any Standard System that provides all
of the Double-Number word set.

The phrase ``Providing \emph{name(s)} from the Double-Number
Extensions word set'' shall be appended to the label of any
Standard System that provides portions of the Double-Number
Extensions word set.

The phrase ``Providing the Double-Number Extensions word set''
shall be appended to the label of any Standard System that
provides all of the Double-Number and Double-Number Extensions
word sets.

\subsection{Forth-\snapshot{} programs} % 8.5.2

The phrase ``Requiring the Double-Number word set'' shall be
appended to the label of Standard Programs that require the
system to provide the Double-Number word set.

The phrase ``Requiring \emph{name(s)} from the Double-Number
Extensions word set'' shall be appended to the label of Standard
Programs that require the system to provide portions of the
Double-Number Extensions word set.

The phrase ``Requiring the Double-Number Extensions word set''
shall be appended to the label of Standard Programs that require
the system to provide all of the Double-Number and Double-Number
Extensions word sets.

\section{Glossary} % 8.6

\subsection{Double-Number words} % 8.6.1

\begin{worddef}{0360}{2CONSTANT}[two-constant]
\item \stack{x_1 x_2 "<spaces>name"}{}

	Skip leading space delimiters. Parse \param{name} delimited by
	a space. Create a definition for \param{name} with the execution
	semantics defined below.

	\param{name} is referred to as a ``two-constant''.

\execute[name]
	\stack{}{x_1 x_2}

	Place cell pair \param{x_1 x_2} on the stack.

\see \xref[3.4.1 Parsing]{usage:parsing},
	\rref{double:2CONSTANT}{}.


	\begin{rationale} % A.8.6.1.0360 2CONSTANT
		Typical use:
			\texttt{x1} \texttt{x2} \word{2CONSTANT} \emph{name}
	\end{rationale}

	\begin{testing}
		\test{1 2 \word{2CONSTANT} 2c1}{} \\
		\test{2c1}{1 2}

		\test{\word{:} cd1 2c1 \word{;}}{} \\
		\test{cd1}{1 2}

		\test{\word{:} cd2 \word{2CONSTANT} \word{;}}{} \\
		\test{-1 -2 cd2 2c2}{} \\
		\test{2c2}{-1 -2}

		\test{4 5 \word{2CONSTANT} 2c3 \word{IMMEDIATE} 2c3}{4 5} \\
		\test{\word{:} cd6 2c3 \word{2LITERAL} \word{;} cd6}{4 5}
	\end{testing}
\end{worddef}


\begin{worddef}{0390}{2LITERAL}[two-literal]
\interpret
	Interpretation semantics for this word are undefined.

\compile
	\stack{x_1 x_2}{}

	Append the run-time semantics below to the current definition.

\runtime
	\stack{}{x_1 x_2}

	Place cell pair \param{x_1 x_2} on the stack.

\see \rref{double:2LITERAL}{}.

	\begin{rationale} % A.8.6.1.0390 2LITERAL
		\setwordlist{core}
		Typical use:
			\word{:} \texttt{X} {\ldots}
				\word{[} \texttt{x1} \texttt{x2} \word{]} \word[double]{2LITERAL}
			{\ldots} \word{;}
		\setwordlist{double}
	\end{rationale}

	\begin{testing}
		\test{\word{:} cd1 \word{[} MAX-2INT \word{]} \word{2LITERAL} \word{;}}{}\\
		\test{cd1}{MAX-2INT}

		\test{\word{2VARIABLE} 2v4 \word{IMMEDIATE} 5 6 2v4 \word{2!}}{} \\
		\test{\word{:} cd7 2v4 \word{[} \word{2@} \word{]} \word{2LITERAL} \word{;} cd7}{5 6} \\
		\test{\word{:} cd8 \word{[} 6 7 \word{]} 2v4 \word{[} \word{2!} \word{]} \word{;} 2v4 \word{2@}}{6 7}
	\end{testing}
\end{worddef}


\begin{worddef}{0440}{2VARIABLE}[two-variable]
\item \stack{"<spaces>name"}{}

	Skip leading space delimiters. Parse \param{name} delimited by a
	space. Create a definition for \param{name} with the execution
	semantics defined below. Reserve two consecutive cells of data
	space.

	\param{name} is referred to as a ``two-variable''.

\execute[name]
	\stack{}{a-addr}

	\param{a-addr} is the address of the first (lowest address)
	cell of two consecutive cells in data space reserved by
	\word{2VARIABLE} when it defined \param{name}. A program is
	responsible for initializing the contents.

\see \xref[3.4.1 Parsing]{usage:parsing},
	\wref{core:VARIABLE}{VARIABLE},
	\rref{double:2VARIABLE}{}.

	\begin{rationale} % A.8.6.1.0440 2VARIABLE
		Typical use:
			\word{2VARIABLE} \param{name}
	\end{rationale}

	\begin{testing}
		\test{\word{2VARIABLE} 2v1}{} \\
		\test{0. 2v1 \word{2!}}{  } \\
		\test{   2v1 \word{2@}}{0.} \\
		\test{-1 -2 2v1 \word{2!}}{     } \\
		\test{      2v1 \word{2@}}{-1 -2}

		\test{\word{:} cd2 \word{2VARIABLE} \word{;}}{} \\
		\test{cd2 2v2}{} \\
		\test{\word{:} cd3 2v2 \word{2!} \word{;}}{} \\
		\test{-2 -1 cd3}{} \\
		\test{2v2 \word{2@}}{-2 -1}

		\test{\word{2VARIABLE} 2v3 \word{IMMEDIATE} 5 6 2v3 \word{2!}}{} \\
		\test{2v3 \word{2@}}{5 6}
	\end{testing}
\end{worddef}


\begin{worddef}{1040}{D+}[d-plus]
\item \stack{d_1|ud_1 d_2|ud_2}{d_3|ud_3}

	Add \param{d_2|ud_2} to \param{d_1|ud_1}, giving the sum
	\param{d_3|ud_3}.

	\begin{testing}
		\test{ 0.  5. \word{D+}}{ 5.} \tab[11.5] \word{bs} small integers \\
		\test{-5.  0. \word{D+}}{-5.} \\
		\test{ 1.  2. \word{D+}}{ 3.} \\
		\test{ 1. -2. \word{D+}}{-1.} \\
		\test{-1.  2. \word{D+}}{ 1.} \\
		\test{-1. -2. \word{D+}}{-3.} \\
		\test{-1.  1. \word{D+}}{ 0.}

		\test{ 0  0  0  5 \word{D+}}{ 0  5} \tab[8] \word{bs} mid range integers \\
		\test{-1  5  0  0 \word{D+}}{-1  5} \\
		\test{ 0  0  0 -5 \word{D+}}{ 0 -5} \\
		\test{ 0 -5 -1  0 \word{D+}}{-1 -5} \\
		\test{ 0  1  0  2 \word{D+}}{ 0  3} \\
		\test{-1  1  0 -2 \word{D+}}{-1 -1} \\
		\test{ 0 -1  0  2 \word{D+}}{ 0  1} \\
		\test{ 0 -1 -1 -2 \word{D+}}{-1 -3} \\
		\test{-1 -1  0  1 \word{D+}}{-1  0}

		\test{MIN-INT 0 \word{2DUP} \word{D+}}{0 1} \\
		\test{MIN-INT \word{StoD} MIN-INT 0 \word{D+}}{0 0}

		\test{ HI-2INT       1.\ \word{D+}}{0 HI-INT \word{1+}} \tab \word{bs} large double integers \\
		\test{ HI-2INT     \word{2DUP} \word{D+}}{1S \word{1-} MAX-INT} \\
		\test{MAX-2INT MIN-2INT \word{D+}}{-1.} \\
		\test{MAX-2INT  LO-2INT \word{D+}}{HI-2INT} \\
		\test{ LO-2INT     \word{2DUP} \word{D+}}{MIN-2INT} \\
		\test{ HI-2INT MIN-2INT \word{D+} 1.\ \word{D+}}{LO-2INT}
	\end{testing}
\end{worddef}


\begin{worddef}{1050}{D-}[d-minus]
\item \stack{d_1|ud_1 d_2|ud_2}{d_3|ud_3}

	Subtract \param{d_2|ud_2} from \param{d_1|ud_1}, giving the
	difference \param{d_3|ud_3}.

	\begin{testing}
		\test{ 0.  5. \word{D-}}{-5.} \tab[6] \word{bs} small integers \\
		\test{ 5.  0. \word{D-}}{ 5.} \\
		\test{ 0. -5. \word{D-}}{ 5.} \\
		\test{ 1.  2. \word{D-}}{-1.} \\
		\test{ 1. -2. \word{D-}}{ 3.} \\
		\test{-1.  2. \word{D-}}{-3.} \\
		\test{-1. -2. \word{D-}}{ 1.} \\
		\test{-1. -1. \word{D-}}{ 0.} \\

		\test{ 0  0  0  5 \word{D-}}{ 0 -5} \tab[2.5] \word{bs} mid-range integers \\
		\test{-1  5  0  0 \word{D-}}{-1  5} \\
		\test{ 0  0 -1 -5 \word{D-}}{ 1  4} \\
		\test{ 0 -5  0  0 \word{D-}}{ 0 -5} \\
		\test{-1  1  0  2 \word{D-}}{-1 -1} \\
		\test{ 0  1 -1 -2 \word{D-}}{ 1  2} \\
		\test{ 0 -1  0  2 \word{D-}}{ 0 -3} \\
		\test{ 0 -1  0 -2 \word{D-}}{ 0  1} \\
		\test{ 0  0  0  1 \word{D-}}{ 0 -1}

		\test{MIN-INT 0 \word{2DUP} \word{D-}}{0.} \\
		\test{MIN-INT \word{StoD} MAX-INT 0\word{D-}}{1 1s} \\

		\test{MAX-2INT max-2INT \word{D-}}{0.} \tab \word{bs} large integers \\
		\test{MIN-2INT min-2INT \word{D-}}{0.} \\
		\test{MAX-2INT  hi-2INT \word{D-}}{lo-2INT \word{DNEGATE}} \\
		\test{ HI-2INT  lo-2INT \word{D-}}{max-2INT} \\
		\test{ LO-2INT  hi-2INT \word{D-}}{min-2INT 1. \word{D+}} \\
		\test{MIN-2INT min-2INT \word{D-}}{0.} \\
		\test{MIN-2INT  lo-2INT \word{D-}}{lo-2INT}
	\end{testing}
\end{worddef}


\begin{worddef}[Dd]{1060}{D.{}}[d-dot]
\item \stack{d}{}

	Display \param{d} in free field format.

	\begin{testing}
		See \tref{double:D.R}{}.
	\end{testing}
\end{worddef}


\begin{worddef}{1070}{D.R}[d-dot-r]
\item \stack{d n}{}

	Display \param{d} right aligned in a field \param{n} characters
	wide. If the number of characters required to display \param{d}
	is greater than \param{n}, all digits are displayed with no
	leading spaces in a field as wide as necessary.

\see \rref{double:D.R}{}.

	\begin{rationale} % A.8.6.1.1070 D.R
		In \word{D.R}, the ``R'' is short for RIGHT.
	\end{rationale}

	\begin{testing}\ttfamily\obeyspaces
		MAX-2INT 71 73 \word{M*/} \word{2CONSTANT} dbl1 \\
		MIN-2INT 73 79 \word{M*/} \word{2CONSTANT} dbl2

		\word{:} d>ascii  \word{p} d -{}- caddr u ) \\
		\tab \word{DUP} \word{toR} \word{num-start} \word{DABS} \word{numS} \word{Rfrom} \word{SIGN} \word{num-end} \tab \word{p} -{}- caddr1 u ) \\
		\tab \word{HERE} \word{SWAP} \word{2DUP} \word{2toR} \word{CHARS} \word{DUP} \word{ALLOT} \word{MOVE} \word{2Rfrom} \\
		\word{;}

		dbl1 d>ascii \word{2CONSTANT} "dbl1" \\
		dbl2 d>ascii \word{2CONSTANT} "dbl2"

		\word{:} DoubleOutput \\
		\tab \word{CR} \word{.q} You should see lines duplicated:" \word{CR} \\
		\tab  5 \word{SPACES} "dbl1" \word{TYPE} \word{CR} \\
		\tab  5 \word{SPACES}  dbl1  \word{Dd} \word{CR} \\
		\tab  8 \word{SPACES} "dbl1" \word{DUP} \word{toR} \word{TYPE} \word{CR} \\
		\tab  5 \word{SPACES}  dbl1  \word{Rfrom} 3 \word{+} \word{D.R} \word{CR} \\
		\tab  5 \word{SPACES} "dbl2" \word{TYPE} \word{CR} \\
		\tab  5 \word{SPACES}  dbl2  \word{Dd} \word{CR} \\
		\tab 10 \word{SPACES} "dbl2" \word{DUP} \word{toR} \word{TYPE} \word{CR} \\
		\tab  5 \word{SPACES}  dbl2  \word{Rfrom} 5 \word{+} \word{D.R} \word{CR} \\
		\word{;}

		\test{DoubleOutput}{}
	\end{testing}
\end{worddef}


\begin{worddef}[D0less]{1075}{D0<}[d-zero-less]
\item \stack{d}{flag}

	\param{flag} is true if and only if \param{d} is less than zero.

	\begin{testing}
		\test{               0. \word{D0less}}{<FALSE>} \\
		\test{               1. \word{D0less}}{<FALSE>} \\
		\test{ MIN-INT        0 \word{D0less}}{<FALSE>} \\
		\test{       0  MAX-INT \word{D0less}}{<FALSE>} \\
		\test{         MAX-2INT \word{D0less}}{<FALSE>} \\
		\test{              -1. \word{D0less}}{<TRUE> } \\
		\test{         MIN-2INT \word{D0less}}{<TRUE> }
	\end{testing}
\end{worddef}


\begin{worddef}{1080}{D0=}[d-zero-equals]
\item \stack{xd}{flag}

	\param{flag} is true if and only if \param{xd} is equal to zero.

	\begin{testing}
		\test{              1. \word{D0=}}{<FALSE>} \\
		\test{MIN-INT        0 \word{D0=}}{<FALSE>} \\
		\test{        MAX-2INT \word{D0=}}{<FALSE>} \\
		\test{     -1  MAX-INT \word{D0=}}{<FALSE>} \\
		\test{              0. \word{D0=}}{<TRUE> } \\
		\test{             -1. \word{D0=}}{<FALSE>} \\
		\test{      0  MIN-INT \word{D0=}}{<FALSE>}
	\end{testing}
\end{worddef}


\begin{worddef}{1090}{D2*}[d-two-star]
\item \stack{xd_1}{xd_2}

	\param{xd_2} is the result of shifting \param{xd_1} one bit
	toward the most-significant bit, filling the vacated
	least-significant bit with zero.

	\begin{testing}
		\test{             0. \word{D2*}}{0. \word{D2*}} \\
		\test{MIN-INT       0 \word{D2*}}{0 1} \\
		\test{        HI-2INT \word{D2*}}{MAX-2INT 1. \word{D-}} \\
		\test{        LO-2INT \word{D2*}}{MIN-2INT}
	\end{testing}
\end{worddef}


\begin{worddef}{1100}{D2/}[d-two-slash]
\item \stack{xd_1}{xd_2}

	\param{xd_2} is the result of shifting \param{xd_1} one bit
	toward the least-significant bit, leaving the most-significant
	bit unchanged.

	\begin{testing}
		\test{      0. \word{D2/}}{0.       } \\
		\test{      1. \word{D2/}}{0.       } \\
		\test{     0 1 \word{D2/}}{MIN-INT 0} \\
		\test{MAX-2INT \word{D2/}}{HI-2INT  } \\
		\test{     -1. \word{D2/}}{-1.      } \\
		\test{MIN-2INT \word{D2/}}{LO-2INT  }
	\end{testing}
\end{worddef}


\begin{worddef}[Dless]{1110}{D<}[d-less-than]
\item \stack{d_1 d_2}{flag}

	\param{flag} is true if and only if \param{d_1} is less than
	\param{d_2}.

	\begin{testing}
		\test{      0.       1. \word{Dless}}{<TRUE> } \\
		\test{      0.       0. \word{Dless}}{<FALSE>} \\
		\test{      1.       0. \word{Dless}}{<FALSE>} \\
		\test{     -1.       1. \word{Dless}}{<TRUE> } \\
		\test{     -1.       0. \word{Dless}}{<TRUE> } \\
		\test{     -2.      -1. \word{Dless}}{<TRUE> } \\
		\test{     -1.      -2. \word{Dless}}{<FALSE>} \\
		\test{     -1. MAX-2INT \word{Dless}}{<TRUE> } \\
		\test{MIN-2INT MAX-2INT \word{Dless}}{<TRUE> } \\
		\test{MAX-2INT      -1. \word{Dless}}{<FALSE>} \\
		\test{MAX-2INT MIN-2INT \word{Dless}}{<FALSE>}

		\test{MAX-2INT \word{2DUP} -1. \word{D+} \word{Dless}}{<FALSE>} \\
		\test{MIN-2INT \word{2DUP}  1. \word{D+} \word{Dless}}{<TRUE> }
	\end{testing}
\end{worddef}


\begin{worddef}{1120}{D=}[d-equals]
\item \stack{xd_1 xd_2}{flag}

	\param{flag} is true if and only if \param{xd_1} is bit-for-bit
	the same as \param{xd_2}.

	\begin{testing}
		\test{     -1.      -1. \word{D=}}{<TRUE> } \\
		\test{     -1.       0. \word{D=}}{<FALSE>} \\
		\test{     -1.       1. \word{D=}}{<FALSE>} \\
		\test{      0.      -1. \word{D=}}{<FALSE>} \\
		\test{      0.       0. \word{D=}}{<TRUE> } \\
		\test{      0.       1. \word{D=}}{<FALSE>} \\
		\test{      1.      -1. \word{D=}}{<FALSE>} \\
		\test{      1.       0. \word{D=}}{<FALSE>} \\
		\test{      1.       1. \word{D=}}{<TRUE> }

		\test{  0   -1    0  -1 \word{D=}}{<TRUE> } \\
		\test{  0   -1    0   0 \word{D=}}{<FALSE>} \\
		\test{  0   -1    0   1 \word{D=}}{<FALSE>} \\
		\test{  0    0    0  -1 \word{D=}}{<FALSE>} \\
		\test{  0    0    0   0 \word{D=}}{<TRUE> } \\
		\test{  0    0    0   1 \word{D=}}{<FALSE>} \\
		\test{  0    1    0  -1 \word{D=}}{<FALSE>} \\
		\test{  0    1    0   0 \word{D=}}{<FALSE>} \\
		\test{  0    1    0   1 \word{D=}}{<TRUE> }

		\test{MAX-2INT MIN-2INT \word{D=}}{<FALSE>} \\
		\test{MAX-2INT       0. \word{D=}}{<FALSE>} \\
		\test{MAX-2INT MAX-2INT \word{D=}}{<TRUE> } \\
		\test{MAX-2INT HI-2INT  \word{D=}}{<FALSE>} \\
		\test{MAX-2INT MIN-2INT \word{D=}}{<FALSE>} \\
		\test{MIN-2INT MIN-2INT \word{D=}}{<TRUE> } \\
		\test{MIN-2INT LO-2INT  \word{D=}}{<FALSE>} \\
		\test{MIN-2INT MAX-2INT \word{D=}}{<FALSE>}
	\end{testing}
\end{worddef}


\begin{worddef}[DtoS]{1140}{D>S}[d-to-s]
\item \stack{d}{n}

	\param{n} is the equivalent of \param{d}. An ambiguous condition
	exists if \param{d} lies outside the range of a signed single-cell
	number.

\see \rref{double:DtoS}{}.

	\begin{rationale} % A.8.6.1.1140 D>S
		There exist number representations, e.g., the sign-magnitude
		representation, where reduction from double- to single-precision
		cannot simply be done with \word[core]{DROP}. This word,
		equivalent to \word[core]{DROP} on two's complement systems,
		desensitizes application code to number representation and
		facilitates portability.
	\end{rationale}

	\begin{testing}
		\test{   1234  0 \word{DtoS}}{ 1234  } \\
		\test{  -1234 -1 \word{DtoS}}{-1234  } \\
		\test{MAX-INT  0 \word{DtoS}}{MAX-INT} \\
		\test{MIN-INT -1 \word{DtoS}}{MIN-INT}
	\end{testing}
\end{worddef}


\begin{worddef}{1160}{DABS}[d-abs]
\item \stack{d}{ud}

	\param{ud} is the absolute value of \param{d}.

	\begin{testing}
		\test{      1. \word{DABS}}{1.      } \\
		\test{     -1. \word{DABS}}{1.      } \\
		\test{MAX-2INT \word{DABS}}{MAX-2INT} \\
		\test{MIN-2INT 1. \word{D+} \word{DABS}}{MAX-2INT}
	\end{testing}
\end{worddef}


\begin{worddef}{1210}{DMAX}[d-max]
\item \stack{d_1 d_2}{d_3}

	\param{d_3} is the greater of \param{d_1} and \param{d_2}.

	\begin{testing}
		\test{      1.       2. \word{DMAX}}{ 2.     } \\
		\test{      1.       0. \word{DMAX}}{ 1.     } \\
		\test{      1.      -1. \word{DMAX}}{ 1.     } \\
		\test{      1.       1. \word{DMAX}}{ 1.     } \\
		\test{      0.       1. \word{DMAX}}{ 1.     } \\
		\test{      0.      -1. \word{DMAX}}{ 0.     } \\
		\test{     -1.       1. \word{DMAX}}{ 1.     } \\
		\test{     -1.      -2. \word{DMAX}}{-1.     }

		\test{MAX-2INT  HI-2INT \word{DMAX}}{MAX-2INT} \\
		\test{MAX-2INT MIN-2INT \word{DMAX}}{MAX-2INT} \\
		\test{MIN-2INT MAX-2INT \word{DMAX}}{MAX-2INT} \\
		\test{MIN-2INT  LO-2INT \word{DMAX}}{LO-2INT }

		\test{MAX-2INT       1. \word{DMAX}}{MAX-2INT} \\
		\test{MAX-2INT      -1. \word{DMAX}}{MAX-2INT} \\
		\test{MIN-2INT       1. \word{DMAX}}{ 1.     } \\
		\test{MIN-2INT      -1. \word{DMAX}}{-1.     }
	\end{testing}
\end{worddef}


\begin{worddef}{1220}{DMIN}[d-min]
\item \stack{d_1 d_2}{d_3}

	\param{d_3} is the lesser of \param{d_1} and \param{d_2}.

	\begin{testing}
		\test{      1.       2. \word{DMIN}}{ 1.     } \\
		\test{      1.       0. \word{DMIN}}{ 0.     } \\
		\test{      1.      -1. \word{DMIN}}{-1.     } \\
		\test{      1.       1. \word{DMIN}}{ 1.     } \\
		\test{      0.       1. \word{DMIN}}{ 0.     } \\
		\test{      0.      -1. \word{DMIN}}{-1.     } \\
		\test{     -1.       1. \word{DMIN}}{-1.     } \\
		\test{     -1.      -2. \word{DMIN}}{-2.     }

		\test{MAX-2INT  HI-2INT \word{DMIN}}{HI-2INT } \\
		\test{MAX-2INT MIN-2INT \word{DMIN}}{MIN-2INT} \\
		\test{MIN-2INT MAX-2INT \word{DMIN}}{MIN-2INT} \\
		\test{MIN-2INT  LO-2INT \word{DMIN}}{MIN-2INT}

		\test{MAX-2INT       1. \word{DMIN}}{ 1.     } \\
		\test{MAX-2INT      -1. \word{DMIN}}{-1.     } \\
		\test{MIN-2INT       1. \word{DMIN}}{MIN-2INT} \\
		\test{MIN-2INT      -1. \word{DMIN}}{MIN-2INT}
	\end{testing}
\end{worddef}


\begin{worddef}{1230}{DNEGATE}[d-negate]
\item \stack{d_1}{d_2}

	\param{d_2} is the negation of \param{d_1}.

	\begin{testing}
		\test{  0.\ \word{DNEGATE}}{ 0.} \\
		\test{  1.\ \word{DNEGATE}}{-1.} \\
		\test{ -1.\ \word{DNEGATE}}{ 1.} \\
		\test{max-2int \word{DNEGATE}}{min-2int \word{SWAP} \word{1+} \word{SWAP}} \\
		\test{min-2int \word{SWAP} \word{1+} \word{SWAP} \word{DNEGATE}}{max-2int}
	\end{testing}
\end{worddef}


\begin{worddef}{1820}{M*/}[m-star-slash]
\item \stack{d_1 n_1 +n_2}{d_2}

	Multiply \param{d_1} by \param{n_1} producing the triple-cell
	intermediate result $t$. Divide $t$ by \param{+n_2} giving the
	double-cell quotient \param{d_2}. An ambiguous condition exists
	if \param{+n_2} is zero or negative, or the quotient lies outside
	of the range of a double-precision signed integer.

\see \rref{double:M*/}{}.

	\begin{rationale} % A.8.6.1.1820 M*/
		\word{M*/} was once described by Chuck Moore as the most
		useful arithmetic operator in Forth. It is the main workhorse
		in most computations involving double-cell numbers. Note that
		some systems allow signed divisors. This can cost a lot in
		performance on some CPUs. The requirement for a positive
		divisor has not proven to be a problem.
	\end{rationale}

	\begin{testing}\ttfamily
		\textdf{To correct the result if the division is floored,
			only used when necessary, i.e., negative quotient and
			remainder $\not=$ 0.}

		\word{:} ?floored \word{[} -3 2 \word{/} -2 \word{=} \word{]} \word{LITERAL} \word{IF} 1.\ \word{D-} \word{THEN} \word{;}

		\small 
		\test{      5.       7             11 \word{M*/}}{ 3.} \\
		\test{      5.      -7             11 \word{M*/}}{-3. ?floored} \\ %\tab \word{bs} \textdf{floored -4.} \\
		\test{     -5.       7             11 \word{M*/}}{-3. ?floored} \\ %\tab \word{bs} \textdf{floored -4.} \\
		\test{     -5.      -7             11 \word{M*/}}{ 3.} \\
		\test{MAX-2INT       8             16 \word{M*/}}{HI-2INT} \\
		\test{MAX-2INT      -8             16 \word{M*/}}{HI-2INT \word{DNEGATE} ?floored} \\ %\tab \word{bs} \textdf{floored subtract 1} \\
		\test{MIN-2INT       8             16 \word{M*/}}{LO-2INT} \\
		\test{MIN-2INT      -8             16 \word{M*/}}{LO-2INT \word{DNEGATE}}

		\test{MAX-2INT MAX-INT        MAX-INT \word{M*/}}{MAX-2INT} \\
		\test{MAX-2INT MAX-INT \word{2/}     MAX-INT \word{M*/}}{MAX-INT 1- HI-2INT \word{NIP}} \\
		\test{MIN-2INT LO-2INT \word{NIP} \word{DUP} \word{NEGATE} \word{M*/}}{MIN-2INT} \\
		\test{MIN-2INT LO-2INT \word{NIP} \word{1-} MAX-INT \word{M*/}}{MIN-INT 3 + HI-2INT \word{NIP} 2 \word{+}} \\
		\test{MAX-2INT LO-2INT \word{NIP} \word{DUP} \word{NEGATE} \word{M*/}}{MAX-2INT \word{DNEGATE}} \\
		\test{MIN-2INT MAX-INT            \word{DUP} \word{M*/}}{MIN-2INT}
	\end{testing}
\end{worddef}


\begin{worddef}{1830}{M+}[m-plus]
\item \stack{d_1|ud_1 n}{d_2|ud_2}

	Add \param{n} to \param{d_1|ud_1}, giving the sum \param{d_2|ud_2}.

\see \rref{double:M+}{}.

	\begin{rationale} % A.8.6.1.1830 M+
		\word{M+} is the classical method for integrating.
	\end{rationale}

	\begin{testing}
		\test{HI-2INT   1 \word{M+}}{HI-2INT   1. \word{D+}} \\
		\test{MAX-2INT -1 \word{M+}}{MAX-2INT -1. \word{D+}} \\
		\test{MIN-2INT  1 \word{M+}}{MIN-2INT  1. \word{D+}} \\
		\test{LO-2INT  -1 \word{M+}}{LO-2INT  -1. \word{D+}}
	\end{testing}
\end{worddef}

\newpage
\subsection{Double-Number extension words} % 8.6.2
\extended

\begin{worddef}{0420}{2ROT}[two-rote]
\item \stack{x_1 x_2 x_3 x_4 x_5 x_6}{x_3 x_4 x_5 x_6 x_1 x_2}

	Rotate the top three cell pairs on the stack bringing cell pair
	\param{x_1 x_2} to the top of the stack.

	\begin{testing}
		\test{      1.       2. 3. \word{2ROT}}{      2. 3.       1.} \\
		\test{MAX-2INT MIN-2INT 1. \word{2ROT}}{MIN-2INT 1. MAX-2INT}
	\end{testing}
\end{worddef}

% ---------------------------------------------------------

\begin{worddef}{0435}{2VALUE}[two-value][X:2value]
\item \stack{x_1 x_2 "<spaces>name"}{}

	Skip leading space delimiters.  Parse \param{name} delimited by a
	space.  Create a definition for \param{name} with the execution
	semantics defined below, with an initial value of \param{x_1 x_2}.

	\param{name} is referred to as a ``two-value''.

\execute[name]
	\stack{}{x_1 x_2}

	Place cell pair \param{x_1 x_2} on the stack.  The value of
	\param{x_1 x_2} is that given when \param{name} was created,
	until the phrase ``\param{x_1 x_2} \word{TO} \param{name}'' is
	executed, causing a new cell pair \param{x_1 x_2} to be assigned
	to \param{name}.

\runtime[\word{TO} \param{name}]
	\stack{x_1 x_2}{}

	Assign the cell pair \param{x_1 x_2} to \param{name}.

\see \xref{usage:parsing} and \wref{core:TO}{},
	\rref{double:2VALUE}{}.

	\begin{rationale}
		Typical use:
		\begin{quote}\ttfamily
			\word{:} fn1 \word{Sq} filename" \word{;} \\
			fn1 \word{2VALUE} myfile \\
			myfile \word[file]{INCLUDED} \\[2ex]
			\word{:} fn2 \word{Sq} filename2" \word{;} \\
			fn2 \word{TO} myfile \\
			myfile \word[file]{INCLUDED}
		\end{quote}
	\end{rationale}

	\begin{implement}
		\dffamily
		The implementation of \word{TO} to include \word{2VALUE}s
		requires detailed knowledge of the host implementation of
		\word{VALUE} and \word{TO}, which is the main reason why
		\word{2VALUE} should be standardized.  The order in which
		the two cells are stored in memory is not specified in the
		definition for \word{2VALUE} but this reference implementation
		has to assume one ordering --- this is not intended to be
		definitive.

		\begin{quote}\ttfamily
			\word{:} \word{2VALUE} \word{p} x1 x2 -{}- ) \\
			\tab \word{CREATE} \word{,} \word{,} \\
			\tab \word{DOES} \word{2@} \word{p} -{}- x1 x2 ) \\
			\word{;}
		\end{quote}

		The corresponding implementation of \word{TO} disregards the
		issue that \word{TO} must also work for integer \word{VALUE}s
		and locals.

		\begin{quote}\ttfamily
			\word{:} \word{TO} \word{p} x1 x2 "<spaces>name" -{}- ) \\
			\tab \word{'} \word{toBODY} \\
			\tab \word{STATE} \word{@} \word{IF} \\
			\tab[2] \word{POSTPONE} \word{2LITERAL} \word{POSTPONE} \word{2!} \\
			\tab \word{ELSE} \\
			\tab[2] \word{2!} \\
			\tab \word{THEN} \\
			\word{;} \word{IMMEDIATE}
		\end{quote}
	\end{implement}

	\begin{testing}\ttfamily
		\test{1 2 \word{2VALUE} t2val}{} \\
		\test{t2val}{1 2} \\[2ex]
		\test{3 4 \word{TO} t2val}{} \\
		\test{t2val}{3 4} \\[2ex]
		\word{:} sett2val t2val \word{2SWAP} \word{TO} t2val \word{;} \\
		\test{5 6 sett2val t2val}{3 4 5 6}
	\end{testing}
\end{worddef}
% ---------------------------------------------------------

\begin{worddef}[DUless]{1270}{DU<}[d-u-less]
\item \stack{ud_1 ud_2}{flag}

	\param{flag} is true if and only if \param{ud_1} is less than
	\param{ud_2}.

	\begin{testing}
		\test{      1.       1. \word{DUless}}{<FALSE>} \\
		\test{      1.      -1. \word{DUless}}{<TRUE> } \\
		\test{     -1.       1. \word{DUless}}{<FALSE>} \\
		\test{     -1.      -2. \word{DUless}}{<FALSE>}

		\test{MAX-2INT  HI-2INT \word{DUless}}{<FALSE>} \\
		\test{ HI-2INT MAX-2INT \word{DUless}}{<TRUE> } \\
		\test{MAX-2INT MIN-2INT \word{DUless}}{<TRUE> } \\
		\test{MIN-2INT MAX-2INT \word{DUless}}{<FALSE>} \\
		\test{MIN-2INT  LO-2INT \word{DUless}}{<TRUE> }
	\end{testing}
\end{worddef}
