Inspired by a question yesterday, I thought I'd try my hand at a LaTeX3 solution which would show how to convert base 10 numbers into any other base of the user's choice.
Yesterday I wrote a nice simple version that worked. But today, I decided I wanted to separate the building of the steps from the process of outputting and formatting those steps. I also thought it would be interesting to explore the possibilities of creating the effect of an array within an array using sequences
and token lists
.
But now, I'm getting an error.
\documentclass{article}
\usepackage{amsmath,amssymb}
\usepackage{xparse}
\pagestyle{empty}
\ExplSyntaxOn
%% setting and getting the base
\int_new:N \g__new_base_int
\NewDocumentCommand{\setbase}{ m }{
\int_gset:Nn \g__new_base_int { #1 }
}
\NewDocumentCommand{\getbase}{}{
\int_use:N \g__new_base_int
}
%% setting and getting the number to be converted
\int_new:N \g__number_to_convert_int
\NewDocumentCommand{\setnumber}{ m }{
\int_gset:Nn \g__number_to_convert_int {#1}
}
\NewDocumentCommand{\getnumber}{ }{
\int_use:N \g__number_to_convert_int
}
%%---internal function to build each step in the conversion process
%%---and the parameters to be used for this function
\int_new:N \l__quotient_int
\int_new:N \l__tmp_new_quotient_int
\int_new:N \l__remainder_int
\seq_new:N \g__steps_of_conversion
\cs_new:Nn \__build_steps_of_conversion: {
\int_set_eq:NN \l__quotient_int \g__number_to_convert_int
\int_do_while:nn { \l__quotient_int >= \g__new_base_int }
{
\int_set:Nn \l__remainder_int { \int_mod:nn { \l__quotient_int } { \g__new_base_int } }
\int_set:Nn \l__tmp_new_quotient_int { \int_div_truncate:nn { \l__quotient_int } {\g__new_base_int }}
\exp_args:NNx \seq_gput_right:Nn \g__steps_of_conversion
{
{\int_use:N \g__new_base_int }
{\int_use:N \l__quotient_int }
{\int_use:N \l__remainder_int }
{\int_use:N \l__tmp_new_quotient_int}
}
\int_set_eq:NN \l__quotient_int \l__tmp_new_quotient_int
}
}
%%---internal function to construct the display of the conversion process
\bool_new:N \l__first_item_on_line_bool
\cs_new:Nn \__show_steps_of_conversion: {
\__build_steps_of_conversion:
\seq_map_inline:Nn \g__steps_of_conversion
{
\bool_set_true:N \l__first_item_on_line_bool
\tl_map_inline:nn { ##1 } {
\bool_if:NF \l__first_item_on_line_bool { & }
###1
\bool_set_false:N \l__first_item_on_line_bool
}
\\
}
}
%%---user interface to displaying the conversion
\NewDocumentCommand{\showstepsofconversion}{ o }{
\[
\begin{array}{crc|r}
\text{Base} & & \text{R} & \text{Q} \\\hline
\__show_steps_of_conversion:
\end{array}
\]
}
%% accessing and using LaTeX3's internal base conversion
\NewDocumentCommand{\converttobase}{m}{
\int_to_base:nn {#1} \g__new_base_int
}
%%
\ExplSyntaxOff
\setlength{\parindent}{0pt}
\setbase{21}
\setnumber{2680010}
\begin{document}
The base is \getbase. \getnumber{} becomes $\converttobase{\getnumber}_{\getbase}$.
\showstepsofconversion
\end{document}
The problem seems to be ###1
. Oddly, the output is as I desire. The suggested correction to ##1
is clearly not correct and when I rewrite my code to ##1
I get the wrong value.
#
must be doubled, so I guess you need####1
. – egreg Feb 2 '13 at 16:30expl3
code should always be set up in a defined namespace. So here you might have\showbaseconv_...
as the function prefix, and therefore\l_showbaseconv_...
for a local variable, etc. – Joseph Wright♦ Feb 2 '13 at 16:33#
. – Joseph Wright♦ Feb 2 '13 at 16:33