% \iffalse
%% File: l3int.dtx Copyright (C) 1990-2008 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 ``expl3 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/cgi-bin/cvsweb.cgi/
%%
%% 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 LaTeX Project Team.
%%
%% -----------------------------------------------------------------------
%
%<*driver|package>
\RequirePackage{l3names}
%</driver|package>
%\fi
\GetIdInfo$Id: l3int.dtx 738 2008-08-01 13:21:42Z morten $
          {L3 Experimental Integer module}
%\iffalse
%<*driver>
%\fi
\ProvidesFile{\filename.\filenameext}
  [\filedate\space v\fileversion\space\filedescription]
%\iffalse
\documentclass{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
%</driver>
% \fi
%
%
% \title{The \textsf{l3int} package\thanks{This file
%         has version number \fileversion, last
%         revised \filedate.}\\
% Counters}
% \author{\Team}
% \date{\filedate}
% \maketitle
%
% \section{Integers}
%
% \LaTeX3 maintains two type of integer registers for internal use.
% One (associated with the name "num") for low level uses in the
% allocation mechanism using macros only and "int": the one described
% here.
%
% The "int" type uses the built-in counter registers of \TeX{} and is
% therefore relatively fast compared to the "num" type and should be
% preferred in all cases as there is little chance we should ever run
% out of registers when being based on at least \eTeX.
%
% \subsection{Functions}
%
% \begin{function}{%
%                  \int_new:N |
%                  \int_new:c |
%                  \int_new_l:N |
% }
% \begin{syntax}
%    "\int_new:N"   <int>
% \end{syntax}
% Globally defines <int> to be a new variable of type "int" although
% you can still choose if it should be a an "\l_" or "\g_" type.
% There is no way to define constant counters with these functions.
% The function  "\int_new_l:N" defines <int> locally only.
% \begin{texnote}
% "\int_new:N" is the equivalent to plain \TeX{}'s \tn{newcount}.
% However, the internal register allocation is done differently.
% \end{texnote}
% \end{function}
%
% \begin{function}{%
%                  \int_incr:N |
%                  \int_incr:c |
%                  \int_gincr:N |
%                  \int_gincr:c |
% }
% \begin{syntax}
%   "\int_incr:N"   <int>
% \end{syntax}
% Increments <int> by one. For global variables the global versions
% should be used.
% \end{function}
%
% \begin{function}{%
%                  \int_decr:N |
%                  \int_decr:c |
%                  \int_gdecr:N |
%                  \int_gdecr:c |
% }
% \begin{syntax}
%   "\int_decr:N"   <int>
% \end{syntax}
% Decrements <int> by one. For global variables the global versions
% should be used.
% \end{function}
%
% \begin{function}{%
%                  \int_set:Nn |
%                  \int_set:cn |
%                  \int_gset:Nn |
%                  \int_gset:cn |
% }
% \begin{syntax}
%   "\int_set:Nn"   <int> "{" <integer expr> "}"
% \end{syntax}
% These functions will set the <int> register to the <integer expr>
% value. This value can contain simple calc-like expressions as
% provided by \eTeX.
% \end{function}
%
%
% \begin{function}{%
%                  \int_zero:N |
%                  \int_zero:c |
%                  \int_gzero:N |
%                  \int_gzero:c |
% }
% \begin{syntax}
%   "\int_zero:N"   <int>
% \end{syntax}
% These functions sets the <int> register to zero either locally
% or globally.
% \end{function}
%
%
% \begin{function}{%
%                  \int_add:Nn |
%                  \int_add:cn |
%                  \int_gadd:Nn |
%                  \int_gadd:cn |
% }
% \begin{syntax}
%   "\int_add:Nn"   <int> "{" <integer expr> "}"
% \end{syntax}
% These functions will add to the <int> register the value <integer
% expr>.  If the second argument is a <int> register too, the
% surrounding braces can be left out.
% \end{function}
%
% \begin{function}{%
%                  \int_sub:Nn |
%                  \int_sub:cn |
%                  \int_gsub:Nn |
%                  \int_gsub:cn |
% }
% \begin{syntax}
%   "\int_gsub:Nn"   <int> "{" <integer expr> "}"
% \end{syntax}
% These functions will subtract from the <int> register the value
% <integer expr>.  If the second argument is a <int> register too, the
% surrounding braces can be left out.
% \end{function}
%
% \begin{function}{%
%                  \int_use:N |
%                  \int_use:c |
% }
% \begin{syntax}
%   "\int_use:N"   <int>
% \end{syntax}
% This function returns the integer value kept in <int> in a way
% suitable for further processing.
% \begin{texnote}
% The function "\int_use:N" could be implemented directly as the \TeX{}
% primitive "\tex_the:D" which is also responsible to produce the values for
% other internal quantities.  We have chosen to use individual functions
% for counters, dimensions etc.\ to allow checks and to make the code
% more self-explaining.
% \end{texnote}
% \end{function}
%
% \subsection{Formatting a counter value}
%
% \begin{function}{
%                   \int_to_arabic:n |
%                   \int_to_alph:n |
%                   \int_to_Alph:n |
%                   \int_to_roman:n |
%                   \int_to_Roman:n |
%                   \int_to_symbol:n |
% }
% \begin{syntax}
%   "\int_to_alph:n" "{" <integer> "}"
%   "\int_to_alph:n"  <int>
% \end{syntax}
% If some <integer> or the the current value of a <int> should be
% displayed or typeset in a special ways (e.g., as uppercase roman
% numerals) these function can be used.  We need braces if the
% argument is a simple <integer>, they can be omitted in case of a
% <int>. By default the letters produced by "\int_to_roman:n" and
% "\int_to_Roman:n" have catcode~11.
%
% All functions are fully expandable and will therefore produce the
% correct output when used inside of deferred writes, etc. In case the
% number in an |alph| or |Alph| function is greater than the default
% base number (26) it follows a simple conversion rule so that 27 is
% turned into |aa|, 50 into |ax| and so on and so forth. These two
% functions can be modified quite easily to take a different base
% number and conversion rule so that other languages can be supported.
% \begin{texnote}
% These are more or less the internal \LaTeX2 functions \tn{@arabic},
% \tn{@alph}, \tn{Alph}, \tn{@roman}, \tn{@Roman}, and \tn{@fnsymbol}
% except that "\int_to_symbol:n" is also allowed outside math mode.
% \end{texnote}
% \end{function}
%
% \subsubsection{Internal functions}
%
% \begin{function}{\int_to_roman:w}
% \begin{syntax}
%   "\int_to_roman:w" <integer> <space> \textit{or} <non-expandable token>
% \end{syntax}
% Converts <integer> to it lowercase roman representation. Note that
% it produces a string of letters with catcode 12.
% \begin{texnote}
%   This is the \TeX{} primitive \tn{romannumeral} renamed.
% \end{texnote}
% \end{function}
% \begin{function}{
%                   \int_roman_lcuc_mapping:Nnn |
%                   \int_to_roman_lcuc:NN |
% }
% \begin{syntax}
%   "\int_roman_lcuc_mapping:Nnn"  <roman_char> "{"<licr>"}" "{"<LICR>"}"
%   "\int_to_roman_lcuc:NN"  <roman_char> <char>
% \end{syntax}
% "\int_roman_lcuc_mapping:Nnn" specifies how the roman
% numeral <roman\_ char> (i, v, x, l, c, d, or m) should be
% interpreted when converting the number. <licr> is the lower case and
% <LICR> is the uppercase mapping. "\int_to_roman_lcuc:NN" is a
% recursive function converting the roman numerals.
% \end{function}
%
%
% \begin{function}{
%                   \int_convert_number_with_rule:nnN |
%                   \int_alph_default_conversion_rule:n |
%                   \int_Alph_default_conversion_rule:n |
%                   \int_symbol_math_conversion_rule:n |
%                   \int_symbol_text_conversion_rule:n |
% }
% \begin{syntax}
%   "\int_convert_number_with_rule:nnN" "{"<int1>"}" "{"<int2>"}" <function>
%   "\int_alph_default_conversion_rule:n"  "{"<int>"}"
% \end{syntax}
% "\int_convert_number_with_rule:nnN" converts <int1> into letters,
% symbols, whatever as defined by <function>. <int2> denotes the base
% number for the conversion.
% \end{function}
%
%
%
%
%
%
% \subsection{Variable and constants}
%
% \begin{variable}{%
%                  \c_max_int |
% }
% Constant that denote the maximum value which can be stored in an
% <int> register.
% \end{variable}
%
%
% \begin{variable}{%
%                  \l_tmpa_int |
%                  \l_tmpb_int |
%                  \l_tmpc_int |
%                  \g_tmpa_int |
%                  \g_tmpb_int |
% }
% Scratch register for immediate use. They are not used by conditionals
% or predicate functions.
% \end{variable}
%
%
% \subsection{Testing and evaluating integer expressions}
%
% \begin{function}{%
%                  \int_eval:n |
%                  \int_div_truncate:nn |
%                  \int_div_round:nn |
%                  \int_mod:nn |
% }
% \begin{syntax}
%   "\int_eval:n"   "{"<int~expr>"}" \\
%   "\int_div_truncate:n"   "{"<int~expr>"}" "{"<int~expr>"}" \\
%   "\int_mod:nn"   "{"<int~expr>"}" "{"<int~expr>"}"
% \end{syntax}
% Evaluates the value of a integer expression so that
% "\int_eval:n {3*5/4}" puts "4" back into the input stream. Note that
% the results of divisions are rounded by the primitive operations. If
% you want the result of a division to be truncated use
% "\int_div_truncate:nn". "\int_div_round:nn" is added for
% completeness. "\int_mod:nn" returns the remainder of a division. All
% of these functions are expandable.
% \begin{texnote}
% "\int_eval:n" is the \eTeX primitive \tn{numexpr} turned into a function
% taking an argument.
% \end{texnote}
% \end{function}
%
% \begin{function}{%
%                  \int_compare:nNnTF |
%                  \int_compare:nNnT |
%                  \int_compare:nNnF |
% }
% \begin{syntax}
%   "\int_compare:nNnTF"   "{"<int~expr>"}" <rel> "{"<int~expr>"}"
%                          "{"<true>"}" "{"<false>"}"
% \end{syntax}
% These functions test two integer expressions against each other. They
% are both evaluated by "\int_eval:n". Note that if both expressions
% are normal integer variables as in
% \begin{quote}
% "\int_compare:nNnTF \l_temp_int < \c_zero {negative}{non-negative}"
% \end{quote}
% you can safely omit the braces.
% \begin{texnote}
% This is the \TeX{} primitive \tn{ifnum} turned into a function.
% \end{texnote}
% \end{function}
%
% \begin{function}{%
%                  \int_compare_p:nNn |
% }
% \begin{syntax}
%   "\int_compare_p:nNn"   "{"<int~expr>"}" <rel> "{"<int~expr>"}"
% \end{syntax}
% A predicate version of the above mentioned functions.
% \end{function}
%
% \begin{function}{%
%                  \int_max_of:nn |
%                  \int_min_of:nn |
% }
% \begin{syntax}
%   "\int_max_of:nn"   "{"<int~expr>"}" "{"<int~expr>"}"
% \end{syntax}
% Return the largest or smallest of two integer expressions.
% \end{function}
%
% \begin{function}{%
%                  \int_abs:n |
% }
% \begin{syntax}
%   "\int_abs:n"   "{"<int~expr>"}"
% \end{syntax}
% Return the numerical value of an integer expression.
% \end{function}
%
% \begin{function}{%
%                  \int_if_odd:nTF |
%                  \int_if_odd_p:n |
% }
% \begin{syntax}
%   "\int_if_odd:nTF"   "{"<int~expr>"}" "{"<true>"}" "{"<false>"}"
% \end{syntax}
% These functions test if an integer expression is even or odd. We
% also define a predicate version of it.
% \begin{texnote}
% This is the \TeX{} primitive \tn{ifodd} turned into a function.
% \end{texnote}
% \end{function}
%
% \begin{function}{%
%                  \int_whiledo:nNnT |
%                  \int_whiledo:nNnF |
%                  \int_dowhile:nNnT |
%                  \int_dowhile:nNnF |
% }
% \begin{syntax}
%   "\int_whiledo:nNnT"   <int expr> <rel> <int~expr> "{"<true>"}"
% \end{syntax}
%  "\int_whiledo:nNnT" tests the integer expressions and if true performs
%  the body "T" until the test fails. "\int_dowhile:nNnT" is similar
%  but executes the body first and then performs the check, thus
%  ensuring that the body is executed at least once. The "F" versions
%  are similar but continue the loop as long as the test is false. They
%  could be omitted as it is just a matter of switching the arguments
%  in the test.
% \end{function}
%

% \subsection{Conversion}
%
% \begin{function}{%
%                  \int_convert_from_base_ten:nn |
% }
% \begin{syntax}
%   "\int_convert_from_base_ten:nn" "{"<number>"}""{"<base>"}"
% \end{syntax}
% Converts the base~10 number <number> into its equivalent
% representation written in base~<base>. Expandable.
% \end{function}
%
%
% \begin{function}{%
%                  \int_convert_to_base_ten:nn |
% }
% \begin{syntax}
%   "\int_convert_to_base_ten:nn" "{"<number>"}""{"<base>"}"
% \end{syntax}
% Converts the base~<base> number <number> into its equivalent
% representation written in base~10. <number> can consist of digits
% and ascii letters. Expandable.
% \end{function}
%
%
% \StopEventually{}
% \subsection{The Implementation}
%
%
%    We start by ensuring that the required packages are loaded.
%    \begin{macrocode}
%<package>\ProvidesExplPackage
%<package>  {\filename}{\filedate}{\fileversion}{\filedescription}
%<package&!check>\RequirePackage{l3num}
%<package&check>\RequirePackage{l3chk}
%<*initex|package>
%    \end{macrocode}
%
% \begin{macro}{\int_to_roman:w}
% \begin{macro}{\int_to_number:w}
% \begin{macro}{\int_advance:w}
% A new name for the primitives.
%    \begin{macrocode}
\let_new:NN \int_to_roman:w \tex_romannumeral:D
\let_new:NN \int_to_number:w \tex_number:D
\let_new:NN \int_advance:w \tex_advance:D
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% Functions that support \LaTeX's user accessible counters should be
% added here, too. But first the internal counters.
%
% \begin{macro}{\int_incr:N}
% \begin{macro}{\int_decr:N}
% \begin{macro}{\int_gincr:N}
% \begin{macro}{\int_gdecr:N}
% \begin{macro}{\int_incr:c}
% \begin{macro}{\int_decr:c}
% \begin{macro}{\int_gincr:c}
% \begin{macro}{\int_gdecr:c}
%    Incrementing and decrementing of integer registers is done with
%    the following functions.
%    \begin{macrocode}
\def_new:Npn \int_incr:N #1{\int_advance:w#1\c_one
%<*check>
        \chk_local_or_pref_global:N #1
%</check>
}
\def_new:Npn \int_decr:N #1{\int_advance:w#1\c_minus_one
%<*check>
        \chk_local_or_pref_global:N #1
