我需要做一个这样的等式
1011 (this is 11 in decimal) x 1110 (this is 14 in decimal) ====== 0000 (this is 1011 x 0) 1011 (this is 1011 x 1, shifted one position to the left) 1011 (this is 1011 x 1, shifted two positions to the left) + 1011 (this is 1011 x 1, shifted three positions to the left) ========= 10011010 (this is 154 in decimal)
我尝试过这样的编码
\begin{equation}
\frac{
\frac{
\begin{array}[b]{r}
1011 \\
\times 1110
\end{array}
}
{
\begin{array}[b]{r}
0000 \\
0000 \\
0000 \\
+ 0000
\end{array}
}
}
{
10011010
}
\end{equation}
但结果并不一致。
有什么建议么?
答案1
以下内容受到 的Robert Fuster
回答的启发。 (我对它做了一些修改,因为有些限制对于使该解决方案与和amsmath
等环境互操作非常重要。)align
gather
笔记。此环境要求最后一行以&
或结尾\\
,否则将产生错误。
简单示例
序言如下。
\begin{document}
\begin{equation}
\begin{arithmetic}
1011 & first factor \\
\times 1110 & second factor \\
0000 & this row is redundant\\
1011~ & this row has been shifted once\\
1011~~ \\
+ 1011~~~ \\
10011010 & result
\end{arithmetic}
\end{equation}
\end{document}
另一个例子:现在有了减法和长除法!
我添加了代码,允许用户描述减法和长除法。这是显示语法的示例代码。同样,本文档的序言如下所述。
\begin{document}
\begin{equation}
\begin{aligned}[t]
\begin{arithmetic}[t]
1011 & first factor \\
\times 1110 & second factor \\
0000 & (this row is redundant)\\
1011~ \\
1011~~ \\
+ 1011~~~ \\
10011010 & result
\end{arithmetic}
\quad
\begin{arithmetic}[t]
3094 \\
- 5029 \\
{{-}}1935 \\
\end{arithmetic}
\quad\;\;
\begin{arithmetic}[t]
1022~r1 \\
13 \Into 13287~~~ \\
\- 13~~~~~~ \\
028~~~~ \\
\- 26~~~~ \\
27~~~ \\
\- 26~~~ \\
1~~~ \\
\end{arithmetic}
\end{aligned}
\end{equation}
\end{document}
请注意{{-}}
上面示例代码中的 ,这是必要的,以避免将负号视为另一个减法运算;以及 符号\-
,我们在长除法中用作减法的替代符号,以获得行为不同的减法(在第一个空格处结束下划线)。
前言
此解决方案基于让表格条目在检测到要执行算术运算时自动使用下划线。它依赖于忽略每个表格单元格中的前导空格,并通过包对表格单元格样式进行一些花哨的操作array
。
\documentclass{article}
\usepackage{array}
\makeatletter
\providecommand\text\mbox
\newenvironment{arithmetic}[1][]{\begin{tabular}[#1]{Al}}{\end{tabular}}
\newcolumntype{A}{>{\bgroup\def~{\phantom{0}}$\@testOptor}r<{\@gobble\\$\egroup}}
列A
样式用于算术运算。它改变了 的含义,~
使其充当正确宽度的空格字符,打开数学模式,并尝试从硬编码列表中检测算术运算符。由于技术原因,列样式以一些涉及结束行的奇怪命令结束。
\def\@testOptor\ignorespaces#1#2\\{%
\ifx#1\times
\@OperatorRow{#1}{#2}\@tempa%
\else\ifx#1+
\@OperatorRow+{#2}\@tempa%
\else\ifx#1\discretionary% detects the soft hyphen, \-
\@ShortSubtractRow{#2}\@tempa%
\else\ifx#1-
\@OperatorRow-{#2}\@tempa%
\else
\@NormalRow{#1#2}\@tempa%
\fi\fi\fi\fi
\@tempa}
该\@testOptor
宏会抓取\ignorespaces
列定义和之间的所有内容\\
(可能是行尾或仅仅是列尾的一部分)。如果它发现算术运算,它会用下划线排版。否则,它会尝试正常排版。
有一种特殊情况:软连字符\-
用于调出类似减法的语法,其中下划线仅延伸到第一个~
空格命令。
\def\@OperatorRow#1#2#3{%
\@IfEndRow#2\@gobble\\{%
\def#3{\underline{{}#1 #2}\\}%
}{%
\def#3{\underline{{}#1 #2{}}}%
}}
\def\@NormalRow#1#2{%
\@IfEndRow#1\@gobble\\{%
\def#2{#1\\}%
}{%
\def#2{#1{}}%
}}
\def\@IfEndRow#1\@gobble#2\\#3#4{%
\ifx#2\@gobble
#4%
\else
#3%
\fi}
\makeatother
我们必须做一些奇怪的事情,因为我们不知道在任何给定的单元格中我们是否只结束了单元格,还是结束了行。我们测试参数的最后一个宏是否是\@gobble
:如果是,它只是一个行结束,所以我们应该添加另一个\@gobble
以确保行实际上没有结束。
\def\@ShortSubtractRow#1#2{\@@ShortSubtractRow#1~\end{#2}}
\def\@@ShortSubtractRow#1#2~#3\end#4{%
\@IfEndRow#3\@gobble\\{%
\def#4{\underline{\text{--} #2}#3\\}%
}{%
\def#4{\underline{\text{--} #2{}}#3}%
}}
对于长除法中使用的短减法,我们对行尾进行类似的测试,但也将参数的结尾定义为第一个~
字符的下划线。我们使用\text{--}
适当的减号来节省空间(它不像笔划那么长)。
\def\Into#1\\{%
\@IfEndRow#1\@gobble\\{%
\def\@tempa{~\raisebox{0.17ex}{\parbox{0.15em}{\centering$\big|$}}\overline{~\big.#1}\\}%
}{%
\def\@tempa{~\raisebox{0.17ex}{\parbox{0.15em}{\centering$\big|$}}\overline{~\big.#1{}}}%
}\@tempa}
该\Into
命令不是环境检测到的操作符,但它同样尝试收集该行的剩余内容,以便\overline
在其上绘制。
使用上面的示例文档之一来补充这个序言,瞧!
答案2
\documentclass{article}
\begin{document}
\begin{equation}
\begin{array}{r}
1011\\
\underline{\mbox{}\times 1110}\\
0000\\
1011\phantom{0}\\
1011\phantom{00}\\
\underline{\mbox{}+ 1011\phantom{000}}\\
10011010
\end{array}
\end{equation}
\end{document}
答案3
如果您不需要注释,我建议采用以下解决方案:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\multiplication}{ O{c} m m m o }
{
\IfNoValueTF { #5 }
{
\xiong_simple_table:nnnn { #1 } { #2 } { #3 } { #4 }
}
{
\xiong_full_table:nnnnn { #1 } { #2 } { #3 } { #4 } { #5 }
}
}
\tl_new:N \l_xiong_table_body_tl
\cs_new_protected:Npn \xiong_simple_table:nnnn #1 #2 #3 #4
{
\begin{array}[#1]{r}
#2 \\
{\times}\; #3 \\
\hline
#4
\end{array}
}
\cs_new_protected:Npn \xiong_full_table:nnnnn #1 #2 #3 #4 #5
{
\tl_clear:N \l_xiong_table_body_tl
\int_step_inline:nnnn { 0 } { 1 } { \clist_count:n { #5 } - 1 }
{
\tl_put_right:Nx \l_xiong_table_body_tl
{
\int_compare:nT { ##1 == \clist_count:n { #5 } - 1 }
{ {+}\exp_not:N \; }
\clist_item:nn { #5 } { ##1 + 1 }
\exp_not:n { \prg_replicate:nn { ##1 } { \hphantom{0} } \\ }
}
}
\begin{array}[#1]{r}
#2 \\
{\times}\; #3 \\
\hline
\tl_use:N \l_xiong_table_body_tl
\hline
#4
\end{array}
}
\ExplSyntaxOff
\begin{document}
Short table: $\multiplication[t]{1011}{1110}{10011010}$
\bigskip
Long table: $\multiplication[t]{1011}{1110}{10011010}[0000,1011,1011,1011]$
\end{document}
第一个可选参数与环境相同array
:[t]
或[b]
垂直对齐(默认为居中对齐)。三个强制参数是因子和结果,尾随的可选参数包含中间加数列表。
以下是给定因子的自动计算的实现;限制:不允许乘以 0(它可以需要注意的是,乘积最多可以有 31 位数字。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\fullmultiplication}{ O{c} m m }
{
\xiong_full_table:nnn { #1 } { #2 } { #3 }
}
\tl_new:N \l__xiong_table_body_tl
\tl_new:N \l__xiong_padding_tl
\seq_new:N \l__xiong_multiplier_seq
\int_new:N \l__xiong_length_int
\cs_new_protected:Npn \xiong_full_table:nnn #1 #2 #3
{
\__xiong_compute:nn { #2 } { #3 }
\begin{array}[#1]{r}
#2 \\
{\times}\; #3 \\
\hline
\tl_use:N \l__xiong_table_body_tl
\hline
\int_to_binary:n { \int_from_binary:n { #2 } * \int_from_binary:n { #3 } }
\end{array}
}
\cs_new_protected:Npn \__xiong_compute:nn #1 #2
{
% clear the variables
\tl_clear:N \l__xiong_table_body_tl
\tl_clear:N \l__xiong_padding_tl
% split the multiplier into digits
\seq_set_split:Nnn \l__xiong_multiplier_seq { } { #2 }
% reverse the sequence, as we want to multiply from the right
\seq_reverse:N \l__xiong_multiplier_seq
% count the number of digits
\int_set:Nn \l__xiong_length_int { \seq_count:N \l__xiong_multiplier_seq }
% detach the most significant bit (we want to add a +)
\seq_pop_right:NN \l__xiong_multiplier_seq \l__xiong_msb_tl
% compute the partial summands (either zeroes or #1)
\seq_map_inline:Nn \l__xiong_multiplier_seq
{
\tl_put_right:Nx \l__xiong_table_body_tl
{
\str_if_eq:nnTF { 1 } { ##1 }
{ #1 }
{ \prg_replicate:nn { \l__xiong_length_int } { 0 } }
}
\tl_put_right:NV \l__xiong_table_body_tl \l__xiong_padding_tl
\tl_put_right:Nn \l__xiong_table_body_tl { \\ }
\tl_put_right:Nn \l__xiong_padding_tl { \hphantom{0} }
}
% the last summand is #1
\tl_put_right:Nn \l__xiong_table_body_tl { {+}\; #1 \tl_use:N \l__xiong_padding_tl \\ }
}
\ExplSyntaxOff
\begin{document}
Here it is: $\fullmultiplication[t]{1011}{1110}$
\end{document}
通过键值语法,提供更多选项:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\fullmultiplication}{ O{} m m }
{
\group_begin:
\keys_set:nn { xiong/binmult } { #1 }
\xiong_multiplication:nn { #2 } { #3 }
\group_end:
}
\keys_define:nn { xiong/binmult }
{
align .choice:,
align/top .code:n = \tl_set:Nn \l__xiong_align_tl { t },
align/t .code:n = \tl_set:Nn \l__xiong_align_tl { t },
align/bottom .code:n = \tl_set:Nn \l__xiong_align_tl { b },
align/b .code:n = \tl_set:Nn \l__xiong_align_tl { b },
align/c .code:n = \tl_set:Nn \l__xiong_align_tl { c },
align/center .code:n = \tl_set:Nn \l__xiong_align_tl { c },
full .bool_set:N = \l__xiong_full_bool,
full .initial:n = true,
showzero .bool_set:N = \l__xiong_showzero_bool,
showzero .initial:n = true,
}
\tl_new:N \l__xiong_align_tl
\tl_set:Nn \l__xiong_align_tl { c } % default
\tl_new:N \l__xiong_table_body_tl
\tl_new:N \l__xiong_padding_tl
\seq_new:N \l__xiong_multiplier_seq
\int_new:N \l__xiong_length_int
\cs_new_protected:Npn \xiong_multiplication:nn #1 #2
{
\int_compare:nT { #2 == 0 } { \bool_set_false:N \l__xiong_full_bool }
\bool_if:NT \l__xiong_full_bool
{ \__xiong_compute:nn { #1 } { #2 } }
\begin{array}[\l__xiong_align_tl]{r}
#1 \\
{\times}\; #2 \\
\hline
\bool_if:NT \l__xiong_full_bool
{
\tl_use:N \l__xiong_table_body_tl
\hline
}
\int_to_binary:n { \int_from_binary:n { #1 } * \int_from_binary:n { #2 } }
\end{array}
}
\cs_new_protected:Npn \__xiong_compute:nn #1 #2
{
% clear the variables
\tl_clear:N \l__xiong_table_body_tl
\tl_clear:N \l__xiong_padding_tl
% split the multiplier into digits
\seq_set_split:Nnn \l__xiong_multiplier_seq { } { #2 }
% reverse the sequence, as we want to multiply from the right
\seq_reverse:N \l__xiong_multiplier_seq
% count the number of digits
\int_set:Nn \l__xiong_length_int { \seq_count:N \l__xiong_multiplier_seq }
% detach the most significant bit (we want to add a +)
\seq_pop_right:NN \l__xiong_multiplier_seq \l__xiong_msb_tl
% compute the partial summands (either zeroes or #1)
\seq_map_inline:Nn \l__xiong_multiplier_seq
{
\tl_put_right:Nx \l__xiong_table_body_tl
{
\str_if_eq:nnTF { 1 } { ##1 }
{ #1 }
{
\bool_if:NT \l__xiong_showzero_bool
{ \prg_replicate:nn { \l__xiong_length_int } { 0 } }
}
}
\tl_put_right:NV \l__xiong_table_body_tl \l__xiong_padding_tl
\bool_if:nT { \l__xiong_showzero_bool || \str_if_eq_p:nn { 1 } { ##1 } }
{ \tl_put_right:Nn \l__xiong_table_body_tl { \\ } }
\tl_put_right:Nn \l__xiong_padding_tl { \hphantom{0} }
}
% the last summand is #1
\tl_put_right:Nn \l__xiong_table_body_tl { {+}\; #1 \tl_use:N \l__xiong_padding_tl \\ }
}
\ExplSyntaxOff
\begin{document}
Here it is: $\fullmultiplication[align=t]{1011}{1110}$
Here it is: $\fullmultiplication[align=b,showzero=false]{1011}{1110}$
Here it is: $\fullmultiplication[align=b,full=false]{1011}{1110}$
Here it is: $\fullmultiplication{1011}{0}$
\end{document}
答案4
这里有一些可以完成您想要的操作的代码:
$
\begin{array}{cccccccccl}
&&&&1&0&1&1&\quad&\text{(this is 11 in decimal)} \\
&&&\times&1&1&1&0&&\text{(this is 14 in decimal)} \\ \cline{4-8}
&&&&0&0&0&0&&\text{(this is $1011 \times 0)$} \\
&&&1&0&1&1&&&\text{(this is $1011 \times 1$, shifted one position to the left)} \\
&&1&0&1&1&&&&\text{(this is $1011 \times 1$, shifted two positions to the left)} \\
&1&0&1&1&&&&&\text{(this is $1011 \times 1$, shifted three positions to the left)} \\ \cline{1-8}
1&0&0&1&1&0&1&0&&\text{(this is $154$ in decimal)} \\
\end{array}
$
为了获取代码,我使用了电子表格程序。我将数字和文本输入到单元格中,就像您希望在输出中看到的那样。其中包含一些 TeX 命令,您可以在代码中看到它们。然后我复制电子表格单元格并将其粘贴到 TeX 编辑器中。在 TeX 编辑器中,两个数字之间有空格,但这是一个特殊的非打印字符。选择这个特殊字符并使用命令replace all
,我&'s
毫不费力地插入了所有内容。
如果您想使用此方法,您的编辑器将需要这些功能。我尝试使用两个不同的电子表格程序和四个不同的编辑器。对于所有 4 个编辑器,此方法都毫无问题。使用电子表格程序可以成为准备tabular, matrix
和array
在 TeX 文档中使用的几项内容的有效方法。