我想使用以下样式排版具有两个以上操作数的加法和减法。
该图像是使用以下(相当丑陋的)代码生成的。
\documentclass{article}
\begin{document}
\begin{math}
\setlength{\arraycolsep}{0.5pt}
\begin{array}{cccccc}
& 1 & 9 & 2 \\
+ & & 2 & 7 \\
+ & & 3 & 1 \\[-1ex]
& _1 & _1 & \\ \hline
& 2 & 5 & 0
\end{array}
\end{math}
\end{document}
是否可以延长脫位以这种方式打包?还有其他可以轻松生成所需结果的包吗?
答案1
虽然不太容易,但可以做到。
\documentclass{article}
\usepackage{xparse,booktabs}
\ExplSyntaxOn
\NewDocumentCommand{\summation}{m}
{
\group_begin:
\setlength{\arraycolsep}{1pt}
\renewcommand{\arraystretch}{0}
\matthias_summation:n { #1 }
\group_end:
}
\int_new:N \l__matthias_summation_order_int
\seq_new:N \l__matthias_summation_items_seq
\seq_new:N \l__matthias_summation_items_pad_seq
\seq_new:N \l__matthias_summation_carries_seq
\seq_new:N \l__matthias_summation_digits_seq
\bool_new:N \g__matthias_summation_plus_bool
\cs_generate_variant:Nn \tl_map_function:nN { e }
\cs_new_protected:Nn \matthias_summation:n
{
\bool_gset_false:N \g__matthias_summation_plus_bool
\seq_set_split:Nnn \l__matthias_summation_items_seq { + } { #1 }
\int_zero:N \l__matthias_summation_order_int
% determine the number of digits
\seq_map_inline:Nn \l__matthias_summation_items_seq
{
\int_set:Nn \l__matthias_summation_order_int
{
\int_max:nn { \l__matthias_summation_order_int } { \tl_count:n { ##1 } }
}
}
% pad the numbers
\seq_set_map:NNn \l__matthias_summation_items_pad_seq \l__matthias_summation_items_seq
{
\prg_replicate:nn { \l__matthias_summation_order_int - \tl_count:n { ##1 } } { 0 } ##1
}
% compute the carries
\seq_clear:N \l__matthias_summation_carries_seq
\seq_put_left:Nn \l__matthias_summation_carries_seq { 0 }
\int_step_inline:nnn { 1 } { \l__matthias_summation_order_int }
{
\seq_clear:N \l__matthias_summation_digits_seq
\seq_map_inline:Nn \l__matthias_summation_items_pad_seq
{
\seq_put_right:Nx \l__matthias_summation_digits_seq { \tl_item:nn { ####1 } { -##1 } }
}
\seq_put_left:Nx \l__matthias_summation_carries_seq
{
\int_eval:n
{
\int_div_truncate:nn
{
\seq_use:Nn \l__matthias_summation_digits_seq { + }
+ \seq_item:Nn \l__matthias_summation_carries_seq { -##1 }
}
{ 10 }
}
}
}
\str_if_eq:eeTF { \seq_item:Nn \l__matthias_summation_carries_seq { 1 } } { 0 }
{% if the leftmost carry is 0, remove it
\seq_pop_left:NN \l__matthias_summation_carries_seq \l_tmpa_tl
}
{% otherwise increase the number of columns
\int_incr:N \l__matthias_summation_order_int
}
% pad again the numbers, but with blanks
\seq_set_map:NNn \l__matthias_summation_items_pad_seq \l__matthias_summation_items_seq
{
\prg_replicate:nn { \l__matthias_summation_order_int - \tl_count:n { ##1 } } { {} } ##1
}
\begin{array}{@{} c *{\l__matthias_summation_order_int}{c} @{}}
\seq_map_function:NN \l__matthias_summation_items_pad_seq \__matthias_summation_row:n
\seq_map_function:NN \l__matthias_summation_carries_seq \__matthias_summation_carry:n \\
\midrule
\tl_map_function:eN
{
\int_eval:n
{
\seq_use:Nn \l__matthias_summation_items_seq { + }
}
}
\__matthias_summation_total:n
\end{array}
}
\cs_new_protected:Nn \__matthias_summation_row:n
{
\bool_if:NTF \g__matthias_summation_plus_bool
{ + }
{ \bool_gset_true:N \g__matthias_summation_plus_bool }
\tl_map_function:nN { #1 } \__matthias_summation_number:n
\\[1ex]
}
\cs_new_protected:Nn \__matthias_summation_number:n { & #1 }
\cs_new_protected:Nn \__matthias_summation_carry:n
{
& \str_if_eq:nnF { #1 } { 0 } { \scriptstyle #1 }
}
\cs_new_protected:Nn \__matthias_summation_total:n { & #1 }
\ExplSyntaxOff
\begin{document}
\[
\summation{192+27+31}\qquad \summation{92+27+31} \qquad
\summation{99+99+99}
\]
\end{document}
我留下一个练习,如果没有进位,如何删除该行。它实际上也不支持大于 9 的进位。