%</check>
}
\def_new:Npn \int_gincr:N {
%    \end{macrocode}
%    We make sure that a local variable is not updated globally by
%    changing the internal test (i.e.\ |\chk_local_or_pref_global:N|) before
%    making the assignment. This is done by |\pref_global_chk:| which also
%    issues the necessary |\pref_global:D|. This is not very efficient, but
%    this code will be only included for debugging purposes. Using
%    |\pref_global:D| in front of the local function is better in the
%    production versions.
%    \begin{macrocode}
%<*check>
   \pref_global_chk:
%</check>
%<-check> \pref_global:D
   \int_incr:N}
\def_new:Npn \int_gdecr:N {
%<*check>
   \pref_global_chk:
%</check>
%<-check> \pref_global:D
   \int_decr:N}
%    \end{macrocode}
%    With the |\int_add:Nn| functions we can shorten the above code.
%    If this makes it too slow \ldots
%    \begin{macrocode}
\def:Npn \int_incr:N #1{\int_add:Nn#1\c_one}
\def:Npn \int_decr:N #1{\int_add:Nn#1\c_minus_one}
\def:Npn \int_gincr:N #1{\int_gadd:Nn#1\c_one}
\def:Npn \int_gdecr:N #1{\int_gadd:Nn#1\c_minus_one}
\def:Npn \int_incr:c {\exp_args:Nc\int_incr:N}
\def:Npn \int_decr:c {\exp_args:Nc\int_decr:N}
\def:Npn \int_gincr:c {\exp_args:Nc\int_gincr:N}
\def:Npn \int_gdecr:c {\exp_args:Nc\int_gdecr:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\int_new:N}
% \begin{macro}{\int_new_l:N}
% \begin{macro}{\int_new:c}
%    Allocation of a new internal counter is already done above. Here we define
%    the next likely variant.
%    \begin{macrocode}
%<*initex>
\alloc_setup_type:nnn {int} \c_eleven \c_max_register_num
\def_new:Npn \int_new:N   #1 {\alloc_reg:NnNN g {int} \tex_countdef:D#1}
\def_new:Npn \int_new_l:N #1 {\alloc_reg:NnNN l {int} \tex_countdef:D#1}
%</initex>
%<package>\let:NN \int_new:N \newcount% allocation better nick the LaTeX one...
\def_new:Npn \int_new:c {\exp_args:Nc \int_new:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\int_set:Nn}
% \begin{macro}{\int_set:cn}
% \begin{macro}{\int_gset:Nn}
% \begin{macro}{\int_gset:cn}
%    Setting counters is again something that I would like to make
%    uniform at the moment to get a better overview.
%    \begin{macrocode}
\def_new:Npn \int_set:Nn #1#2{#1 \int_eval:w #2\int_eval_end:
%<*check>
\chk_local_or_pref_global:N #1
%</check>
}
\def_new:Npn \int_gset:Nn {
%<*check>
   \pref_global_chk:
%</check>
%<-check> \pref_global:D
   \int_set:Nn }
