How to make a multiply equation?
The following is inspired by Robert Fuster
's answer. (I have modified it slightly, because of some limitations which become important to make this solution interoperable with amsmath
evnironments such as align
and gather
.)
Note. This environment requires the last row to end with an &
or a \\
, or else it will generate an error.
Simple example
The pre-amble is described below.
\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}
Another example: now with subtraction and long division!
I have added code which allows the user to describe subtraction and long division as well. This is sample code showing the syntax. Again, the pre-amble for this document is described below.
\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}
Note the {{-}}
in the sample code above, which is necessary to avoid seeing the negation symbol as another subtraction operation; and the \-
symbols, which we use as an alternative symbol for subtraction in the midst of a long division to obtain a subtraction which behaves differently (ending the underline at the first space).
Preamble
This solution is based on making entries of a table automatically use underlines, whenever it detects an arithmetic operation is to be performed. It relies on ignoring leading whitespace in each table cell, and doing fancy things with the table-cell styles via the array
package.
\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}}
The A
column style is for arithmetic operations. It changes the meaning of ~
to make it act as a space character of the correct width, turns on math mode, and tries to detect an arithmetic operator from a hard-coded list. The column style ends with some odd commands involving end-rows for technical reasons.
\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}
The \@testOptor
macro grabs everything between \ignorespaces
in the column definition and \\
(which may be an end-of-row or merely part of an end-of-column). If it finds an arithmetic operation, it typesets it with underlines. Otherwise, it tries to typeset it normally.
There is one special case: the soft hyphen \-
is used to bring up a subtraction-like syntax, where the underlines extend only as far as the first ~
space command.
\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
We have to do some weird stuff because we don't know in any given cell whether we've only ended the cell, or ended the row. We test whether or not the final macro of the argument is \@gobble
: if so, it's merely an end-of-row, and so we ought to add another \@gobble
to make sure that the row doesn't actually end.
\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}%
}}
For the short subtractions used in long division, we do similar testing for ends of rows, but also define the end of the argument to be underlined by the first ~
character. We use \text{--}
in place of a proper minus sign to save space (it's not as long a stroke).
\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}
The \Into
command isn't an operator which the environment detects, but it similarly attempts to collect the remainder of the contents of the row, in order to draw an \overline
over it.
Supplement this pre-amble with the one of the above sample documents, and voilà!
\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}
If you don't need the annotations, I propose this solution:
\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}
The first optional argument is just the same as for the array
environment: [t]
or [b]
for vertical alignment (default is center alignment). The three mandatory arguments are the factors and the result, the trailing optional argument contains the list of intermediate summands.
Here's an implementation for the automatic computation given the factors; limitations: multiplying by 0 is not allowed (it could be taken care of) and the product can have at most 31 digits.
\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}
With some options more, through a key-value syntax:
\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}