% \iffalse meta-comment
%
%% File: l3int.dtx Copyright (C) 1990-2012 The LaTeX3 Project
%%
%% It may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License (LPPL), either version 1.3c of this
%% license or (at your option) any later version.  The latest version
%% of this license is in the file
%%
%%    http://www.latex-project.org/lppl.txt
%%
%% This file is part of the "l3kernel bundle" (The Work in LPPL)
%% and all files in that bundle must be distributed together.
%%
%% The released version of this bundle is available from CTAN.
%%
%% -----------------------------------------------------------------------
%%
%% The development version of the bundle can be found at
%%
%%    http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
%%%%%%%%%%%
%% NOTE: %%
%%%%%%%%%%%
%%
%%   Snapshots taken from the repository represent work in progress and may
%%   not work or may contain conflicting material!  We therefore ask
%%   people _not_ to put them into distributions, archives, etc. without
%%   prior consultation with the LaTeX3 Project.
%%
%% -----------------------------------------------------------------------
%
%<*driver|package>
\RequirePackage{l3names}
\GetIdInfo$Id: l3int.dtx 3490 2012-03-04 01:00:53Z bruno $
  {L3 Experimental integers}
%</driver|package>
%<*driver>
\documentclass[full]{l3doc}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \title{^^A
%   The \pkg{l3int} package\\ Integers^^A
%   \thanks{This file describes v\ExplFileVersion,
%      last revised \ExplFileDate.}^^A
% }
%
% \author{^^A
%  The \LaTeX3 Project\thanks
%    {^^A
%      E-mail:
%        \href{mailto:latex-team@latex-project.org}
%          {latex-team@latex-project.org}^^A
%    }^^A
% }
%
% \date{Released \ExplFileDate}
%
% \maketitle
%
% \begin{documentation}
%
% Calculation and comparison of integer values can be carried out
% using literal numbers, \texttt{int} registers, constants and
% integers stored in token list variables. The standard operators
% \texttt{+}, \texttt{-}, \texttt{/} and \texttt{*} and
% parentheses can be used within such expressions to carry
% arithmetic operations. This module carries out these functions
% on \emph{integer expressions} (\enquote{\texttt{int expr}}).
%
% \section{Integer expressions}
%
% \begin{function}[EXP]{\int_eval:n}
%   \begin{syntax}
%     \cs{int_eval:n} \Arg{integer expression}
%   \end{syntax}
%   Evaluates the \meta{integer expression}, expanding any
%   integer and token list variables within the \meta{expression}
%   to their content (without requiring \cs{int_use:N}/\cs{tl_use:N})
%   and applying the standard mathematical rules. For example both
%   \begin{verbatim}
%     \int_eval:n { 5 +  4 * 3 - ( 3 + 4 * 5 ) }
%   \end{verbatim}
%   and
%   \begin{verbatim}
%     \tl_new:N  \l_my_tl
%     \tl_set:Nn \l_my_tl { 5 }
%     \int_new:N  \l_my_int
%     \int\set:Nn \l_my_int { 4 }
%    \int_eval:n { \l_my_tl +  \l_my_int * 3 - ( 3 + 4 * 5 ) }
%   \end{verbatim}
%   both evaluate to \( -6 \). The  \Arg{integer expression} may
%   contain the operators \texttt{+}, \texttt{-}, \texttt{*} and
%   \texttt{/}, along with parenthesis \texttt{(} and \texttt{)}.
%   After two expansions, \cs{int_eval:n} yields a
%   \meta{integer denotation} which is left in the input stream. This is
%   \emph{not} an \meta{internal integer}, and therefore requires
%   suitable termination if used in a \TeX{}-style integer assignment.
% \end{function}
%
% \begin{function}[EXP]{\int_abs:n}
%   \begin{syntax}
%     \cs{int_abs:n} \Arg{integer expression}
%   \end{syntax}
%   Evaluates the \meta{integer expression} as described for
%   \cs{int_eval:n} and leaves the absolute value of the result in
%   the input stream as an \meta{integer denotation} after two
%   expansions.
% \end{function}
%
% \begin{function}[EXP]{\int_div_round:nn}
%   \begin{syntax}
%     \cs{int_div_round:nn} \Arg{intexpr_1} \Arg{intexpr_2}
%   \end{syntax}
%   Evaluates the two \meta{integer expressions} as described earlier,
%   then calculates the result of dividing the first value by the
%   second, rounding any remainder. Ties are rounded away from zero.
%   Note that this is identical to using
%   |/| directly in an \meta{integer expression}. The result is left in
%   the input stream as a \meta{integer denotation} after two expansions.
% \end{function}
%
% \begin{function}[EXP, updated = 2012-02-09]{\int_div_truncate:nn}
%   \begin{syntax}
%     \cs{int_div_truncate:nn} \Arg{intexpr_1} \Arg{intexpr_2}
%   \end{syntax}
%   Evaluates the two \meta{integer expressions} as described earlier,
%   then calculates the result of dividing the first value by the
%   second, truncating any remainder. Note that division using |/|
%   rounds the result. The result is left in the input stream as a
%   \meta{integer denotation} after two expansions.
% \end{function}
%
% \begin{function}[EXP]{\int_max:nn, \int_min:nn}
%   \begin{syntax}
%     \cs{int_max:nn} \Arg{intexpr_1} \Arg{intexpr_2}
%     \cs{int_min:nn} \Arg{intexpr_1} \Arg{intexpr_2}
%   \end{syntax}
%   Evaluates the \meta{integer expressions} as described for
%   \cs{int_eval:n} and leaves either the larger or smaller value
%   in the input stream as an \meta{integer denotation} after two
%   expansions.
% \end{function}
%
% \begin{function}[EXP]{\int_mod:nn}
%   \begin{syntax}
%     \cs{int_mod:nn} \Arg{intexpr_1} \Arg{intexpr_2}
%   \end{syntax}
%   Evaluates the two \meta{integer expressions} as described earlier,
%   then calculates the integer remainder of dividing the first
%   expression by the second. This is left in the input stream as an
%   \meta{integer denotation} after two expansions.
% \end{function}
%
% \section{Creating and initialising integers}
%
% \begin{function}{\int_new:N, \int_new:c}
%   \begin{syntax}
%     \cs{int_new:N} \meta{integer}
%   \end{syntax}
%   Creates a new \meta{integer} or raises an error if the name is
%   already taken. The declaration is global. The \meta{integer} will
%   initially be equal to $0$.
% \end{function}
%
% \begin{function}[updated = 2011-10-22]{\int_const:Nn, \int_const:cn}
%   \begin{syntax}
%     \cs{int_const:Nn} \meta{integer} \Arg{integer expression}
%   \end{syntax}
%   Creates a new constant \meta{integer} or raises an error if the name
%   is already taken. The value of the \meta{integer} will be set
%   globally to the \meta{integer expression}.
% \end{function}
%
% \begin{function}{\int_zero:N, \int_zero:c, \int_gzero:N, \int_gzero:c}
%   \begin{syntax}
%     \cs{int_zero:N} \meta{integer}
%   \end{syntax}
%   Sets \meta{integer} to $0$.
% \end{function}
%
% \begin{function}[added = 2011-12-13]
%   {\int_zero_new:N, \int_zero_new:c, \int_gzero_new:N, \int_gzero_new:c}
%   \begin{syntax}
%     \cs{int_zero_new:N} \meta{integer}
%   \end{syntax}
%   Ensures that the \meta{integer} exists globally by applying
%   \cs{int_new:N} if necessary, then applies \cs{int_(g)zero:N} to leave
%   the \meta{integer} set to zero.
% \end{function}
%
% \begin{function}
%   {
%     \int_set_eq:NN,  \int_set_eq:cN,  \int_set_eq:Nc,  \int_set_eq:cc,
%     \int_gset_eq:NN, \int_gset_eq:cN, \int_gset_eq:Nc, \int_gset_eq:cc
%   }
%   \begin{syntax}
%     \cs{int_set_eq:NN} \meta{integer1} \meta{integer2}
%   \end{syntax}
%   Sets the content of \meta{integer1} equal to that of
%   \meta{integer2}.
% \end{function}
%
% \begin{function}[EXP, pTF, added=2012-03-03]
%   {\int_if_exist:N, \int_if_exist:c}
%   \begin{syntax}
%     \cs{int_if_exist_p:N} \meta{int}
%     \cs{int_if_exist:NTF} \meta{int} \Arg{true code} \Arg{false code}
%   \end{syntax}
%   Tests whether the \meta{int} is currently defined.  This does not
%   check that the \meta{int} really is an integer variable.
% \end{function}
%
% \section{Setting and incrementing integers}
%
% \begin{function}[updated = 2011-10-22]
%   {\int_add:Nn, \int_add:cn, \int_gadd:Nn, \int_gadd:cn}
%   \begin{syntax}
%     \cs{int_add:Nn} \meta{integer} \Arg{integer expression}
%   \end{syntax}
%   Adds the result of the \meta{integer expression} to the current
%   content of the \meta{integer}.
% \end{function}
%
% \begin{function}{\int_decr:N, \int_decr:c, \int_gdecr:N, \int_gdecr:c}
%   \begin{syntax}
%     \cs{int_decr:N} \meta{integer}
%   \end{syntax}
%   Decreases the value stored in \meta{integer} by $1$.
% \end{function}
%
% \begin{function}{\int_incr:N, \int_incr:c, \int_gincr:N, \int_gincr:c}
%   \begin{syntax}
%     \cs{int_incr:N} \meta{integer}
%   \end{syntax}
%   Increases the value stored in \meta{integer} by $1$.
% \end{function}
%
% \begin{function}[updated = 2011-10-22]
%   {\int_set:Nn, \int_set:cn, \int_gset:Nn, \int_gset:cn}
%   \begin{syntax}
%     \cs{int_set:Nn} \meta{integer} \Arg{integer expression}
%   \end{syntax}
%   Sets \meta{integer} to the value of \meta{integer expression},
%   which must evaluate to an integer (as described for
%   \cs{int_eval:n}).
% \end{function}
%
% \begin{function}[updated = 2011-10-22]
%   {\int_sub:Nn, \int_sub:cn, \int_gsub:Nn, \int_gsub:cn}
%   \begin{syntax}
%     \cs{int_sub:Nn} \meta{integer} \Arg{integer expression}
%   \end{syntax}
%   Subtracts the result of the \meta{integer expression} to the
%   current content of the \meta{integer}.
% \end{function}
%
% \section{Using integers}
%
% \begin{function}[updated = 2011-10-22, EXP]{\int_use:N, \int_use:c}
%   \begin{syntax}
%     \cs{int_use:N} \meta{integer}
%   \end{syntax}
%   Recovers the content of a \meta{integer} and places it directly
%   in the input stream. An error will be raised if the variable does
%   not exist or if it is invalid. Can be omitted in places where a
%   \meta{integer} is required (such as in the first and third arguments
%   of \cs{int_compare:nNnTF}).
%   \begin{texnote}
%     \cs{int_use:N} is the \TeX{} primitive \tn{the}: this is one of
%     several \LaTeX3 names for this primitive.
%   \end{texnote}
% \end{function}
%
% \section{Integer expression conditionals}
%
% \begin{function}[EXP,pTF]{\int_compare:nNn}
%   \begin{syntax}
%     \cs{int_compare_p:nNn} \Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \\
%     \cs{int_compare:nNnTF}
%     ~~\Arg{intexpr_1} \meta{relation} \Arg{intexpr_2}
%     ~~\Arg{true code} \Arg{false code}
%   \end{syntax}
%   This function first evaluates each of the \meta{integer expressions}
%   as described for \cs{int_eval:n}. The two results are then
%   compared using the \meta{relation}:
%   \begin{center}
%     \begin{tabular}{ll}
%       Equal                 & |=| \\
%       Greater than          & |>| \\
%       Less than             & |<| \\
%     \end{tabular}
%   \end{center}
% \end{function}
%
% \begin{function}[EXP,pTF]{\int_compare:n}
%   \begin{syntax}
%     \cs{int_compare_p:n} \{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} \\
%     \cs{int_compare:nTF}
%     ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \}
%     ~~\Arg{true code} \Arg{false code}
%   \end{syntax}
%   This function first evaluates each of the \meta{integer expressions}
%   as described for \cs{int_eval:n}. The two results are then
%   compared using the \meta{relation}:
%   \begin{center}
%     \begin{tabular}{ll}
%       Equal                    & |=| or |==| \\
%       Greater than or equal to & |>=|        \\
%       Greater than             & |>|         \\
%       Less than or equal to    & |<=|        \\
%       Less than                & |<|         \\
%       Not equal                & |!=|        \\
%     \end{tabular}
%   \end{center}
% \end{function}
%
% \begin{function}[EXP,pTF]{\int_if_even:n, \int_if_odd:n}
%   \begin{syntax}
%     \cs{int_if_odd_p:n} \Arg{integer expression}
%     \cs{int_if_odd:nTF} \Arg{integer expression}
%     ~~\Arg{true code} \Arg{false code}
%   \end{syntax}
%   This function first evaluates the \meta{integer expression}
%   as described for \cs{int_eval:n}. It then evaluates if this
%   is odd or even, as appropriate.
% \end{function}
%
% \section{Integer expression loops}
%
% \begin{function}[rEXP]{\int_do_while:nNnn}
%   \begin{syntax}
%      \cs{int_do_while:nNnn}
%      ~~\Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code}
%   \end{syntax}
%   Evaluates the relationship between the two \meta{integer expressions}
%   as described for \cs{int_compare:nNnTF}, and then places the
%   \meta{code} in the input stream if the \meta{relation} is
%   \texttt{true}. After the \meta{code} has been processed by \TeX{} the
%   test will be repeated, and a loop will occur until the test is
%   \texttt{false}.
% \end{function}
%
% \begin{function}[rEXP]{\int_do_until:nNnn}
%   \begin{syntax}
%      \cs{int_do_until:nNnn}
%      ~~\Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code}
%   \end{syntax}
%   Evaluates the relationship between the two \meta{integer expressions}
%   as described for \cs{int_compare:nNnTF}, and then places the
%   \meta{code} in the input stream if the \meta{relation} is
%   \texttt{false}. After the \meta{code} has been processed by \TeX{} the
%   test will be repeated, and a loop will occur until the test is
%   \texttt{true}.
% \end{function}
%
% \begin{function}[rEXP]{\int_until_do:nNnn}
%   \begin{syntax}
%      \cs{int_until_do:nNnn}
%      ~~\Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code}
%   \end{syntax}
%   Places the \meta{code} in the input stream for \TeX{} to process, and
%   then evaluates the relationship between the two
%   \meta{integer expressions} as described for \cs{int_compare:nNnTF}.
%   If the test is \texttt{false} then the \meta{code} will be inserted
%   into the input stream again and a loop will occur until the
%   \meta{relation} is \texttt{true}.
% \end{function}
%
% \begin{function}[rEXP]{\int_while_do:nNnn}
%   \begin{syntax}
%      \cs{int_while_do:nNnn} \
%      ~~\Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code}
%   \end{syntax}
%   Places the \meta{code} in the input stream for \TeX{} to process, and
%   then evaluates the relationship between the two
%   \meta{integer expressions} as described for \cs{int_compare:nNnTF}.
%   If the test is \texttt{true} then the \meta{code} will be inserted
%   into the input stream again and a loop will occur until the
%   \meta{relation} is \texttt{false}.
% \end{function}
%
% \begin{function}[rEXP]{\int_do_while:nn}
%   \begin{syntax}
%      \cs{int_do_while:nn}
%      ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} \Arg{code}
%   \end{syntax}
%   Evaluates the relationship between the two \meta{integer expressions}
%   as described for \cs{int_compare:nTF}, and then places the
%   \meta{code} in the input stream if the \meta{relation} is
%   \texttt{true}. After the \meta{code} has been processed by \TeX{} the
%   test will be repeated, and a loop will occur until the test is
%   \texttt{false}.
% \end{function}
%
% \begin{function}[rEXP]{\int_do_until:nn}
%   \begin{syntax}
%      \cs{int_do_until:nn}
%      ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} \Arg{code}
%   \end{syntax}
%   Evaluates the relationship between the two \meta{integer expressions}
%   as described for \cs{int_compare:nTF}, and then places the
%   \meta{code} in the input stream if the \meta{relation} is
%   \texttt{false}. After the \meta{code} has been processed by \TeX{} the
%   test will be repeated, and a loop will occur until the test is
%   \texttt{true}.
% \end{function}
%
% \begin{function}[rEXP]{\int_until_do:nn}
%   \begin{syntax}
%      \cs{int_until_do:nn}
%      ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} \Arg{code}
%   \end{syntax}
%   Places the \meta{code} in the input stream for \TeX\ to process, and
%   then evaluates the relationship between the two
%   \meta{integer expressions} as described for \cs{int_compare:nTF}.
%   If the test is \texttt{false} then the \meta{code} will be inserted
%   into the input stream again and a loop will occur until the
%   \meta{relation} is \texttt{true}.
% \end{function}
%
% \begin{function}[rEXP]{\int_while_do:nn}
%   \begin{syntax}
%      \cs{int_while_do:nn} \
%      ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} \Arg{code}
%   \end{syntax}
%   Places the \meta{code} in the input stream for \TeX{} to process, and
%   then evaluates the relationship between the two
%   \meta{integer expressions} as described for \cs{int_compare:nTF}.
%   If the test is \texttt{true} then the \meta{code} will be inserted
%   into the input stream again and a loop will occur until the
%   \meta{relation} is \texttt{false}.
% \end{function}
%
% \section{Formatting integers}
%
% Integers can be placed into the output stream with formatting. These
% conversions apply to any integer expressions.
%
% \begin{function}[updated = 2011-10-22, EXP]{\int_to_arabic:n}
%   \begin{syntax}
%     \cs{int_to_arabic:n} \Arg{integer expression}
%   \end{syntax}
%   Places the value of the \meta{integer expression} in the input
%   stream as digits, with category code $12$ (other).
% \end{function}
%
% \begin{function}[updated = 2011-09-17, EXP]{\int_to_alph:n, \int_to_Alph:n}
%   \begin{syntax}
%     \cs{int_to_alph:n} \Arg{integer expression}
%   \end{syntax}
%   Evaluates the \meta{integer expression} and converts the result
%   into a series of letters, which are then left in the input stream.
%   The conversion rule uses the $26$ letters of the English
%   alphabet, in order, adding letters when necessary to increase the total
%   possible range of representable numbers. Thus
%   \begin{verbatim}
%     \int_to_alph:n { 1 }
%   \end{verbatim}
%   places |a| in the input stream,
%   \begin{verbatim}
%     \int_to_alph:n { 26 }
%   \end{verbatim}
%   is represented as |z| and
%   \begin{verbatim}
%     \int_to_alph:n { 27 }
%   \end{verbatim}
%   is converted to |aa|. For conversions using other alphabets, use
%   \cs{int_convert_to_symbols:nnn} to define an alphabet-specific
%   function. The basic \cs{int_to_alph:n} and \cs{int_to_Alph:n}
%   functions should not be modified.
% \end{function}
%
% \begin{function}[updated = 2011-09-17, EXP]{\int_to_symbols:nnn}
%   \begin{syntax}
%     \cs{int_to_symbols:nnn}
%     ~~\Arg{integer expression} \Arg{total symbols}
%     ~~\meta{value to symbol mapping}
%   \end{syntax}
%   This is the low-level function for conversion of an
%   \meta{integer expression} into a symbolic form (which will often
%   be letters). The \meta{total symbols} available should be given
%   as an integer expression. Values are actually converted to symbols
%   according to the \meta{value to symbol mapping}. This should be given
%   as \meta{total symbols} pairs of entries, a number and the
%   appropriate symbol. Thus the \cs{int_to_alph:n} function is defined
%   as
%   \begin{verbatim}
%     \cs_new:Npn \int_to_alph:n #1
%       {
%         \int_convert_to_symbols:nnn {#1} { 26 }
%           {
%             {  1 } { a }
%             {  2 } { b }
%             ...
%             { 26 } { z }
%           }
%       }
%   \end{verbatim}
% \end{function}
%
% \begin{function}[updated = 2011-09-17, EXP]{\int_to_binary:n}
%   \begin{syntax}
%     \cs{int_to_binary:n} \Arg{integer expression}
%   \end{syntax}
%   Calculates the value of the \meta{integer expression} and places
%   the binary representation of the result in the input stream.
% \end{function}
%
% \begin{function}[updated = 2011-09-17, EXP]{\int_to_hexadecimal:n}
%   \begin{syntax}
%     \cs{int_to_binary:n} \Arg{integer expression}
%   \end{syntax}
%   Calculates the value of the \meta{integer expression} and places
%   the hexadecimal (base~$16$) representation of the result in the
%   input stream. Upper case letters are used for digits beyond $9$.
% \end{function}
%
% \begin{function}[updated = 2011-09-17, EXP]{\int_to_octal:n}
%   \begin{syntax}
%     \cs{int_to_octal:n} \Arg{integer expression}
%   \end{syntax}
%   Calculates the value of the \meta{integer expression} and places
%   the octal (base~$8$) representation of the result in the input
%   stream.
% \end{function}
%
% \begin{function}[updated = 2011-09-17, EXP]{\int_to_base:nn}
%   \begin{syntax}
%     \cs{int_to_base:nn} \Arg{integer expression} \Arg{base}
%   \end{syntax}
%   Calculates the value of the \meta{integer expression} and
%   converts it into the appropriate representation in the \meta{base};
%   the later may be given as an integer expression. For bases greater
%   than $10$ the higher \enquote{digits} are represented by the upper case
%   letters from the English alphabet.
%   The maximum \meta{base} value is $36$.
%   \begin{texnote}
%     This is a generic version of \cs{int_to_binary:n}, \emph{etc.}
%   \end{texnote}
% \end{function}
%
% \begin{function}[updated = 2011-10-22, rEXP]{\int_to_roman:n, \int_to_Roman:n}
%   \begin{syntax}
%     \cs{int_to_roman:n} \Arg{integer expression}
%   \end{syntax}
%   Places the value of the \meta{integer expression} in the input
%   stream as Roman numerals, either lower case (\cs{int_to_roman:n})
%   or upper case (\cs{int_to_Roman:n}). The Roman numerals are letters
%   with category code $11$ (letter).
% \end{function}
%
% \section{Converting from other formats to integers}
%
% \begin{function}[EXP]{\int_from_alph:n}
%   \begin{syntax}
%     \cs{int_from_alpa:n} \Arg{letters}
%   \end{syntax}
%   Converts the \meta{letters} into the integer (base~$10$)
%   representation and leaves this in the input stream. The
%   \meta{letters} are treated using the English alphabet only, with
%   \enquote{a} equal to $1$ through to \enquote{z} equal to $26$. Either lower
%   or upper case letters may be used. This is the inverse function of
%   \cs{int_to_alph:n}.
% \end{function}
%
% \begin{function}[EXP]{\int_from_binary:n}
%   \begin{syntax}
%     \cs{int_from_binary:n} \Arg{binary number}
%   \end{syntax}
%   Converts the \meta{binary number} into the integer (base~$10$)
%   representation and leaves this in the input stream.
% \end{function}
%
% \begin{function}[EXP]{\int_from_hexadecimal:n}
%   \begin{syntax}
%     \cs{int_from_binary:n} \Arg{hexadecimal number}
%   \end{syntax}
%   Converts the \meta{hexadecimal number} into the integer
%   (base~$10$) representation and leaves this in the input stream.
%   Digits greater than $9$ may be represented in the
%   \meta{hexadecimal number} by upper or lower case letters.
% \end{function}
%
% \begin{function}[EXP]{\int_from_octal:n}
%   \begin{syntax}
%     \cs{int_from_octal:n} \Arg{octal number}
%   \end{syntax}
%   Converts the \meta{octal number} into the integer (base~$10$)
%   representation and leaves this in the input stream.
% \end{function}
%
% \begin{function}[EXP]{\int_from_roman:n}
%   \begin{syntax}
%     \cs{int_from_roman:n} \Arg{roman numeral}
%   \end{syntax}
%   Converts the \meta{roman numeral} into the integer (base~$10$)
%   representation and leaves this in the input stream. The
%   \meta{roman numeral} may be in upper or lower case; if the numeral
%   is not valid then the resulting value will be $-1$.
% \end{function}
%
% \begin{function}[EXP]{\int_from_base:nn}
%   \begin{syntax}
%     \cs{int_from_base:nn} \Arg{number} \Arg{base}
%   \end{syntax}
%   Converts the \meta{number} in \meta{base} into the appropriate
%   value in base $10$. The \meta{number} should consist of
%   digits and letters (either lower or upper case), plus optionally
%   a leading sign. The maximum \meta{base} value is $36$.
% \end{function}
%
% \section{Viewing integers}
%
% \begin{function}{\int_show:N, \int_show:c}
%   \begin{syntax}
%     \cs{int_show:N} \meta{integer}
%   \end{syntax}
%   Displays the value of the \meta{integer} on the terminal.
% \end{function}
%
% \begin{function}[added = 2011-11-22]{\int_show:n}
%   \begin{syntax}
%     \cs{int_show:n} \meta{integer expression}
%   \end{syntax}
%   Displays the result of evaluating the \meta{integer expression}
%   on the terminal.
% \end{function}
%
% \section{Constant integers}
%
% \begin{variable}
%   {
%     \c_minus_one              ,
%     \c_zero                   ,
%     \c_one                    ,
%     \c_two                    ,
%     \c_three                  ,
%     \c_four                   ,
%     \c_five                   ,
%     \c_six                    ,
%     \c_seven                  ,
%     \c_eight                  ,
%     \c_nine                   ,
%     \c_ten                    ,
%     \c_eleven                 ,
%     \c_twelve                 ,
%     \c_thirteen               ,
%     \c_fourteen               ,
%     \c_fifteen                ,
%     \c_sixteen                ,
%     \c_thirty_two             ,
%     \c_one_hundred            ,
%     \c_two_hundred_fifty_five ,
%     \c_two_hundred_fifty_six  ,
%     \c_one_thousand           ,
%     \c_ten_thousand
% }
%   Integer values used with primitive tests and assignments:
%   self-terminating nature makes these more convenient and faster than
%   literal numbers.
% \end{variable}
%
% \begin{variable}{\c_max_int}
%   The maximum value that can be stored as an integer.
% \end{variable}
%
% \begin{variable}{\c_max_register_int}
%   Maximum number of registers.
% \end{variable}
%
% \section{Scratch integers}
%
% \begin{variable}{\l_tmpa_int, \l_tmpb_int, \l_tmpc_int}
%   Scratch integer for local assignment. These are never used by
%   the kernel code, and so are safe for use with any \LaTeX3-defined
%   function. However, they may be overwritten by other non-kernel
%   code and so should only be used for short-term storage.
% \end{variable}
%
% \begin{variable}{\g_tmpa_int, \g_tmpb_int}
%   Scratch integer for global assignment. These are never used by
%   the kernel code, and so are safe for use with any \LaTeX3-defined
%   function. However, they may be overwritten by other non-kernel
%   code and so should only be used for short-term storage.
% \end{variable}
%
% \section{Internal functions}
%
% \begin{function}[EXP]{\int_get_digits:n}
%   \begin{syntax}
%     \cs{int_get_digits:n} \meta{value}
%   \end{syntax}
%     Parses the \meta{value} to leave the absolute \meta{value}
%     in the input stream. This may therefore be used
%     to remove multiple sign tokens from the \meta{value}
%     (which may be symbolic).
% \end{function}
%
% \begin{function}[rEXP]{\int_get_sign:n}
%   \begin{syntax}
%     \cs{int_get_sign:n} \meta{value}
%   \end{syntax}
%     Parses the \meta{value} to leave a single sign token
%     (either |+| or |-|) in the input stream. This may therefore be used
%     to sanitise sign tokens from the \meta{value} (which may be symbolic).
% \end{function}
%
% \begin{function}[updated = 2011-09-17, EXP]{\int_to_letter:n}
%   \begin{syntax}
%     \cs{int_to_letter:n} \meta{integer value}
%   \end{syntax}
%   For \meta{integer values} from $0$ to $9$, leaves the \meta{value}
%   in the input stream unchanged. For \meta{integer values} from
%   $10$ to $35$, leaves the appropriate upper case letter (from the
%   standard English alphabet) in the input stream: for example,
%   $10$ is converted to |A|, $11$ to |B|, \emph{etc.}
% \end{function}
%
% \begin{function}[EXP]{\int_to_roman:w}
%   \begin{syntax}
%     \cs{int_to_roman:w} \meta{integer} \meta{space} \textit{or} \meta{non-expandable token}
%   \end{syntax}
%   Converts \meta{integer} to it lower case Roman representation. Expansion
%   ends when a space or non-expandable token is found.
%   Note that this function produces a string of letters with category code
%   $12$ and that protected functions \emph{are} expanded by this
%   process. Negative \meta{integer} values result in no output, although
%   the function does not terminate expansion until a suitable endpoint
%   is found in the same way as for positive numbers.
%   \begin{texnote}
%     This is the \TeX{} primitive \tn{romannumeral} renamed.
%   \end{texnote}
% \end{function}
%
% \begin{function}[EXP]{\if_num:w, \if_int_compare:w}
%   \begin{syntax}
%     \cs{if_num:w} \meta{integer1} \meta{relation} \meta{integer2}
%     ~~\meta{true code}
%     \cs{else:}
%     ~~\meta{false code}
%     \cs{fi:}
%   \end{syntax}
%   Compare two integers using \meta{relation}, which must be one of
%   |=|, |<| or |>| with category code $12$.
%   The \cs{else:} branch is optional.
%   \begin{texnote}
%     These are both names for the \TeX{} primitive \tn{ifnum}.
%   \end{texnote}
% \end{function}
%
% \begin{function}[EXP]{\if_case:w, \or:}
%   \begin{syntax}
%     \cs{if_case:w} \meta{integer} \meta{case0}
%     ~~\cs{or:} \meta{case1}
%     ~~\cs{or:} |...|
%     ~~\cs{else:} \meta{default}
%     \cs{fi:}
%   \end{syntax}
%   Selects a case to execute based on the value of the \meta{integer}. The
%   first case (\meta{case0}) is executed if \meta{integer} is $0$, the second
%   (\meta{case1}) if the \meta{integer} is $1$, \emph{etc.} The
%   \meta{integer} may be a literal, a constant or an integer
%   expression (\emph{e.g.}~using \cs{int_eval:n}).
%   \begin{texnote}
%     These are the \TeX{} primitives \tn{ifcase} and \tn{or}.
%   \end{texnote}
% \end{function}
%
% \begin{function}[EXP]{\int_value:w}
%   \begin{syntax}
%     \cs{int_value:w} \meta{integer}
%     \cs{int_value:w} \meta{tokens} \meta{optional space}
%   \end{syntax}
%   Expands \meta{tokens} until an \meta{integer} is formed. One space may be
%   gobbled in the process.
%   \begin{texnote}
%     This is the \TeX{} primitive \tn{number}.
%   \end{texnote}
% \end{function}
%
% \begin{function}[EXP]{\int_eval:w, \int_eval_end:}
%   \begin{syntax}
%     \cs{int_eval:w} \meta{intexpr} \cs{int_eval_end:}
%   \end{syntax}
%   Evaluates \meta{integer expression} as described for \cs{int_eval:n}.
%   The evaluation stops when an unexpandable token which is not a valid
%   part of an integer is read or when \cs{int_eval_end:} is
%   reached. The latter is gobbled by the scanner mechanism:
%   \cs{int_eval_end:} itself is unexpandable but used correctly
%   the entire construct is expandable.
%   \begin{texnote}
%     This is the \eTeX{} primitive \tn{numexpr}.
%   \end{texnote}
% \end{function}
%
% \begin{function}[EXP]{\if_int_odd:w}
%   \begin{syntax}
%     \cs{if_int_odd:w} \meta{tokens}  \meta{optional space}
%     ~~\meta{true code}
%     \cs{else:}
%     ~~\meta{true code}
%     \cs{fi:}
%   \end{syntax}
%   Expands \meta{tokens} until a non-numeric token or a space is found, and
%   tests whether the resulting \meta{integer} is odd. If so, \meta{true code}
%   is executed. The \cs{else:} branch is optional.
%   \begin{texnote}
%     This is the \TeX{} primitive \tn{ifodd}.
%   \end{texnote}
% \end{function}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3int} implementation}
%
%    \begin{macrocode}
%<*initex|package>
%    \end{macrocode}
%
% \TestFiles{m3int001,m3int002,m3int03}
%
%    \begin{macrocode}
%<*package>
\ProvidesExplPackage
  {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
\package_check_loaded_expl:
%</package>
%    \end{macrocode}
%
% \begin{macro}{\int_to_roman:w}
% \begin{macro}{\if_int_compare:w}
%   Done in \pkg{l3basics}.
% \end{macro}
% \end{macro}
%
% \begin{macro}{\int_value:w}
% \begin{macro}{\int_eval:w}
% \begin{macro}{\int_eval_end:}
% \begin{macro}{\if_num:w}
% \begin{macro}{\if_int_odd:w}
% \begin{macro}{\if_case:w}
%   Here are the remaining primitives for number comparisons and
%   expressions.
%    \begin{macrocode}
\cs_new_eq:NN \int_value:w   \tex_number:D
\cs_new_eq:NN \int_eval:w    \etex_numexpr:D
\cs_new_eq:NN \int_eval_end: \tex_relax:D
\cs_new_eq:NN \if_num:w      \tex_ifnum:D
\cs_new_eq:NN \if_int_odd:w  \tex_ifodd:D
\cs_new_eq:NN \if_case:w     \tex_ifcase:D
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsection{Integer expressions}
%
% \begin{macro}{\int_eval:n}
%   Wrapper for \cs{int_eval:w}. Can be used in an integer expression
%   or directly in the input stream. In format mode, there is already
%   a definition in \pkg{l3alloc} for bookstrapping, which is therefore
%   corrected to the \enquote{real} version here.
%    \begin{macrocode}
%<*initex>
\cs_set:Npn \int_eval:n #1 { \int_value:w \int_eval:w #1 \int_eval_end: }
%</initex>
%<*package>
\cs_new:Npn \int_eval:n #1 { \int_value:w \int_eval:w #1 \int_eval_end: }
%</package>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\int_max:nn}
% \UnitTested
% \begin{macro}{\int_min:nn}
% \UnitTested
% \begin{macro}{\int_abs:n}
% \UnitTested
% Functions for $\min$, $\max$, and absolute value.
%    \begin{macrocode}
\cs_new:Npn \int_abs:n #1
  {
    \int_value:w
      \if_int_compare:w \int_eval:w #1 < \c_zero
        -
      \fi:
    \int_eval:w #1 \int_eval_end:
  }
\cs_new:Npn \int_max:nn #1#2
  {
    \int_value:w \int_eval:w
      \if_int_compare:w
        \int_eval:w #1 > \int_eval:w #2 \int_eval_end:
        #1
      \else:
        #2
      \fi:
    \int_eval_end:
  }
\cs_new:Npn \int_min:nn #1#2
  {
    \int_value:w \int_eval:w
      \if_int_compare:w
        \int_eval:w #1 < \int_eval:w #2 \int_eval_end:
        #1
      \else:
        #2
      \fi:
    \int_eval_end:
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}[EXP]{\int_div_truncate:nn}
% \UnitTested
% \begin{macro}[EXP]{\int_div_round:nn}
% \UnitTested
% \begin{macro}[EXP]{\int_mod:nn}
% \UnitTested
% \begin{macro}[aux, EXP]{\int_div_truncate_aux:NwNw}
%   As \cs{int_eval:w} rounds the result of a division we also provide a
%   version that truncates the result. We use an auxiliary to make sure
%   numerator and denominator are only evaluated once: this comes in
%   handy when those are more expressions are expensive to evaluate
%   (\emph{e.g.}, \cs{tl_length:n}). If the numerator |#1#2| is $0$,
%   then we divide $0$ by the denominator (this ensures that $0/0$ is
%   correctly reported as an error). Otherwise, shift the numerator
%   |#1#2| towards $0$ by $(\left\vert\texttt{\#3\#4}\right\vert-1)/2$, which we
%   round away from zero. It turns out that this quantity exactly
%   compensates the difference between \eTeX{}'s rounding and the
%   truncating behaviour that we want. The details are thanks to Heiko
%   Oberdiek: getting things right in all cases is not so easy.
%    \begin{macrocode}
\cs_new:Npn \int_div_truncate:nn #1#2
  {
    \int_use:N \int_eval:w
      \exp_after:wN \int_div_truncate_aux:NwNw
      \int_use:N \int_eval:w #1 \exp_after:wN ;
      \int_use:N \int_eval:w #2 ;
    \int_eval_end:
  }
\cs_new:Npn \int_div_truncate_aux:NwNw #1#2; #3#4;
  {
    \if_meaning:w 0 #1
      \c_zero
    \else:
      (
        #1#2
        \if_meaning:w - #1 + \else: - \fi:
        ( \if_meaning:w - #3 - \fi: #3#4 - \c_one ) / \c_two
      )
    \fi:
    / #3#4
  }
%    \end{macrocode}
%   For the sake of completeness:
%    \begin{macrocode}
\cs_new:Npn \int_div_round:nn #1#2 { \int_eval:n { ( #1 ) / ( #2 ) } }
%    \end{macrocode}
%   Finally there's the modulus operation.
%    \begin{macrocode}
\cs_new:Npn \int_mod:nn #1#2
  {
    \int_value:w \int_eval:w
      #1 - \int_div_truncate:nn {#1} {#2} * ( #2 )
    \int_eval_end:
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsection{Creating and initialising integers}
%
% \begin{macro}{\int_new:N, \int_new:c}
% \UnitTested
%   Two ways to do this: one for the format and one for the \LaTeXe{}
%   package.
%    \begin{macrocode}
%<*package>
\cs_new_protected:Npn \int_new:N #1
  {
    \chk_if_free_cs:N #1
    \newcount #1
  }
%</package>
\cs_generate_variant:Nn \int_new:N { c }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\int_const:Nn, \int_const:cn}
% \begin{macro}[aux]{\int_constdef:Nw}
% \begin{variable}{\c_max_const_int}
% \UnitTested
%   As stated, most constants can be defined as \tn{chardef} or
%   \tn{mathchardef} but that's engine dependent. As a result, there is some
%   set up code to determine what can be done.
%    \begin{macrocode}
\cs_new_protected:Npn \int_const:Nn #1#2
  {
    \int_compare:nNnTF {#2} > \c_minus_one
      {
        \int_compare:nNnTF {#2} > \c_max_const_int
          {
            \int_new:N #1
            \int_gset:Nn #1 {#2}
          }
          {
            \chk_if_free_cs:N #1
            \tex_global:D \int_constdef:Nw #1 =
              \int_eval:w #2 \int_eval_end:
          }
      }
      {
        \int_new:N #1
        \int_gset:Nn #1 {#2}
      }
  }
\cs_generate_variant:Nn \int_const:Nn { c }
\pdftex_if_engine:TF
  {
    \cs_new_eq:NN \int_constdef:Nw \tex_mathchardef:D
    \tex_mathchardef:D \c_max_const_int 32 767 ~
  }
  {
    \cs_new_eq:NN \int_constdef:Nw \tex_chardef:D
    \tex_chardef:D \c_max_const_int 1 114 111 ~
  }
%    \end{macrocode}
% \end{variable}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\int_zero:N, \int_zero:c}
% \UnitTested
% \begin{macro}{\int_gzero:N, \int_gzero:c}
% \UnitTested
%   Functions that reset an \meta{integer} register to zero.
%    \begin{macrocode}
\cs_new_protected:Npn \int_zero:N  #1 { #1 = \c_zero }
\cs_new_protected:Npn \int_gzero:N #1 { \tex_global:D #1 = \c_zero }
\cs_generate_variant:Nn \int_zero:N  { c }
\cs_generate_variant:Nn \int_gzero:N { c }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}
%   {\int_zero_new:N, \int_zero_new:c, \int_gzero_new:N, \int_gzero_new:c}
%   Create a register if needed, otherwise clear it.
%    \begin{macrocode}
\cs_new_protected:Npn \int_zero_new:N  #1
  { \int_if_exist:NTF #1 { \int_zero:N #1 } { \int_new:N #1 } }
\cs_new_protected:Npn \int_gzero_new:N #1
  { \int_if_exist:NTF #1 { \int_gzero:N #1 } { \int_new:N #1 } }
\cs_generate_variant:Nn \int_zero_new:N  { c }
\cs_generate_variant:Nn \int_gzero_new:N { c }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\int_set_eq:NN,\int_set_eq:cN, \int_set_eq:Nc,\int_set_eq:cc}
% \UnitTested
% \begin{macro}
%   {\int_gset_eq:NN,\int_gset_eq:cN, \int_gset_eq:Nc,\int_gset_eq:cc}
% \UnitTested
%   Setting equal means using one integer inside the set function of
%   another.
%    \begin{macrocode}
\cs_new_protected:Npn \int_set_eq:NN #1#2 { #1 = #2 }
\cs_generate_variant:Nn \int_set_eq:NN {       c }
\cs_generate_variant:Nn \int_set_eq:NN { Nc , cc }
\cs_new_protected:Npn \int_gset_eq:NN #1#2 { \tex_global:D #1 = #2 }
\cs_generate_variant:Nn \int_gset_eq:NN {       c }
\cs_generate_variant:Nn \int_gset_eq:NN { Nc , cc }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}[pTF]{\int_if_exist:N, \int_if_exist:c}
%   Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
%    \begin{macrocode}
\cs_new_eq:NN \int_if_exist:NTF \cs_if_exist:NTF
\cs_new_eq:NN \int_if_exist:NT  \cs_if_exist:NT
\cs_new_eq:NN \int_if_exist:NF  \cs_if_exist:NF
\cs_new_eq:NN \int_if_exist_p:N \cs_if_exist_p:N
\cs_new_eq:NN \int_if_exist:cTF \cs_if_exist:cTF
\cs_new_eq:NN \int_if_exist:cT  \cs_if_exist:cT
\cs_new_eq:NN \int_if_exist:cF  \cs_if_exist:cF
\cs_new_eq:NN \int_if_exist_p:c \cs_if_exist_p:c
%    \end{macrocode}
% \end{macro}
%
% \subsection{Setting and incrementing integers}
%
% \begin{macro}{\int_add:Nn, \int_add:cn}
% \UnitTested
% \begin{macro}{\int_gadd:Nn, \int_gadd:cn}
% \UnitTested
% \begin{macro}{\int_sub:Nn, \int_sub:cn}
% \UnitTested
% \begin{macro}{\int_gsub:Nn, \int_gsub:cn}
% \UnitTested
%    Adding and subtracting to and from a counter \ldots
%    \begin{macrocode}
\cs_new_protected:Npn \int_add:Nn #1#2
  { \tex_advance:D #1 by \int_eval:w #2 \int_eval_end: }
\cs_new_protected:Npn \int_sub:Nn #1#2
  { \tex_advance:D #1 by - \int_eval:w #2 \int_eval_end: }
\cs_new_protected_nopar:Npn \int_gadd:Nn
  { \tex_global:D \int_add:Nn }
\cs_new_protected_nopar:Npn \int_gsub:Nn
  { \tex_global:D \int_sub:Nn }
\cs_generate_variant:Nn \int_add:Nn  { c }
\cs_generate_variant:Nn \int_gadd:Nn { c }
\cs_generate_variant:Nn \int_sub:Nn  { c }
\cs_generate_variant:Nn \int_gsub:Nn { c }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\int_incr:N, \int_incr:c}
% \UnitTested
% \begin{macro}{\int_gincr:N, \int_gincr:c}
% \UnitTested
% \begin{macro}{\int_decr:N, \int_decr:c}
% \UnitTested
% \begin{macro}{\int_gdecr:N, \int_gdecr:c}
% \UnitTested
%   Incrementing and decrementing of integer registers is done with
%   the following functions.
%    \begin{macrocode}
\cs_new_protected:Npn \int_incr:N #1
  { \tex_advance:D #1 \c_one }
\cs_new_protected:Npn \int_decr:N #1
  { \tex_advance:D #1 \c_minus_one }
\cs_new_protected_nopar:Npn \int_gincr:N
  { \tex_global:D \int_incr:N }
\cs_new_protected_nopar:Npn \int_gdecr:N
  { \tex_global:D \int_decr:N }
\cs_generate_variant:Nn \int_incr:N  { c }
\cs_generate_variant:Nn \int_decr:N  { c }
\cs_generate_variant:Nn \int_gincr:N { c }
\cs_generate_variant:Nn \int_gdecr:N { c }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\int_set:Nn, \int_set:cn}
% \UnitTested
% \begin{macro}{\int_gset:Nn, \int_gset:cn}
% \UnitTested
%   As integers are register-based \TeX{} will issue an error
%   if they are not defined. Thus there is no need for the checking
%   code seen with token list variables.
%    \begin{macrocode}
\cs_new_protected:Npn \int_set:Nn #1#2
  { #1 ~ \int_eval:w #2\int_eval_end: }
\cs_new_protected_nopar:Npn \int_gset:Nn { \tex_global:D \int_set:Nn }
\cs_generate_variant:Nn \int_set:Nn  { c }
\cs_generate_variant:Nn \int_gset:Nn { c }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsection{Using integers}
%
% \begin{macro}{\int_use:N, \int_use:c}
% \UnitTested
%    Here is how counters are accessed:
%    \begin{macrocode}
\cs_new_eq:NN \int_use:N \tex_the:D
\cs_new:Npn \int_use:c #1 { \int_use:N \cs:w #1 \cs_end: }
%    \end{macrocode}
% \end{macro}
%
% \subsection{Integer expression conditionals}
%
% \begin{macro}[aux, EXP]{\kernel_compare_error:, \kernel_compare_error:NNw}
%   Those functions are used for comparison tests which use a simple
%   syntax where only one set of braces is required and additional
%   operators such as |!=| and |>=| are supported.  The tests first
%   evaluate their left-hand side, with a trailing
%   \cs{kernel_compare_error:}. This marker is normally not expanded,
%   but if the relation symbol is missing from the test's argument, then
%   the marker inserts |=| (and itself) after triggering the relevant
%   \TeX{} error.  If the first token which appears after evaluating and
%   removing the left-hand side is not a known relation symbol, then a
%   judiciously placed \cs{kernel_compare_error:Nw} gets expanded,
%   cleaning up the end of the test and telling the user what the
%   problem was.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \kernel_compare_error:
  {
    \if_num:w \c_zero \c_zero \fi:
    =
    \kernel_compare_error:
  }
\cs_new:Npn \kernel_compare_error:Nw
    #1#2 \prg_return_true: \else: \prg_return_false: \fi:
  {
    \msg_expandable_kernel_error:nnn
      { kernel } { unknown-comparison } {#1}
    \prg_return_false:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[pTF, EXP]{\int_compare:n}
% \begin{macro}[aux, EXP]{\int_compare_aux:Nw, \int_compare_aux:NNw}
% \begin{macro}[aux, EXP]
%   {
%     \int_compare_=:NNw,
%     \int_compare_<:NNw,
%     \int_compare_>:NNw,
%     \int_compare_==:NNw,
%     \int_compare_!=:NNw,
%     \int_compare_<=:NNw,
%     \int_compare_>=:NNw
%   }
%   Comparison tests using a simple syntax where only one set of braces
%   is required and additional operators such as |!=| and |>=| are
%   supported.  We can start evaluating from the left using
%   \cs{int_eval:w}, and we know that since the relation symbols |<|,
%   |>|, |=| and |!| are not allowed in such expressions, they will
%   terminate the expression.  Therefore, we first let \TeX{} evaluate
%   this left hand side of the (in)equality.  We also insert at that
%   stage the end of the test: \cs{int_eval_end:} will end the
%   evaluation of the right-hand side.
%    \begin{macrocode}
\prg_new_conditional:Npnn \int_compare:n #1 { p , T , F , TF }
  {
    \exp_after:wN \int_compare_aux:Nw \int_use:N \int_eval:w #1
        \kernel_compare_error: \int_eval_end:
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
%    \end{macrocode}
%   We have just evaluated the left-hand side.  To access the relation
%   symbol, we remove the number by applying \cs{int_to_roman:w}, after
%   making sure that the argument becomes non-positive: its roman
%   numeral representation is then empty.  The \cs{int_compare_aux:NNw}
%   auxiliary then probes the first two tokens to determine the relation
%   symbol, building a control sequence from it.  All the extended forms
%   have an extra |=| hence the test for that as a second token.  If the
%   relation symbol is unknown, then the control sequence is turned by
%   \TeX{} into \cs{scan_stop:}, and \cs{kernel_compare_error:Nw}
%   raises an error.
%    \begin{macrocode}
\cs_new:Npn \int_compare_aux:Nw #1#2 \kernel_compare_error:
  {
    \exp_after:wN \int_compare_aux:NNw
      \int_to_roman:w - 0 #2 ?? \q_mark
    #1#2
  }
\cs_new:Npn \int_compare_aux:NNw #1#2#3 \q_mark
  {
    \use:c { int_compare_  #1  \if_meaning:w = #2 =  \fi: :NNw }
      \kernel_compare_error:Nw #1
  }
%    \end{macrocode}
%   The actual comparisons are then simple function calls, using the
%   relation as delimiter for a delimited argument and discarding
%   \cs{kernel_compare_error:Nw} \meta{token} responsible for error
%   detection.
%    \begin{macrocode}
\cs_new:cpn { int_compare_=:NNw } #1#2#3 =
  { \if_int_compare:w #3 = \int_eval:w }
\cs_new:cpn { int_compare_<:NNw } #1#2#3 <
  { \if_int_compare:w #3 < \int_eval:w }
\cs_new:cpn { int_compare_>:NNw } #1#2#3 >
  { \if_int_compare:w #3 > \int_eval:w }
\cs_new:cpn { int_compare_==:NNw } #1#2#3 ==
  { \if_int_compare:w #3 = \int_eval:w }
\cs_new:cpn { int_compare_!=:NNw } #1#2#3 !=
  { \reverse_if:N \if_int_compare:w #3 = \int_eval:w }
\cs_new:cpn { int_compare_<=:NNw } #1#2#3 <=
  { \reverse_if:N \if_int_compare:w #3 > \int_eval:w }
\cs_new:cpn { int_compare_>=:NNw } #1#2#3 >=
  { \reverse_if:N \if_int_compare:w #3 < \int_eval:w }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}[pTF]{\int_compare:nNn}
% \UnitTested
% More efficient but less natural in typing.
%    \begin{macrocode}
\prg_new_conditional:Npnn \int_compare:nNn #1#2#3 { p , T , F , TF}
  {
    \if_int_compare:w \int_eval:w #1 #2 \int_eval:w #3 \int_eval_end:
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[pTF]{\int_if_odd:n}
% \UnitTested
% \begin{macro}[pTF]{\int_if_even:n}
% \UnitTested
%   A predicate function.
%    \begin{macrocode}
\prg_new_conditional:Npnn \int_if_odd:n #1 { p , T , F , TF}
  {
    \if_int_odd:w \int_eval:w #1 \int_eval_end:
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\prg_new_conditional:Npnn \int_if_even:n #1 { p , T , F , TF}
  {
    \if_int_odd:w \int_eval:w #1 \int_eval_end:
      \prg_return_false:
    \else:
      \prg_return_true:
    \fi:
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsection{Integer expression loops}
%
% \begin{macro}{\int_while_do:nn}
% \UnitTested
% \TestMissing{Boundary cases}
% \begin{macro}{\int_until_do:nn}
% \UnitTested
% \TestMissing{Boundary cases}
% \begin{macro}{\int_do_while:nn}
% \UnitTested
% \TestMissing{Boundary cases}
% \begin{macro}{\int_do_until:nn}
% \UnitTested
% \TestMissing{Boundary cases}
%   These are quite easy given the above functions. The |while| versions
%   test first and then execute the body. The |do_while| does it the
%   other way round.
%    \begin{macrocode}
\cs_new:Npn \int_while_do:nn #1#2
  {
    \int_compare:nT {#1}
      {
        #2
        \int_while_do:nn {#1} {#2}
      }
  }
\cs_new:Npn \int_until_do:nn #1#2
  {
    \int_compare:nF {#1}
      {
        #2
        \int_until_do:nn {#1} {#2}
      }
  }
\cs_new:Npn \int_do_while:nn #1#2
  {
    #2
    \int_compare:nT {#1}
      { \int_do_while:nn {#1} {#2} }
  }
\cs_new:Npn \int_do_until:nn #1#2
  {
    #2
    \int_compare:nF {#1}
      { \int_do_until:nn {#1} {#2} }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\int_while_do:nNnn}
% \begin{macro}{\int_until_do:nNnn}
% \begin{macro}{\int_do_while:nNnn}
% \begin{macro}{\int_do_until:nNnn}
%    As above but not using the more natural syntax.
%    \begin{macrocode}
\cs_new:Npn \int_while_do:nNnn #1#2#3#4
  {
    \int_compare:nNnT {#1} #2 {#3}
      {
        #4
        \int_while_do:nNnn {#1} #2 {#3} {#4}
      }
  }
\cs_new:Npn \int_until_do:nNnn #1#2#3#4
  {
  \int_compare:nNnF {#1} #2 {#3}
    {
      #4
      \int_until_do:nNnn {#1} #2 {#3} {#4}
    }
  }
\cs_new:Npn \int_do_while:nNnn #1#2#3#4
  {
    #4
    \int_compare:nNnT {#1} #2 {#3}
      { \int_do_while:nNnn {#1} #2 {#3} {#4} }
  }
\cs_new:Npn \int_do_until:nNnn #1#2#3#4
  {
    #4
    \int_compare:nNnF {#1} #2 {#3}
      { \int_do_until:nNnn {#1} #2 {#3} {#4} }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsection{Formatting integers}
%
% \begin{macro}{\int_to_arabic:n}
% \UnitTested
%   Nothing exciting here.
%    \begin{macrocode}
\cs_new:Npn \int_to_arabic:n #1 { \int_eval:n {#1} }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\int_to_symbols:nnn}
% \UnitTested
%   For conversion of integers to arbitrary symbols the method is in
%   general as follows. The input number (|#1|) is compared to the total
%   number of symbols available at each place (|#2|). If the input is larger
%   than the total number of symbols available then the modulus is needed,
%   with one added so that the positions don't have to number from
%   zero. Using an \texttt{f}-type expansion, this is done so that the system
%   is recursive. The actual conversion function therefore gets a `nice'
%   number at each stage. Of course, if the initial input was small enough
%   then there is no problem and everything is easy.
%    \begin{macrocode}
\cs_new:Npn \int_to_symbols:nnn #1#2#3
  {
    \int_compare:nNnTF {#1} > {#2}
      {
        \exp_args:NNo \exp_args:No \int_to_symbols_aux:nnnn
          {
            \prg_case_int:nnn
              { 1 + \int_mod:nn { #1 - 1 } {#2} }
              {#3} { }
          }
          {#1} {#2} {#3}
      }
      { \prg_case_int:nnn {#1} {#3} { } }
  }
\cs_new:Npn \int_to_symbols_aux:nnnn #1#2#3#4
  {
    \exp_args:Nf \int_to_symbols:nnn
      { \int_div_truncate:nn { #2 - 1 } {#3} } {#3} {#4}
    #1
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\int_to_alph:n,\int_to_Alph:n}
% \UnitTested
%   These both use the above function with input functions that make sense
%   for the alphabet in English.
%    \begin{macrocode}
\cs_new:Npn \int_to_alph:n #1
  {
    \int_to_symbols:nnn {#1} { 26 }
      {
        {  1 } { a }
        {  2 } { b }
        {  3 } { c }
        {  4 } { d }
        {  5 } { e }
        {  6 } { f }
        {  7 } { g }
        {  8 } { h }
        {  9 } { i }
        { 10 } { j }
        { 11 } { k }
        { 12 } { l }
        { 13 } { m }
        { 14 } { n }
        { 15 } { o }
        { 16 } { p }
        { 17 } { q }
        { 18 } { r }
        { 19 } { s }
        { 20 } { t }
        { 21 } { u }
        { 22 } { v }
        { 23 } { w }
        { 24 } { x }
        { 25 } { y }
        { 26 } { z }
      }
  }
\cs_new:Npn \int_to_Alph:n #1
  {
    \int_to_symbols:nnn {#1} { 26 }
      {
        {  1 } { A }
        {  2 } { B }
        {  3 } { C }
        {  4 } { D }
        {  5 } { E }
        {  6 } { F }
        {  7 } { G }
        {  8 } { H }
        {  9 } { I }
        { 10 } { J }
        { 11 } { K }
        { 12 } { L }
        { 13 } { M }
        { 14 } { N }
        { 15 } { O }
        { 16 } { P }
        { 17 } { Q }
        { 18 } { R }
        { 19 } { S }
        { 20 } { T }
        { 21 } { U }
        { 22 } { V }
        { 23 } { W }
        { 24 } { X }
        { 25 } { Y }
        { 26 } { Z }
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\int_to_base:nn}
% \UnitTested
% \begin{macro}[aux]{\int_to_base_aux_i:nn,
%     \int_to_base_aux_ii:nnN,\int_to_base_aux_iii:nnnN}
% \begin{macro}[int]{\int_to_letter:n}
% \UnitTested
%   Converting from base ten (|#1|) to a second base (|#2|) starts with
%   computing |#1|: if it is a complicated calculation, we shouldn't
%   perform it twice. Then check the sign, store it, either \texttt{-}
%   or \cs{c_empty_tl}, and feed the absolute value to the next auxiliary
%   function.
%    \begin{macrocode}
\cs_new:Npn \int_to_base:nn #1
  { \exp_args:Nf \int_to_base_aux_i:nn { \int_eval:n {#1} } }
\cs_new:Npn \int_to_base_aux_i:nn #1#2
  {
    \int_compare:nNnTF {#1} < \c_zero
      { \exp_args:No \int_to_base_aux_ii:nnN { \use_none:n #1 } {#2} - }
      { \int_to_base_aux_ii:nnN {#1} {#2} \c_empty_tl }
  }
%    \end{macrocode}
%   Here, the idea is to provide a recursive system to deal with the
%   input. The output is built up after the end of the function.
%   At each pass, the value in |#1| is checked to see if it is less
%   than the new base (|#2|). If it is, then it is converted directly,
%   putting the sign back in front.
%   On the other hand, if the value to convert is greater than or equal
%   to the new base then the modulus and remainder values are found. The
%   modulus is converted to a symbol and put on the right,
%   and the remainder is carried forward to the next round.
%    \begin{macrocode}
\cs_new:Npn \int_to_base_aux_ii:nnN #1#2#3
  {
    \int_compare:nNnTF {#1} < {#2}
      { \exp_last_unbraced:Nf #3 { \int_to_letter:n {#1} } }
      {
        \exp_args:Nf \int_to_base_aux_iii:nnnN
          { \int_to_letter:n { \int_mod:nn {#1} {#2} } }
          {#1}
          {#2}
          #3
      }
  }
\cs_new:Npn \int_to_base_aux_iii:nnnN #1#2#3#4
  {
    \exp_args:Nf \int_to_base_aux_ii:nnN
      { \int_div_truncate:nn {#2} {#3} }
      {#3}
      #4
    #1
  }
%    \end{macrocode}
%   Convert to a letter only if necessary, otherwise simply return the
%   value unchanged. It would be cleaner to use \cs{prg_case_int:nnn},
%   but in our case, the cases are contiguous, so it is forty times faster
%   to use the \cs{if_case:w} primitive. The first \cs{exp_after:wN}
%   expands the conditional, jumping to the correct case, the second one
%   expands after the resulting character to close the conditional.
%   Since |#1| might be an expression, and not directly a single digit,
%   we need to evaluate it properly, and expand the trailing \cs{fi:}.
%    \begin{macrocode}
\cs_new:Npn \int_to_letter:n #1
  {
    \exp_after:wN \exp_after:wN
    \if_case:w \int_eval:w #1 - \c_ten \int_eval_end:
         A
    \or: B
    \or: C
    \or: D
    \or: E
    \or: F
    \or: G
    \or: H
    \or: I
    \or: J
    \or: K
    \or: L
    \or: M
    \or: N
    \or: O
    \or: P
    \or: Q
    \or: R
    \or: S
    \or: T
    \or: U
    \or: V
    \or: W
    \or: X
    \or: Y
    \or: Z
    \else: \int_value:w \int_eval:w #1 \exp_after:wN \int_eval_end:
    \fi:
  }
%    \end{macrocode}
%\end{macro}
%\end{macro}
%\end{macro}
%
% \begin{macro}{\int_to_binary:n, \int_to_hexadecimal:n, \int_to_octal:n}
% \UnitTested
%   Wrappers around the generic function.
%    \begin{macrocode}
\cs_new:Npn \int_to_binary:n #1
  { \int_to_base:nn {#1} { 2 } }
\cs_new:Npn \int_to_hexadecimal:n #1
  { \int_to_base:nn {#1} { 16 } }
\cs_new:Npn \int_to_octal:n #1
  { \int_to_base:nn {#1} { 8 } }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\int_to_roman:n, \int_to_Roman:n}
% \UnitTested
% \begin{macro}[aux]{\int_to_roman_aux:N, \int_to_roman_aux:N}
% \begin{macro}[aux]
%   {
%     \int_to_roman_i:w, \int_to_roman_v:w, \int_to_roman_x:w,
%     \int_to_roman_l:w, \int_to_roman_c:w, \int_to_roman_d:w,
%     \int_to_roman_m:w, \int_to_roman_Q:w,
%     \int_to_Roman_i:w, \int_to_Roman_v:w, \int_to_Roman_x:w,
%     \int_to_Roman_l:w, \int_to_Roman_c:w, \int_to_Roman_d:w,
%     \int_to_Roman_m:w, \int_to_Roman_Q:w,
%   }
% The \cs{int_to_roman:w} primitive creates tokens of category
% code $12$ (other). Usually, what is actually wanted is letters.
% The approach here is to convert the output of the primitive into
% letters using appropriate control sequence names. That keeps
% everything expandable. The loop will be terminated by the conversion
% of the |Q|.
%    \begin{macrocode}
\cs_new:Npn \int_to_roman:n #1
  {
    \exp_after:wN \int_to_roman_aux:N
      \int_to_roman:w \int_eval:n {#1} Q
  }
\cs_new:Npn \int_to_roman_aux:N #1
  {
    \use:c { int_to_roman_ #1 :w }
    \int_to_roman_aux:N
  }
\cs_new:Npn \int_to_Roman:n #1
  {
    \exp_after:wN \int_to_Roman_aux:N
      \int_to_roman:w \int_eval:n {#1} Q
  }
\cs_new:Npn \int_to_Roman_aux:N #1
  {
    \use:c { int_to_Roman_ #1 :w }
    \int_to_Roman_aux:N
  }
\cs_new_nopar:Npn \int_to_roman_i:w { i }
\cs_new_nopar:Npn \int_to_roman_v:w { v }
\cs_new_nopar:Npn \int_to_roman_x:w { x }
\cs_new_nopar:Npn \int_to_roman_l:w { l }
\cs_new_nopar:Npn \int_to_roman_c:w { c }
\cs_new_nopar:Npn \int_to_roman_d:w { d }
\cs_new_nopar:Npn \int_to_roman_m:w { m }
\cs_new_nopar:Npn \int_to_roman_Q:w #1 { }
\cs_new_nopar:Npn \int_to_Roman_i:w { I }
\cs_new_nopar:Npn \int_to_Roman_v:w { V }
\cs_new_nopar:Npn \int_to_Roman_x:w { X }
\cs_new_nopar:Npn \int_to_Roman_l:w { L }
\cs_new_nopar:Npn \int_to_Roman_c:w { C }
\cs_new_nopar:Npn \int_to_Roman_d:w { D }
\cs_new_nopar:Npn \int_to_Roman_m:w { M }
\cs_new:Npn \int_to_Roman_Q:w #1 { }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsection{Converting from other formats to integers}
%
% \begin{macro}[int]{\int_get_sign:n}
% \begin{macro}[int]{\int_get_digits:n}
% \begin{macro}[aux]
%   {\int_get_sign_and_digits_aux:nNNN, \int_get_sign_and_digits_aux:oNNN}
%   Finding a number and its sign requires dealing with an arbitrary
%   list of |+| and |-| symbols. This is done by working through token
%   by token until there is something else at the start of the input.
%   The sign of the input is tracked by the first Boolean used by the
%   auxiliary function.
%    \begin{macrocode}
\cs_new:Npn \int_get_sign:n #1
  {
    \int_get_sign_and_digits_aux:nNNN {#1}
      \c_true_bool \c_true_bool \c_false_bool
  }
\cs_new:Npn \int_get_digits:n #1
  {
    \int_get_sign_and_digits_aux:nNNN {#1}
      \c_true_bool \c_false_bool \c_true_bool
  }
%    \end{macrocode}
%   The auxiliary loops through, finding sign tokens and removing them.
%   The sign itself is carried through as a flag.
%    \begin{macrocode}
\cs_new:Npn \int_get_sign_and_digits_aux:nNNN #1#2#3#4
  {
    \exp_args:Nf \tl_if_head_eq_charcode:nNTF {#1} -
      {
        \bool_if:NTF #2
          {
            \int_get_sign_and_digits_aux:oNNN
              { \use_none:n #1 } \c_false_bool #3#4
          }
          {
            \int_get_sign_and_digits_aux:oNNN
              { \use_none:n #1 } \c_true_bool #3#4
          }
      }
      {
        \exp_args:Nf \tl_if_head_eq_charcode:nNTF {#1} +
          { \int_get_sign_and_digits_aux:oNNN { \use_none:n #1 } #2#3#4 }
          {
            \bool_if:NT #3 { \bool_if:NF #2 - }
            \bool_if:NT #4 {#1}
          }
      }
  }
\cs_generate_variant:Nn \int_get_sign_and_digits_aux:nNNN { o }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\int_from_alph:n}
% \UnitTested
% \begin{macro}[aux]{\int_from_alph_aux:n}
% \begin{macro}[aux]{\int_from_alph_aux:nN}
% \begin{macro}[aux]{\int_from_alph_aux:N}
%   The aim here is to iterate through the input, converting one letter at
%   a time to a number. The same approach is also used for base
%   conversion, but this needs a different final auxiliary.
%    \begin{macrocode}
\cs_new:Npn \int_from_alph:n #1
  {
    \int_eval:n
      {
        \int_get_sign:n {#1}
        \exp_args:Nf \int_from_alph_aux:n { \int_get_digits:n {#1} }
      }
  }
\cs_new:Npn \int_from_alph_aux:n #1
  { \int_from_alph_aux:nN { 0 } #1 \q_nil }
\cs_new:Npn \int_from_alph_aux:nN #1#2
  {
    \quark_if_nil:NTF #2
      {#1}
      {
        \exp_args:Nf \int_from_alph_aux:nN
          { \int_eval:n { #1 * 26 + \int_from_alph_aux:N #2 } }
      }
  }
\cs_new:Npn \int_from_alph_aux:N #1
  { \int_eval:n { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 64 } { 96 } } }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\int_from_base:nn}
% \UnitTested
% \begin{macro}[aux]{\int_from_base_aux:nn}
% \begin{macro}[aux]{\int_from_base_aux:nnN}
% \begin{macro}[aux]{\int_from_base_aux:N}
%   Conversion to base ten means stripping off the sign then iterating
%   through the input one token at a time. The total number is then added
%   up as the code loops.
%    \begin{macrocode}
\cs_new:Npn \int_from_base:nn #1#2
  {
    \int_eval:n
      {
        \int_get_sign:n {#1}
        \exp_args:Nf \int_from_base_aux:nn
          { \int_get_digits:n {#1} } {#2}
      }
  }
\cs_new:Npn \int_from_base_aux:nn #1#2
  { \int_from_base_aux:nnN { 0 } { #2 } #1 \q_nil }
\cs_new:Npn \int_from_base_aux:nnN #1#2#3
  {
    \quark_if_nil:NTF #3
      {#1}
      {
        \exp_args:Nf \int_from_base_aux:nnN
          { \int_eval:n { #1 * #2 + \int_from_base_aux:N #3 } }
          {#2}
      }
  }
%    \end{macrocode}
%   The conversion here will take lower or upper case letters and turn
%   them into the appropriate number, hence the two-part nature of the
%   function.
%    \begin{macrocode}
\cs_new:Npn \int_from_base_aux:N #1
  {
    \int_compare:nNnTF { `#1 } < { 58 }
      {#1}
      {
        \int_eval:n
          { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 55 } { 87 } }
      }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\int_from_binary:n, \int_from_hexadecimal:n, \int_from_octal:n}
% \UnitTested
%   Wrappers around the generic function.
%    \begin{macrocode}
\cs_new:Npn \int_from_binary:n #1
  { \int_from_base:nn {#1} \c_two }
\cs_new:Npn \int_from_hexadecimal:n #1
  { \int_from_base:nn {#1} \c_sixteen }
\cs_new:Npn \int_from_octal:n #1
  { \int_from_base:nn {#1} \c_eight }
%    \end{macrocode}
% \end{macro}
%
% \begin{variable}
%   {
%     \c_int_from_roman_i_int, \c_int_from_roman_v_int,
%     \c_int_from_roman_x_int, \c_int_from_roman_l_int,
%     \c_int_from_roman_c_int, \c_int_from_roman_d_int,
%     \c_int_from_roman_m_int,
%     \c_int_from_roman_I_int, \c_int_from_roman_V_int,
%     \c_int_from_roman_X_int, \c_int_from_roman_L_int,
%     \c_int_from_roman_C_int, \c_int_from_roman_D_int,
%     \c_int_from_roman_M_int
%  }
% Constants used to convert from Roman numerals to integers.
%    \begin{macrocode}
\int_const:cn { c_int_from_roman_i_int } { 1 }
\int_const:cn { c_int_from_roman_v_int } { 5 }
\int_const:cn { c_int_from_roman_x_int } { 10 }
\int_const:cn { c_int_from_roman_l_int } { 50 }
\int_const:cn { c_int_from_roman_c_int } { 100 }
\int_const:cn { c_int_from_roman_d_int } { 500 }
\int_const:cn { c_int_from_roman_m_int } { 1000 }
\int_const:cn { c_int_from_roman_I_int } { 1 }
\int_const:cn { c_int_from_roman_V_int } { 5 }
\int_const:cn { c_int_from_roman_X_int } { 10 }
\int_const:cn { c_int_from_roman_L_int } { 50 }
\int_const:cn { c_int_from_roman_C_int } { 100 }
\int_const:cn { c_int_from_roman_D_int } { 500 }
\int_const:cn { c_int_from_roman_M_int } { 1000 }
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\int_from_roman:n}
% \UnitTested
% \TestMissing{boundary cases / wrong input?}
% \begin{macro}[aux]{\int_from_roman_aux:NN}
% \begin{macro}[aux]{\int_from_roman_end:w}
% \begin{macro}[aux]{\int_from_roman_clean_up:w}
%   The method here is to iterate through the input, finding the
%   appropriate value for each letter and building up a sum. This is
%   then evaluated by \TeX{}.
%    \begin{macrocode}
\cs_new:Npn \int_from_roman:n #1
  {
    \tl_if_blank:nF {#1}
      {
        \exp_after:wN \int_from_roman_end:w
          \int_value:w \int_eval:w
            \int_from_roman_aux:NN #1 Q \q_stop
      }
  }
\cs_new:Npn \int_from_roman_aux:NN #1#2
  {
    \str_if_eq:nnTF {#1} { Q }
      {#1#2}
      {
        \str_if_eq:nnTF {#2} { Q }
          {
            \int_if_exist:cF { c_int_from_roman_ #1 _int }
              { \int_from_roman_clean_up:w }
            +
            \use:c { c_int_from_roman_ #1 _int }
            #2
          }
          {
            \int_if_exist:cF { c_int_from_roman_ #1 _int }
              { \int_from_roman_clean_up:w }
            \int_if_exist:cF { c_int_from_roman_ #2 _int }
              { \int_from_roman_clean_up:w }
            \int_compare:nNnTF
              { \use:c { c_int_from_roman_ #1 _int } }
              <
              { \use:c { c_int_from_roman_ #2 _int  } }
              {
                + \use:c { c_int_from_roman_ #2 _int }
                - \use:c { c_int_from_roman_ #1 _int }
                \int_from_roman_aux:NN
              }
              {
                + \use:c { c_int_from_roman_ #1 _int }
                \int_from_roman_aux:NN #2
              }
          }
      }
  }
\cs_new:Npn \int_from_roman_end:w #1 Q #2 \q_stop
  { \tl_if_empty:nTF {#2} {#1} {#2} }
\cs_new:Npn \int_from_roman_clean_up:w #1 Q { + 0 Q -1 }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsection{Viewing integer}
%
% \begin{macro}{\int_show:N,\int_show:c}
% \UnitTested
%    \begin{macrocode}
\cs_new_eq:NN \int_show:N \kernel_register_show:N
\cs_new_eq:NN \int_show:c \kernel_register_show:c
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\int_show:n}
% \UnitTested
%    \begin{macrocode}
\cs_new_protected:Npn \int_show:n #1
  { \tex_showthe:D \int_eval:w #1 \int_eval_end: }
%    \end{macrocode}
% \end{macro}
%
% \subsection{Constant integers}
%
% \begin{variable}{\c_minus_one}
%   This is needed early, and so is in \pkg{l3basics}
% \end{variable}
%
% \begin{variable}{\c_zero}
%   Again, one in \pkg{l3basics} for obvious reasons.
% \end{variable}
%
% \begin{variable}{\c_six, \c_seven}
% \begin{variable}{\c_twelve}
% \begin{variable}{\c_sixteen}
%   Once again, in \pkg{l3basics}.
% \end{variable}
% \end{variable}
% \end{variable}
%
% \begin{variable}
%   {
%     \c_one, \c_two, \c_three, \c_four, \c_five, \c_eight, \c_nine, \c_ten,
%     \c_eleven, \c_thirteen, \c_fourteen, \c_fifteen,
%   }
% Low-number values not previously defined.
%    \begin{macrocode}
\int_const:Nn \c_one      {  1 }
\int_const:Nn \c_two      {  2 }
\int_const:Nn \c_three    {  3 }
\int_const:Nn \c_four     {  4 }
\int_const:Nn \c_five     {  5 }
\int_const:Nn \c_eight    {  8 }
\int_const:Nn \c_nine     {  9 }
\int_const:Nn \c_ten      { 10 }
\int_const:Nn \c_eleven   { 11 }
\int_const:Nn \c_thirteen { 13 }
\int_const:Nn \c_fourteen { 14 }
\int_const:Nn \c_fifteen  { 15 }
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\c_thirty_two}
%   One middling value.
%    \begin{macrocode}
\int_const:Nn \c_thirty_two { 32 }
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\c_two_hundred_fifty_five, \c_two_hundred_fifty_six}
%   Two classic mid-range integer constants.
%    \begin{macrocode}
\int_const:Nn \c_two_hundred_fifty_five { 255 }
\int_const:Nn \c_two_hundred_fifty_six  { 256 }
%    \end{macrocode}
%\end{variable}
%
% \begin{variable}
%   {\c_one_hundred, \c_one_thousand, \c_ten_thousand}
%   Simple runs of powers of ten.
%    \begin{macrocode}
\int_const:Nn \c_one_hundred  {   100 }
\int_const:Nn \c_one_thousand {  1000 }
\int_const:Nn \c_ten_thousand { 10000 }
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\c_max_int}
%   The largest number allowed is $2^{31}-1$
%    \begin{macrocode}
\int_const:Nn \c_max_int { 2 147 483 647 }
%    \end{macrocode}
% \end{variable}
%
% \subsection{Scratch integers}
%
% \begin{variable}{\l_tmpa_int, \l_tmpb_int, \l_tmpc_int}
% \begin{variable}{\g_tmpa_int, \g_tmpb_int}
%    We provide three local and two global scratch counters, maybe we
%    need more or less.
%    \begin{macrocode}
\int_new:N \l_tmpa_int
\int_new:N \l_tmpb_int
\int_new:N \l_tmpc_int
\int_new:N \g_tmpa_int
\int_new:N \g_tmpb_int
%    \end{macrocode}
% \end{variable}
% \end{variable}
%
% \subsection{Deprecated functions}
%
% Deprecated on 2011-05-27, for removal by 2011-08-31.
%
% \begin{macro}{\int_convert_from_base_ten:nn}
% \begin{macro}{\int_convert_to_symbols:nnn}
% \begin{macro}{\int_convert_to_base_ten:nn}
% Some simple renames.
%    \begin{macrocode}
%<*deprecated>
\cs_new_eq:NN \int_convert_from_base_ten:nn \int_to_base:nn
\cs_new_eq:NN \int_convert_to_symbols:nnn   \int_to_symbols:nnn
\cs_new_eq:NN \int_convert_to_base_ten:nn   \int_from_base:nn
%</deprecated>
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\int_to_symbol:n}
% \begin{macro}[aux]{\int_to_symbol_math:n}
% \begin{macro}[aux]{\int_to_symbol_text:n}
% \UnitTested
%   This is rather too tied to \LaTeXe{}.
%    \begin{macrocode}
%<*deprecated>
\cs_new_nopar:Npn \int_to_symbol:n
  {
    \scan_align_safe_stop:
    \mode_if_math:TF
      { \int_to_symbol_math:n }
      { \int_to_symbol_text:n }
  }
\cs_new:Npn \int_to_symbol_math:n #1
  {
    \int_to_symbols:nnn {#1} { 9 }
      {
        { 1 } {                 * }
        { 2 } {           \dagger }
        { 3 } {          \ddagger }
        { 4 } {      \mathsection }
        { 5 } {    \mathparagraph }
        { 6 } {                \| }
        { 7 } {                ** }
        { 8 } {   \dagger \dagger }
        { 9 } { \ddagger \ddagger }
      }
  }
\cs_new:Npn \int_to_symbol_text:n #1
  {
    \int_to_symbols:nnn {#1} { 9 }
      {
        { 1 } {                       \textasteriskcentered }
        { 2 } {                                 \textdagger }
        { 3 } {                              \textdaggerdbl }
        { 4 } {                                \textsection }
        { 5 } {                              \textparagraph }
        { 6 } {                                 \textbardbl }
        { 7 } { \textasteriskcentered \textasteriskcentered }
        { 8 } {                     \textdagger \textdagger }
        { 9 } {               \textdaggerdbl \textdaggerdbl }
      }
  }
%</deprecated>
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%    \begin{macrocode}
%</initex|package>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex
