算术运算

算术运算

我想使用以下样式排版具有两个以上操作数的加法和减法。

期望结果

该图像是使用以下(相当丑陋的)代码生成的。

\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 的进位。

相关内容