6

I have to make an assignment about converting base-n notation to decimal and vice versa.

We are allowed to make it on paper, and send it in digitally by scanning. However, I'd like to send it in using LaTeX. Because I think it's an interesting technology which can come very handy in the future to handle.

Unfortunately I don't know yet how to use it properly, I don't feel the same 'freedom' as I'd have with e.g LibreOffice Writer. But an helping hand can solve that!

This is what I have on paper:

enter image description here

How would I make that nice in LaTeX?

This is what I need to know: How to...

  • Put a small number (base number) in small right-bottom of the notation
  • Make those arrows (down and than right)
  • Bullet for multiply-sign
  • Exponent
  • Make that add-notation, with that line and plus-sign
  • All nicely formatted?

To be clear, I'm not asking any of you to do this all for me. But to put my in the right direction or give examples on how to accomplish this. Thanks!

2
  • 2
    Welcome to TeX.SX! Please help us (and also you) and add a minimal working example (MWE). This isn't a "Please do my work for me" site! What do you have so far? Try to create ... and we will help you to get your "perfect" paper.
    – Bobyandbob
    Commented Nov 11, 2017 at 15:52
  • My answer and @DavidCarlisle's ones do the computations automatically which may be a bit overwhelming. You can drop that aspect of the answers and concentrate on formatting: it is rather natural to use a "tabular" to align the computations. Then you can extract from my answer the technique for instructing TikZ to draw the arrows. You only need to manually insert the suitable \tablenode (from tex.stackexchange.com/a/400571/4686; by the way they don't have to be used inside a tabular) to create the source and target nodes for the arrows.
    – user4686
    Commented Nov 14, 2017 at 9:32

2 Answers 2

17
  • First version uses LaTeX's picture as enhanced by pict2e and it only handles bases less then (or equal to) 10, some extra macros would be needed for higher bases (from digits in the base to actual number in base 10 understood by TeX; the case of bases <= 16 could be handled directly as in v2).

  • Second version works with bases up to 16 and it uses TikZ's tikzpicture for fancier graphics. I went a bit overboard when I started playing with xcolor color series... Also the method uses tabular's allowing easier to right align things than in v1 with direct \put.

    Regarding the basic TikZ method for setting up nodes and then drawing arrows from one tabular to the other, I copied it from https://tex.stackexchange.com/a/400571/4686. It needs at least two compilations.

    In an edit, I have simplified a bit the coding of v2 (removal of usage of \xintAssignArray, as the \xintFor* loops are used directly on the number to be converted without having first made it into an "array"). For v2, the number passed as second argument to \ConvertFromBase may be a macro (if it is completely expandable in an \edef).

  • finally I add also for conversion from decimal to another base: at most 36 because Latin alphabet has 26 letters (I don't know the consensus on notation beyond that). This was also mentioned in OP but with no concrete layout proposed. If a separate question gets asked I will move that part to an answer there.

  • Remove brackets who causes an error.

Last remark: the conversion routines are tailored by the display constraints. For numbers with hundreds of digits, one would proceed differently (as it is not realistic to display like here and only the result of the conversion matters). The macros here do not necessarily define a macro expanding to the converted number, as they are only preoccupied with typesetting the process.


v1

\documentclass{article}
\usepackage{xint, xinttools}
\usepackage{pict2e}
\usepackage{picture}

\makeatletter
\newcommand\ConvertFromBase[2]{%
  \begingroup
  \ttfamily
  \def\my@base{#1}%
  \def\my@number{#2}%
  \xdef\my@total{0}%
  \edef\my@power{1}%
% ATTENTION THIS IS ONLY FOR BASES <= 10.
  \xintAssignArray\xintRev{\my@number}\to\my@array
  \setlength{\unitlength}{1sp}%
  \begin{picture}(\my@array{0}\fontcharwd\font`0,%
                  \numexpr\my@array{0}+2\relax\baselineskip)
                 (-\my@array{0}\fontcharwd\font`0,%
                  -\numexpr\my@array{0}+1\relax\baselineskip)
    \put(0,0){ (base #1)}
    \xintFor* ##1 in {\xintSeq{1}{\my@array{0}}}\do{
      \put(-##1\fontcharwd\font`0,0){\my@array{##1}}
      \edef\my@partial{\xintiiMul{\my@array{##1}}{\my@power}}
      \xdef\my@total{\xintiiAdd{\my@total}{\my@partial}}
      \put(0,-##1\baselineskip)
      {$\my@array{##1}\cdot\my@base^{\the\numexpr##1-1\ifnum##1<11 \phantom{9}\fi}=\my@partial$}
      \edef\my@power{\xintiiMul{\my@base}{\my@power}}
% unfortunately we can not use dimensions like in \put with the
% \curveto command. We have to use the picture "unit", hence we
% we the latter to 1sp, for easier computations with \number
      \edef\halfx
          {\number\dimexpr.5\dimexpr\the\numexpr##1-1.5\fontcharwd\font`0}
      \edef\halfy
          {\number\dimexpr.5\dimexpr##1\baselineskip}
      \moveto(-\numexpr2*\halfx, 0)
      \curveto(-\numexpr2*\halfx, -\halfy)(-\halfx,-\numexpr2*\halfy\relax)%
              (0,-\numexpr2*\halfy\relax)
      \strokepath
      }
  \end{picture}\hphantom{$9\cdot9^{99}$}${}=\my@total$%
  \endgroup
}
\makeatother

\begin{document}\pagestyle{empty}
BEFORE\ConvertFromBase{9}{666}AFTER (to show space occupied)

\ConvertFromBase{9}{12345678}

\ConvertFromBase{2}{10001001001000111100000101010101001110101010010101}

\end{document}

enter image description here

enter image description here


v2

\documentclass{article}
\usepackage{xint, xinttools}
\usepackage{tikz}

% From https://tex.stackexchange.com/a/400571/4686
\newcommand{\tablenode}[2]
 {\tikz[baseline=(#1.base),remember picture]\node[inner sep=0pt,name=#1]{#2};}

\makeatletter
% Works with bases up to 16, using ABCDEF as digits for 10, ..., 15
% (we use that TeX understand "A, ..., "F; for higher bases we would
% need macros converting from the base-b digit to the base-10 number)
\newcommand\ConvertFromBase[2]{%
  \begingroup
  \ttfamily
  \edef\my@base{#1}%   allow #1 to be a macro
  \edef\my@number{#2}% allow #2 to be a macro
  \gdef\my@total{0}%
  \gdef\my@power{1}%
  \edef\my@nbofdigits{\expandafter\xintLength\expandafter{\my@number}}%
% make fun things with colors
  \definecolorseries{foo}{rgb}{last}{red}{blue}%
  \resetcolorseries[\my@nbofdigits]{foo}%
% input number
  \global\let\my@nodeindex\my@nbofdigits
  \begin{tabular}{@{}*{\my@nbofdigits}{c@{}}c@{}}
    \xintFor* ##1 in {\my@number}\do{%
     \tablenode{A\my@nodeindex}{\textcolor{foo!!+}{##1}}%
     \xdef\my@nodeindex{\the\numexpr\my@nodeindex-1}% step by -1
    &}%
    ${}_{\my@base}$
  \end{tabular} %<-- deliberate space
% make fun things with colors
  \definecolorseries{foo}{rgb}{last}{blue}{red}%
  \resetcolorseries[\my@nbofdigits]{foo}%
% output conversion
  % \my@nodeindex is at 0
  \begin{tabular}[t]{@{}l@{}c@{}r@{}}
    &\\
    \xintFor* ##1 in % \xintReverseOrder does not expand its argument
    % \xintReverseDigits does but it works only with 0..9 digits
    % we could use \xintReverseOrder{#2}, if we did not need
    % to allow #2 to be a macro itself.
   {\expandafter\xintReverseOrder\expandafter{\my@number}}\do{%
      \xdef\my@nodeindex{\the\numexpr\my@nodeindex+1}% step by +1
      \tablenode{B\my@nodeindex}
                {\textcolor{foo}{##1}${}\cdot\my@base^{\the\numexpr\my@nodeindex-1}$}%
      &${}={}$&%
      % use " notation to allow also A, B, C, D, E, F (only uppercase)
      \edef\my@partial{\xintiiMul{\the\numexpr"##1\relax}{\my@power}}%
      \xdef\my@total{\xintiiAdd{\my@total}{\my@partial}}%
      \xdef\my@power{\xintiiMul{\my@base}{\my@power}}%
      \textcolor{foo!!+}{$\my@partial$}\\}%
  \cline{3-3}
  &&\textcolor{red}{$\my@total$}
  \end{tabular}%<-- no space here
% workaround the fact that foo!!+ from xcolor steps twice when used
% with tikz's \draw (I guess once from the arrow, once from the arrow tip)
  \resetcolorseries[\numexpr2*\my@nbofdigits\relax]{foo}%
% DRAWING THE ARROWS
%
% YOU NEED TO COMPILE AT LEAST TWICE FOR THE START AND END
% NODE LOCATIONS TO STABILIZE
%
  \begin{tikzpicture}[remember picture, overlay, >=stealth]
  % tikz natural language:
  % (this loop uses first the nodes for the least significant digits
  %  and ends up with the ones for the most significant digits)
  \foreach\my@nodeindex in {1, 2, ..., \my@nbofdigits}
    {\draw [->,very thick,{foo!!+}] 
           (A\[email protected]) to[out=270,in=180] (B\[email protected]);}%
  % or again with an \xintFor loop
  %  \xintFor* ##1 in {\xintSeq{1}{\my@nbofdigits}}\do{%
  %     \draw [->,very thick,{foo!!+}] 
  %           (A##1.south) to[out=270,in=180] (B##1.west);%
  %    }%
  \end{tikzpicture}%<-- no space here
 \endgroup
}
\makeatother

\begin{document}\pagestyle{empty}
BEFORE\ConvertFromBase{16}{FFF}AFTER (to show space occupied)

\ConvertFromBase{9}{12345678}

\ConvertFromBase{16}{F9A70B46721}

\ConvertFromBase{2}{10001001001000111100000101010101001110101010010101}

\end{document}

enter image description here

enter image description here


Conversion from decimal to another base. The target base is at most 36.

The OP mentioned this was also asked for but gave to model layout. I chose the one which made the curves easier to manage.

\documentclass{article}
\usepackage{geometry}
\usepackage{xintexpr}
\usepackage{tikz}

% From https://tex.stackexchange.com/a/400571/4686
\newcommand{\tablenode}[2]
 {\tikz[baseline=(#1.base),remember picture]\node[inner sep=0pt,name=#1]{#2};}

\makeatletter
\newcommand\ConvertDigit[1]{\ifcase\numexpr#1\relax
0\or1\or2\or3\or4\or5\or6\or7\or8\or9%
\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\else\TOOBIGDIGIT\fi}
%
\newcommand\ConvertToBase[2]{%
% #1 = target base
% #2 = number to be converted
  \begingroup
  \ttfamily
  \edef\my@base{#1}%   allow #1 to be a macro, must be at most 36
  \edef\my@number{#2}% allow #2 to be a macro
  \global\let\my@remainder\my@number
  % produce a comma separated list of all the powers of the base
  % at most equal to the number, with highest power first
  % of course, it is not really needed to use \xintiiexpr here,
  % but this is fun (to me) and avoids defining any helper macro...
  \edef\my@powers{%
    \xinttheiiexpr 
      reversed(rseq(1; (@>\my@number)?{abort}{\my@base*@},n=1++))[1:]
      % [1:] is Python slicing notation to drop the first item as
      % it is actually the first base^something > number
    \relax
  }%
  \edef\my@nbofdigits{\xintCSVLength{\my@powers}}%
  \global\let\my@nodeindex\my@nbofdigits
% make fun things with colors
  \definecolorseries{foo}{rgb}{last}{red}{blue}%
  \resetcolorseries[\my@nbofdigits]{foo}%
\begin{tabular}{@{}c@{}c@{}}% used for positioning, surely a better TikZ
                            % solution exists
  % nothing here
  &
  \begin{tabular}{@{}r@{}r@{}r@{}}
    &\my@number&\\
    \cline{2-2}
% \xintFor works with comma separated lists,
% it expands once the list argument
    \xintFor ##1 in {\my@powers}\do{%
     \xdef\my@nodeindex{\the\numexpr\my@nodeindex-1}% step by -1
     \xintAssign\xintiiDivision{\my@remainder}{##1}\to\Q\R
% no LaTeX \@nameedef, only \@namedef (booooohhhh....)
     \global\expandafter\let\csname my@digits\my@nodeindex\endcsname\Q
     \xdef\my@temp{\xintiiSub{\my@remainder}{\R}}% = digit times base^power
     \global\let\my@remainder\R
     $\tablenode{A\my@nodeindex}
               {\textcolor{foo!!+}{\@nameuse{my@digits\my@nodeindex}}}
     \times{}$&$##1$&\null\space$(\my@base^{\my@nodeindex})$\\
     ${}={}$&$\my@temp$&\\
     $\to$&$\my@remainder$&\\
     \ifnum\my@nodeindex=\z@\else\cline{2-2}\fi % happy that \cline ok before \fi
     }% end of xintFor loop
  \end{tabular}\\
% CONVERTED NUMBER
  \resetcolorseries[\my@nbofdigits]{foo}% good that global effect
% \xintFor* works with braced items
% it f-expands the list argument (at each iteration after pruning an item)
% \xintSeq produces list of number, detects automatically if needs
% to go decreasing
  \xintFor* ##1 in {\xintSeq{\my@nbofdigits-1}{0}}\do{%
      \tablenode{B##1}
      {\textcolor{foo!!+}{\ConvertDigit{\@nameuse{my@digits##1}}}}%
      }% end of second For loop
  ${}_{\my@base}$%
  &
  % nothing here
\end{tabular}% end of enclosing tabular used for positioning other one
%
% workaround the fact that foo!!+ from xcolor steps twice when used
% with tikz's \draw (I guess once from the arrow, once from the arrow tip)
  \resetcolorseries[\numexpr2*\my@nbofdigits\relax]{foo}%
% DRAWING THE ARROWS
%
% YOU NEED TO COMPILE AT LEAST TWICE FOR THE START AND END
% NODE LOCATIONS TO STABILIZE
%
  \begin{tikzpicture}[remember picture, overlay, >=stealth]
    \xintFor* ##1 in {\xintSeq{\my@nbofdigits-1}{0}}\do{%
       \draw [->,very thick,{foo!!+}] 
             (A##1.west) to[out=180,in=90] (B##1.north);%
      }%
  \end{tikzpicture}%<-- no space here
 \endgroup
}
\makeatother

\begin{document}\pagestyle{empty}

\ConvertToBase{2}{10000}% layout takes lot of vertical space...

\clearpage

\ConvertToBase{16}{17155990251297}

\clearpage

\ConvertToBase{16}{4096}

\end{document}

For base 2, the layout taking much vertical space limits us to some small example...

enter image description here

enter image description here

4
  • +1 Very pretty! (actually, I voted earlier for the pre-tikzpicture version:)
    – user30471
    Commented Nov 12, 2017 at 16:12
  • @Andrew, I initially wanted to use your matrix of nodes, but I am not familiar enough with it (rather: not at all) to get quickly layout I know how to obtain from tabular (+ the loop \xintFor which I designed especially to be usable within tabular; possibly within matrix of nodes, even simpler loops will do).
    – user4686
    Commented Nov 12, 2017 at 16:38
  • I made a comment The remember picture in \begin{tikzpicture}[remember picture, overlay, >=stealth] is not needed. Only overlay is but this was wrong. I discovered after compiling twice... thus, yes, the remember picture is mandatory. I shoud learn to trust the answers on this site...
    – user4686
    Commented Nov 12, 2017 at 17:17
  • for conversion to another base b another approach is simply iteration n <- n div b, the digit being n mod b (in Python n, digit = divmod(n, b)). This produces base-b-digits from least to most significant. This would by the way allow a more compact layout than the one used here based on subtracting powers of b. I guess an elementary course would first use the approach here, then the divmod one as alternative.
    – user4686
    Commented Nov 14, 2017 at 8:53
6

Something like this might get you started

enter image description here

\documentclass{article}
\usepackage{amsmath}

\def\zz#1#2{%
\begin{array}{r@{}l@{{}={}}r}
\multicolumn{1}{l}{\llap{#1}_{#2}}\\
\gdef\zzp{0}%
\gdef\zzpp{1}%
\gdef\zzt{0}%
\sbox0{0}%
\xdef\zzw{\the\wd0}%
\xdef\zzww{0pt}%
\zzz#1\relax{#2}
\end{array}}
\def\zzz#1#2\relax#3{%
\hspace{-\zzww}$\rightarrowfill$&#1\times#3^{\zzp}&\the\numexpr(#1)*(\zzpp)\relax
\xdef\zzww{\the\dimexpr\zzww+\zzw\relax}%
\xdef\zzt{\the\numexpr(#1)*(\zzpp)+\zzt\relax}%
\xdef\zzp{\the\numexpr\zzp+1\relax}%
\xdef\zzpp{\the\numexpr(\zzpp)*(#3)\relax}%
\ifx\relax#2\relax
\\\cline{3-3}
\zza{\multicolumn{2}{c}{}&}\zzt\else
\\\zzz#2\relax{#3}%
\fi}
\def\zza#1{#1}
\begin{document}


$\zz{666}{9}$


\end{document}

would need a bit more work to add the vertical lines, and cope with bases bigger than 10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .