LaTeX 中的 n 进制到十进制计算

LaTeX 中的 n 进制到十进制计算

我必须完成一项作业,将基数为 n 的表示法转换为十进制,反之亦然。

我们可以在纸上制作,然后通过扫描以数字形式发送。但是,我想使用 LaTeX 发送。因为我认为这是一项有趣的技术,将来会非常有用。

不幸的是,我还不知道如何正确使用它,我感觉不到像使用 LibreOffice Writer 那样的“自由”。但有人能伸出援手,就能解决这个问题!

这是我在纸上所写的:

在此处输入图片描述

我怎样才能在 LaTeX 中让它变得好看呢?

这是我需要知道的: 如何...

  • 在符号的右下角小位置输入一个小数(基数)
  • 制作那些箭头(向下,然后向右)
  • 多重签名项目符号
  • 指数
  • 用那条线和加号做加法符号
  • 格式都很好吗?

需要说明的是,我并不是要求你们为我做这一切。而是要求你们为我指明正确的方向或举例说明如何做到这一点。谢谢!

答案1

  • 第一个版本使用 LaTeX 的图片作为增强版,pict2e它只处理小于(或等于)10 的基数,对于更高的基数(从基数中的数字到 TeX 理解的 10 基数的实际数字),需要一些额外的宏;基数 <= 16 的情况可以直接处理,如下所示v2)。

  • 第二个版本适用于最多 16 个基数,并使用 TikZ 的 tikzpicture 来制作更精美的图形。当我开始使用 xcolor 颜色系列时,我有点过头了……此外,该方法使用 tabular,可以比在v1直接\put

    关于设置节点然后从一个表格到另一个表格绘制箭头的基本 TikZ 方法,我从https://tex.stackexchange.com/a/400571/4686. 至少需要两次编译。

    在编辑中,我简化了一些编码v2(删除了 的使用\xintAssignArray,因为\xintFor*循环直接用于要转换的数字,而无需先将其转换为“数组”)。对于v2,作为第二个参数传递的数字可能\ConvertFromBase是一个宏(如果它在中完全可扩展\edef)。

  • 最后,我还补充了从十进制到其他进制的转换:最多 36 个,因为拉丁字母有 26 个字母(我不知道除此之外的符号的共识)。 OP 中也提到了这一点,但没有提出具体的布局。 如果有人提出单独的问题,我会将该部分移至那里的答案。

最后说明:转换例程是根据显示约束量身定制的。对于有数百位数字的数字,可以采用不同的方法(因为像这里这样显示是不现实的,只有转换的结果才重要)。这里的宏不一定定义扩展到转换后数字的宏,因为它们只专注于排版过程。


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}

在此处输入图片描述

在此处输入图片描述


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}

在此处输入图片描述

在此处输入图片描述


从十进制转换为其他基数。目标基数最多为 36。

楼主提到这也是要求的,但给了模型布局。我选择了使曲线更易于管理的那个。

\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}

对于基数 2,布局占用了太多的垂直空间,这限制了我们只能举一些小例子......

在此处输入图片描述

在此处输入图片描述

答案2

类似这样的事情可能会让你开始

在此处输入图片描述

\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}

需要做更多工作来添加垂直线,并处理大于 10 的基数

相关内容