\def_new:Npn \int_set:cn {\exp_args:Nc \int_set:Nn }
\def_new:Npn \int_gset:cn {\exp_args:Nc \int_gset:Nn }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%  \begin{macro}{\int_zero:N}
%  \begin{macro}{\int_zero:c}
%  \begin{macro}{\int_gzero:N}
%  \begin{macro}{\int_gzero:c}
%  Functions that reset an \m{int} register to zero.
%    \begin{macrocode}
\def_new:Npn \int_zero:N  #1 {#1=\c_zero}
\def_new:Npn \int_zero:c  #1 {\exp_args:Nc \int_zero:N}
\def_new:Npn \int_gzero:N #1 {\pref_global:D #1=\c_zero}
\def_new:Npn \int_gzero:c {\exp_args:Nc \int_gzero:N}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
% \begin{macro}{\int_add:Nn}
% \begin{macro}{\int_add:cn}
% \begin{macro}{\int_gadd:Nn}
% \begin{macro}{\int_gadd:cn}
% \begin{macro}{\int_sub:Nn}
% \begin{macro}{\int_sub:cn}
% \begin{macro}{\int_gsub:Nn}
% \begin{macro}{\int_gsub:cn}
%    Adding and substracting to and from a counter \ldots
%    We should think of using these functions
%    \begin{macrocode}
\def_new:Npn \int_add:Nn #1#2{
%    \end{macrocode}
%    We need to say |by| in case the first argument is a register
%    accessed by its number, e.g., |\count23|. Not that it should
%    ever happen but\dots
%    \begin{macrocode}
    \int_advance:w #1 by \int_eval:w #2\int_eval_end:
%<*check>
    \chk_local_or_pref_global:N #1
%</check>
}
\def_new:Npn\int_add:cn{\exp_args:Nc\int_add:Nn}
\def_new:Npn \int_sub:Nn #1#2{
    \int_advance:w #1-\int_eval:w #2\int_eval_end:
%<*check>
\chk_local_or_pref_global:N #1
%</check>
}
\def_new:Npn \int_gadd:Nn {
%<*check>
   \pref_global_chk:
%</check>
%<-check> \pref_global:D
   \int_add:Nn }
\def_new:Npn \int_gsub:Nn {
%<*check>
   \pref_global_chk:
%</check>
%<-check> \pref_global:D
   \int_sub:Nn }
\def_new:Npn \int_gadd:cn{\exp_args:Nc\int_gadd:Nn}
\def_new:Npn \int_sub:cn{\exp_args:Nc\int_sub:Nn}
\def_new:Npn \int_gsub:cn{\exp_args:Nc\int_gsub:Nn}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%  \begin{macro}{\int_use:N}
%  \begin{macro}{\int_use:c}
%    Here is how counters are accessed:
%    \begin{macrocode}
\let_new:NN \int_use:N \tex_the:D
\def_new:Npn \int_use:c #1{\int_use:N \cs:w#1\cs_end:}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%
%
%
%  \begin{macro}{\int_to_arabic:n}
%  Nothing exciting here.
%    \begin{macrocode}
\def_new:Npn \int_to_arabic:n #1{\int_to_number:w \int_eval:n{#1}}
%    \end{macrocode}
%  \end{macro}
%
%
%
%  \begin{macro}{\int_roman_lcuc_mapping:Nnn}
%  Using \TeX's built-in feature for producing roman numerals has some
%  surprising features. One is the the characters resulting from
%  |\int_to_roman:w| have category code~12 so they may fail in
%  certain comparison tests. Therefore we use a mapping from the
%  character \TeX{} produces to the character we actually want which
%  will give us letters with category code~11.%
%    \begin{macrocode}
\def_new:Npn \int_roman_lcuc_mapping:Nnn #1#2#3{
  \def:cpn {int_to_lc_roman_#1:}{#2}
  \def:cpn {int_to_uc_roman_#1:}{#3}
}
%    \end{macrocode}
%  \end{macro}
%  Here are the default mappings. I haven't found any examples of say
%  Turkish doing the mapping |i \i I| but at least there is a
%  possibility for it if needed. Note: I have now asked a Turkish
%  person and he tells me they do the |i I| mapping.
%    \begin{macrocode}
\int_roman_lcuc_mapping:Nnn i i I
\int_roman_lcuc_mapping:Nnn v v V
\int_roman_lcuc_mapping:Nnn x x X
\int_roman_lcuc_mapping:Nnn l l L
\int_roman_lcuc_mapping:Nnn c c C
\int_roman_lcuc_mapping:Nnn d d D
\int_roman_lcuc_mapping:Nnn m m M
%    \end{macrocode}
%  For the delimiter we cheat and let it gobble its arguments instead.
%    \begin{macrocode}
\int_roman_lcuc_mapping:Nnn Q \use_none:nn \use_none:nn
%    \end{macrocode}
%
%  \begin{macro}{\int_to_roman:n}
%  \begin{macro}{\int_to_Roman:n}
%  \begin{macro}{\int_to_roman_lcuc:NN}
%  The commands for producing the lower and upper case roman numerals
%  run a loop on one character at a time and also carries some
%  information for upper or lower case with it. We put it through
%  |\int_eval:n| first which is safer and more flexible.
%    \begin{macrocode}
\def_new:Npn \int_to_roman:n #1 {
  \exp_after:NN \int_to_roman_lcuc:NN \exp_after:NN l
    \int_to_roman:w \int_eval:n {#1} Q
}
\def_new:Npn \int_to_Roman:n #1 {
  \exp_after:NN \int_to_roman_lcuc:NN \exp_after:NN u
    \int_to_roman:w \int_eval:n {#1} Q
}
\def_new:Npn \int_to_roman_lcuc:NN #1#2{
  \cs_use:c {int_to_#1c_roman_#2:}
  \int_to_roman_lcuc:NN #1
}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%
%
%  \begin{macro}{\int_convert_number_with_rule:nnN}
%  This is our major workhorse for conversions. |#1| is the number we
%  want converted, |#2| is the base number, and |#3| is the function
%  converting the number. This function expects to receive a
%  non-negative integer and as such is ideal for something using
%  |\if_case:w| internally.
%
%  The basic example is this: We want to convert the number 50 (|#1|)
%  into an alphabetic equivalent |ax|. For the English language our
%  list contains 26 elements so this is our argument |#2| while the
%  function |#3| just turns |1| into |a|, |2| into |b|, etc. Hence our
%  goal is to turn 50 into the sequence |#3{1}#1{24}| so what we do is
%  to first divide 50 by 26 and truncating the result returning 1.
%  Then before we execute this we call the function again but this time
%  on the result of the remainder of the division. This goes on until
%  the remainder is less than or equal to the base number where we just
%  call the function |#3| directly on the number.
%
%  We do a little pre-expansion of the arguments below as they
%  otherwise have a tendency to grow quite large.
%    \begin{macrocode}
\def:Npn \int_convert_number_with_rule:nnN #1#2#3{
  \int_compare:nNnTF {#1}>{#2}
  {
    \exp_args:No \int_convert_number_with_rule:nnN
      { \int_use:N\int_div_truncate:nn {#1-1}{#2} }{#2}
      #3
%    \end{macrocode}
%  Note that we have to nudge our modulus function so it won't
%  return~$0$ as that wouldn't work with |\if_case:w| when that
%  expects a positive number to produce a letter.
%    \begin{macrocode}
    \exp_args:No #3 { \int_use:N\int_eval:n{1+\int_mod:nn {#1-1}{#2}} }
  }
  { \exp_args:No #3{ \int_use:N\int_eval:n{#1} } }
}
%    \end{macrocode}
%    As can be seen it is even simpler to convert to number systems
%    that contain 0, since then we don't have to add or subtract 1
%    here and there.
%  \end{macro}
%  
%  \begin{macro}{\int_alph_default_conversion_rule:n}
%  \begin{macro}{\int_Alph_default_conversion_rule:n}
%  Now we just set up a default conversion rule. Ideally every language
%  should have one such rule, as say in Danish there are 29 letters in
%  the alphabet.
%    \begin{macrocode}
\def_new:Npn \int_alph_default_conversion_rule:n #1{
  \if_case:w #1
    \or: 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
  \fi:
}
\def_new:Npn \int_Alph_default_conversion_rule:n #1{
  \if_case:w #1
    \or: 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
  \fi:
}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%
%  \begin{macro}{\int_to_alph:n}
%  \begin{macro}{\int_to_Alph:n}
%  The actual functions are just instances of the generic function. The
%  second argument of |\int_convert_number_with_rule:nnN| should of
%  course match the number of |\or:|s in the conversion rule.
%    \begin{macrocode}
\def_new:Npn \int_to_alph:n #1{
  \int_convert_number_with_rule:nnN {#1}{26}
    \int_alph_default_conversion_rule:n
}
\def_new:Npn \int_to_Alph:n #1{
  \int_convert_number_with_rule:nnN {#1}{26}
    \int_Alph_default_conversion_rule:n
}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\int_to_symbol:n}
%  Turning a number into a symbol is also easy enough.
%    \begin{macrocode}
\def_new:Npn \int_to_symbol:n #1{
  \mode_if_math:TF
  {
    \int_convert_number_with_rule:nnN {#1}{9}
      \int_symbol_math_conversion_rule:n
  }
  {
    \int_convert_number_with_rule:nnN {#1}{9}
      \int_symbol_text_conversion_rule:n
  }
}
%    \end{macrocode}
%  \end{macro}
%  \begin{macro}{\int_symbol_math_conversion_rule:n}
%  \begin{macro}{\int_symbol_text_conversion_rule:n}
%  Nothing spectacular here.
%    \begin{macrocode}
\def_new:Npn \int_symbol_math_conversion_rule:n #1 {
  \if_case:w #1
    \or: *
    \or: \dagger
    \or: \ddagger
    \or: \mathsection
    \or: \mathparagraph
    \or: \|
    \or: **
    \or: \dagger\dagger
    \or: \ddagger\ddagger
  \fi:
}
\def_new:Npn \int_symbol_text_conversion_rule:n #1 {
  \if_case:w #1
    \or: \textasteriskcentered
    \or: \textdagger
    \or: \textdaggerdbl
    \or: \textsection
    \or: \textparagraph
    \or: \textbardbl
    \or: \textasteriskcentered\textasteriskcentered
    \or: \textdagger\textdagger
    \or: \textdaggerdbl\textdaggerdbl
  \fi:
}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
% \begin{macro}{\l_tmpa_int}
% \begin{macro}{\l_tmpb_int}
% \begin{macro}{\l_tmpc_int}
% \begin{macro}{\g_tmpa_int}
% \begin{macro}{\g_tmpb_int}
% \begin{macro}{\l_loop_int}
%    We provide four 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
\int_new:N \l_loop_int  % a variable for use in loops (whilenum etc)
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\int_eval:n}
% \begin{macro}{\int_eval:w}
% \begin{macro}{\int_eval_end:}
% Evaluating a calc expression using normal operators. Many of these
% are exactly the same as the ones in the \textsf{num} module so we
% just use them.
%    \begin{macrocode}
\let_new:NN \int_eval:n    \num_eval:n
\let_new:NN \int_eval:w    \num_eval:w
\let_new:NN \int_eval_end: \num_eval_end:
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\c_max_int}
%    The largest number allowed is $2^{31}-1$
%    \begin{macrocode}
\const_new:Nn \c_max_int {2147483647}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\int_pre_eval_one_arg:Nn}
% \begin{macro}{\int_pre_eval_two_args:Nnn}
%   These might be handy when handing down values to other
%   functions. All they do is evaluate the number in advance.
%    \begin{macrocode}
\def:Npn \int_pre_eval_one_arg:Nnn #1#2{\exp_args:No#1{\int_eval:w#2}}
\def:Npn \int_pre_eval_two_args:Nnn #1#2#3{
  \exp_args:Noo#1{\int_use:N\int_eval:w#2}{\int_use:N\int_eval:w#3}
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\int_div_truncate:nn}
% \begin{macro}{\int_div_round:nn}
% \begin{macro}{\int_mod:nn}
% \begin{macro}{\int_div_truncate_raw:nn}
% \begin{macro}{\int_div_round_raw:nn}
% \begin{macro}{\int_mod_raw:nn}
% As "\num_eval:w" rounds the result of a division we also
% provide a version that truncates the result.
%    \begin{macrocode}
\def_new:Npn \int_div_truncate:nn {
  \int_pre_eval_two_args:Nnn\int_div_truncate_raw:nn
}
%    \end{macrocode}
%    Initial version didn't work correctly with e\TeX's implementation.    
%    \begin{macrocode}
%\def_new:Npn \int_div_truncate_raw:nn #1#2 {
%  \int_eval:n{ (2*#1 - #2) / (2* #2) }
%}
%    \end{macrocode}
%    New version by Heiko:
%    \begin{macrocode}
\def_new:Npn \int_div_truncate_raw:nn #1#2 {
  \int_eval:w
    \if_num:w \int_eval:w#1 = \c_zero
      0
    \else:
      (#1
      \if_num:w  \int_eval:w #1 < \c_zero
        \if_num:w \int_eval:w#2 < \c_zero
          -( #2 +
        \else:   
          +( #2 -
        \fi:
      \else:
        \if_num:w \int_eval:w #2 < \c_zero
          +( #2 + 
        \else:   
          -( #2 -
        \fi:
      \fi:  
      1)/2)
    \fi:
    /(#2)
  \int_eval_end:  
}
%    \end{macrocode}
% For the sake of completeness:
%    \begin{macrocode}
\def_new:Npn \int_div_round:nn {
  \int_pre_eval_two_args:Nnn\int_div_round_raw:nn
}
\def_new:Npn \int_div_round_raw:nn #1#2 {\int_eval:n{#1/#2}}
%    \end{macrocode}
% Finally there's the modulus operation.
%    \begin{macrocode}
\def_new:Npn \int_mod:nn {\int_pre_eval_two_args:Nnn\int_mod_raw:nn}
\def_new:Npn \int_mod_raw:nn #1#2 {
  \int_eval:n{ #1 - \int_div_truncate_raw:nn {#1}{#2} * #2 }
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\int_compare:nNnTF}
% \begin{macro}{\int_compare:nNnT}
% \begin{macro}{\int_compare:nNnF}
% Simple comparison tests.
%    \begin{macrocode}
\let_new:NN \int_compare:nNnTF \num_compare:nNnTF
\let_new:NN \int_compare:nNnT \num_compare:nNnT
\let_new:NN \int_compare:nNnF \num_compare:nNnF
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\int_max_of:nn}
% \begin{macro}{\int_min_of:nn}
% \begin{macro}{\int_abs:n}
% Simple comparison tests.
%    \begin{macrocode}
\let_new:NN \int_max_of:nn \num_max_of:nn
\let_new:NN \int_min_of:nn \num_min_of:nn
\let_new:NN \int_abs:nn \num_abs:nn
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\int_compare_p:nNn}
% A predicate function.
%    \begin{macrocode}
\let_new:NN \int_compare_p:nNn \num_compare_p:nNn
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\int_if_odd_p:n}
% \begin{macro}{\int_if_odd:nTF}
% \begin{macro}{\int_if_odd:nT}
% \begin{macro}{\int_if_odd:nF}
% A predicate function.
%    \begin{macrocode}
\def_new:Npn \int_if_odd_p:n #1 {
  \if_num_odd:w \int_eval:n{#1}
    \c_true
  \else:
    \c_false
  \fi:
}
\def_test_function_new:npn {int_if_odd:n}#1{\if_num_odd:w \int_eval:n{#1}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\int_whiledo:nNnT}
% \begin{macro}{\int_whiledo:nNnF}
% \begin{macro}{\int_dowhile:nNnT}
% \begin{macro}{\int_dowhile:nNnF}
%  These are quite easy given the above functions. The "while" versions
%  test first and then execute the body. The "dowhile" does it the
%  other way round. The have to be defined as ``long'' since the "T" argument
%  might contain "\par" tokens.
%    \begin{macrocode}
\def_long_new:Npn \int_whiledo:nNnT #1#2#3#4{
  \int_compare:nNnT {#1}#2{#3}{#4 \int_whiledo:nNnT {#1}#2{#3}{#4}}
}
\def_long_new:Npn \int_whiledo:nNnF #1#2#3#4{
  \int_compare:nNnF {#1}#2{#3}{#4 \int_whiledo:nNnF {#1}#2{#3}{#4}}
}
\def_long_new:Npn \int_dowhile:nNnT #1#2#3#4{
  #4 \int_compare:nNnT {#1}#2{#3}{\int_dowhile:nNnT {#1}#2{#3}{#4}}
}
\def_long_new:Npn \int_dowhile:nNnF #1#2#3#4{
  #4 \int_compare:nNnF {#1}#2{#3}{\int_dowhile:nNnF {#1}#2{#3}{#4}}
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \subsubsection{Scanning and conversion}
%
%
% Conversion between different numbering schemes requires meticulous
% work. A number can be preceeded by any number of |+| and/or |-|. We
% define a generic function which will return the sign and/or the
% remainder.
%
% \begin{macro}{\int_get_sign_and_digits:n}
% \begin{macro}{\int_get_sign:n}
% \begin{macro}{\int_get_digits:n}
% \begin{macro}{\int_get_sign_and_digits_aux:nNNN}
% \begin{macro}{\int_get_sign_and_digits_aux:oNNN}
% A number may be preceeded by any number of |+|s and |-|s. Start out
% by assuming we have a positive number.
%    \begin{macrocode}
\def_new:Npn \int_get_sign_and_digits:n #1{
  \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_true \c_true
}
\def_new:Npn \int_get_sign:n #1{
  \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_true \c_false
}
\def_new:Npn \int_get_digits:n #1{
  \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_false \c_true
}
%    \end{macrocode}
% Now check the first character in the string. Only a |-| can change
% if a number is positive or negative, hence we reverse the boolean
% governing this. Then gobble the |-| and start over.
%    \begin{macrocode}
\def_new:Npn \int_get_sign_and_digits_aux:nNNN #1#2#3#4{
  \tlist_if_head_eq_charcode:fNTF {#1} - 
  {
    \bool_if:NTF #2
    { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_false #3#4 }
    { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_true  #3#4 }
  }
%    \end{macrocode}
% The other cases are much simpler since we either just have to gobble
% the |+| or exit immediately and insert the correct sign.
%    \begin{macrocode}
  {
    \tlist_if_head_eq_charcode:fNTF {#1} +
    { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} #2#3#4}
    {
%    \end{macrocode}
% The boolean |#3| is for printing the sign while |#4| is for printing
% the digits.
%    \begin{macrocode}
      \bool_double_if:NNnnnn #3#4
      { \bool_if:NF #2 - #1 }
      { \bool_if:NF #2 -    }
      { #1 }  {  }
    }
  }
}
\def_new:Npn \int_get_sign_and_digits_aux:oNNN{
  \exp_args:No\int_get_sign_and_digits_aux:nNNN
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\int_convert_from_base_ten:nn}
% \begin{macro}{\int_convert_from_base_ten_aux:nnn}
% \begin{macro}{\int_convert_from_base_ten_aux:non}
% \begin{macro}{\int_convert_from_base_ten_aux:fon}
%   |#1| is the base 10 number to be converted to base |#2|. We split
%   off the sign first, print if if there and then convert only the
%   number. Since this is supposedly a base~10 number we can let \TeX\
%   do the reading of |+| and |-|.
%    \begin{macrocode}
\def:Npn \int_convert_from_base_ten:nn#1#2{
  \num_compare:nNnTF {#1}<\c_zero
  {
    - \int_convert_from_base_ten_aux:non {}
    { \int_use:N \int_eval:n {-#1} } 
  }
  {
    \int_convert_from_base_ten_aux:non {}
    { \int_use:N \int_eval:n {#1} } 
  }
  {#2}
}
%    \end{macrocode}
% The algorithm runs like this:
% \begin{enumerate}
% \item If the number \meta{num} is greater than \meta{base},
%   calculate modulus of \meta{num} and \meta{base} and carry that
%   over for next round. The remainder is calculated as a truncated
%   division of \meta{num} and \meta{base}. Start over with these new
%   values.
% \item If \meta{num} is less than or equal to \meta{base} convert it
%   to the correct symbol, print the previously calculated digits and
%   exit.
% \end{enumerate}
% |#1| is the carried over result, |#2| the remainder and |#3| the
% base number.
%    \begin{macrocode}
\def_new:Npn \int_convert_from_base_ten_aux:nnn#1#2#3{
  \num_compare:nNnTF {#2}<{#3}
  { \int_convert_number_to_letter:n{#2} #1 }
  {
    \int_convert_from_base_ten_aux:fon 
    {
      \int_convert_number_to_letter:n {\int_use:N\int_mod_raw:nn {#2}{#3}} 
      #1
    }
    {\int_use:N \int_div_truncate_raw:nn{#2}{#3}}
    {#3}
  }
}
\def:Npn \int_convert_from_base_ten_aux:non{
  \exp_args:Nno\int_convert_from_base_ten_aux:nnn
}
\def:Npn \int_convert_from_base_ten_aux:fon{
  \exp_args:Nfo\int_convert_from_base_ten_aux:nnn
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \begin{macro}{\int_convert_number_to_letter:n}
%   Turning a number for a different base into a letter or digit.
%    \begin{macrocode}
\def:Npn \int_convert_number_to_letter:n #1{ \if_case:w \int_eval:w
  #1-10\scan_stop: \exp_after:NN A \or: \exp_after:NN B \or:
  \exp_after:NN C \or: \exp_after:NN D \or: \exp_after:NN E \or:
  \exp_after:NN F \or: \exp_after:NN G \or: \exp_after:NN H \or:
  \exp_after:NN I \or: \exp_after:NN J \or: \exp_after:NN K \or:
  \exp_after:NN L \or: \exp_after:NN M \or: \exp_after:NN N \or:
  \exp_after:NN O \or: \exp_after:NN P \or: \exp_after:NN Q \or:
  \exp_after:NN R \or: \exp_after:NN S \or: \exp_after:NN T \or:
  \exp_after:NN U \or: \exp_after:NN V \or: \exp_after:NN W \or:
  \exp_after:NN X \or: \exp_after:NN Y \or: \exp_after:NN Z \else:
  \use_arg_i_after_fi:nw{ #1 }\fi: }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\int_convert_to_base_ten:nn}
%   |#1| is the number, |#2| is its base. First we get the sign, then
%   use only the digits/letters from it and pass that onto a new
%   function.
%    \begin{macrocode}
\def:Npn \int_convert_to_base_ten:nn #1#2 {
  \int_use:N\int_eval:n{
    \int_get_sign:n{#1}
    \exp_args:Nf\int_convert_to_base_ten_aux:nn {\int_get_digits:n{#1}}{#2}
  }
}
%    \end{macrocode}
% This is an intermediate function to get things started.
%    \begin{macrocode}
\def_new:Npn \int_convert_to_base_ten_aux:nn #1#2{
  \int_convert_to_base_ten_auxi:nnN {0}{#2} #1 \q_nil
}
%    \end{macrocode}
% Here we check each letter/digit and calculate the next number. |#1|
% is the previously calculated result (to be multiplied by the base),
% |#2| is the base and |#3| is the next letter/digit to be added.
%    \begin{macrocode}
\def_new:Npn \int_convert_to_base_ten_auxi:nnN#1#2#3{
  \quark_if_nil:NTF #3
  {#1}
  {\exp_args:No\int_convert_to_base_ten_auxi:nnN
    {\int_use:N \int_eval:n{ #1*#2+\int_convert_letter_to_number:N #3} }
    {#2}
  }
}
%    \end{macrocode}
% This is for turning a letter or digit into a number. This function
% also takes care of handling lowercase and uppercase letters. Hence
% |a| is turned into |11| and so is |A|.
%    \begin{macrocode}
\def:Npn \int_convert_letter_to_number:N #1{
  \int_compare:nNnTF{`#1}<{58}{#1}
  {
    \int_eval:n{ `#1 -
      \if:w\int_compare_p:nNn{`#1}<{91}
      55
      \else:
      87
      \fi:
    }
  }
}
%    \end{macrocode}
% \end{macro}
%
%
%
%
%
%
%
%    Show token usage:
%    \begin{macrocode}
%</initex|package>
%<*showmemory>
\showMemUsage
%</showmemory>
%    \end{macrocode}
%
%
% \endinput
%
% $Log$
% Revision 1.26  2006/06/03 17:17:08  morten
% Functions for converting between number bases
%
% Revision 1.25  2006/03/20 18:26:35  braams
% Updated the copyright notice (2006) and demoted all implementation
% sections to subsections and so on to clean up the toc for source3.tex
%
% Revision 1.24  2006/01/17 22:47:43  morten
% Changed \int_while:nNnT to \int_whiledo:nNnT to avoid confusion with
% the dowhile versions.
%
% Revision 1.23  2005/12/27 10:02:37  morten
% Minor changes plus changed RCS information retrieval
%
% Revision 1.22  2005/12/21 20:43:32  morten
% Fixed silly bugs!
%
% Revision 1.21  2005/12/06 17:31:23  morten
% fixed \int_convert_number_with_rule:nnN
%
% Revision 1.20  2005/12/06 14:49:36  morten
% Fixed primitive names plus a few minor touch-ups
%
% Revision 1.19  2005/04/25 15:02:47  morten
% Added ifodd functions
%
% Revision 1.18  2005/04/09 21:07:39  morten
% Added (extensible) implementations of \int_to_roman:n etc.
%
% Revision 1.17  2005/04/06 22:35:43  braams
% Now we have register allocation fitted
%
% Revision 1.16  2005/03/25 23:48:47  braams
% Added a missing \end{macro}
%
% Revision 1.15  2005/03/22 23:22:09  morten
% Moved definitions of constants to l3num
%
% Revision 1.14  2005/03/16 22:36:30  braams
% Added the tweaks necessary to be able to load with initex
%
% Revision 1.13  2005/03/11 21:38:31  braams
% Fixed the use of RCS information; added \StopEventually
%
