我必须完成一项作业,将基数为 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$\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 的基数