LaTeX 中的铅笔和纸张减法

LaTeX 中的铅笔和纸张减法

有没有办法在 LaTeX 中格式化减法,就像你手工计算一样?(见附图)。顺便说一下,1)和 2)不必包括在内。

在此处输入图片描述

答案1

原帖的标题写着减法,但他/她的图片显示的是加法。我最初选择后者,但后来编辑成也执行减法。在附录,我已经开始实现小数的过程,此时为2位数加法。

减法

如果有人愿意这样称呼它的话,一个已知的缺陷就是差异将显示前导零。

使用\showdiff{<minuend>}{<subtrahend>}

这种方法使用我的stringstrings包从被减数和减数中一次提取一列,从右边开始(stringstrings使用 功能可以方便地$表示字符串结尾字符的位置)。它会减去它们,但如果值为负,它会执行借位。如果被减数的值\borrowed小于零,它会将其增加到 9 并设置一个\futureborrowed标志以应用于下一列。然后,它会构造并保存\Longstack这些列数字中的一个(包括借入或借出数字的任何数量),名称为\thediff

\savediff然后,通过将最新的添加\thediff到现有的前面,构建 中和的全局图景\savediff。它丢弃每个加数的最后一位数字(使用\nextcolumn),然后它递归返回并再次执行此操作。当它确定截断的被减数和​​减数都为零时,它会在 前面添加一个减号\savediff并显示它。

\documentclass{article}
\usepackage{stringstrings,stackengine}
\newcommand\showdiff[2]{%
  \let\savediff\relax%
  \def\borrow{}%
  \xdef\borrowed{0}%
  \ifnum#1>32\relax\showdiffengine{#1}{#2}\else
    {\ttfamily\Longstack[r]{#1\,{} \underline{-#2\,} {< 0\,}}}\fi
}
\newcommand\showdiffengine[2]{%
  \xdef\opA{#1}%
  \xdef\opB{#2}%
  \lastdigits{\opA}{\opB}%
  \ifnum\borrowed=1\relax\xdef\XdigA{\the\numexpr\digA-1}\else\xdef\XdigA{\digA}\fi%
  \ifnum\XdigA<0\relax\xdef\XdigA{9}\xdef\futureborrowed{1}\else
    \xdef\futureborrowed{0}\fi
  \edef\coldiff{\the\numexpr\XdigA-\digB\relax}%
  \ifnum\coldiff<0\relax%
    \xdef\borrow{1}%
    \edef\coldiff{\the\numexpr\borrow\XdigA-\digB\relax}%
  \else
    \xdef\borrow{}%
  \fi
  \ifnum\borrowed=0\relax%
    \savestack{\thediff}{\ttfamily\Longstack[l]{%
      \tiny\bllap[1.5\baselineskip]{\borrow} \XdigA{} \underline{\VdigB\kern3pt} %
        \coldiff}}%
  \else
    \savestack{\thediff}{\ttfamily\Longstack[l]{%
     \tiny\brlap[.7\baselineskip]{\borrow\the\numexpr\XdigA} \crossout{\digA} %
        \underline{\VdigB\kern3pt} \coldiff}}%
  \fi
  \if\relax\borrow\relax\xdef\borrowed{0}\else\xdef\borrowed{1}\fi
  \savestack{\savediff}{\thediff\savediff}%
  \ifnum\futureborrowed>0\relax\xdef\borrowed{1}\xdef\fugureborrowed{0}\fi
  \nextcolumn{\opA}{\opB}%
  \ifnum\numexpr0\opA+0\opB>0\relax\showdiffengine{\opA}{\opB}%
  \else
    \Longstack{\underline{\ttfamily-\,} {}}\savediff\fi%
}
\newcommand\crossout[1]{\stackengine{0pt}{#1}{/}{O}{c}{F}{F}{L}}
\newcommand\lastdigits[2]{%
  \substring[q]{#1}{$}{$}%
  \xdef\digA{\thestring}%
  \xdef\VdigA{\digA}\if0\digA\ifnum#1=0\relax\xdef\VdigA{~}\fi\fi%
  \substring[q]{#2}{$}{$}%
  \xdef\digB{\thestring}%
  \xdef\VdigB{\digB}\if0\digB\ifnum#2=0\relax\xdef\VdigB{~}\fi\fi%
}
\newcommand\nextcolumn[2]{%
  \substring[q]{#1}{1}{$-1}%
  \xdef\opA{0\thestring}%
  \substring[q]{#2}{1}{$-1}%
  \xdef\opB{0\thestring}%
}
\begin{document}
\showdiff{567}{243}\qquad
\showdiff{37}{9}\qquad
\showdiff{135}{49}\qquad
\showdiff{2134}{49}\bigskip

\showdiff{107}{23}\qquad
\showdiff{100}{1}\qquad
\showdiff{1000}{999}\qquad
\showdiff{10}{70}\qquad\bigskip
\end{document}

在此处输入图片描述

2 学期加法

使用\showsum{<addend-1>}{<addend-2>}

此方法还会从每个加数中一次提取一列,从右侧开始。它将这些加数相加,提取总和的最右边的数字,并保存余数。然后,它构建并保存\Longstack这些列数字(包括任何先前的余数)的 ,名称为\thesum

\savesum然后,通过将最新的添加\thesum到现有的前面,构建 中和的全局图景\savesum。它丢弃每个加数的最后一位数字(使用\nextcolumn),然后它递归返回并再次执行此操作。当它确定余数和截断的加数都为零时,它会在 前面添加一个加号\savesum并显示它。

(注意:这里的宏\nextcolumn\lastdigits宏与上面减法代码中使用的宏相同)

\documentclass{article}
\usepackage{stringstrings,stackengine}
\newcommand\showsum[2]{%
  \xdef\remainder{0}%
  \xdef\Vremainder{~}%
  \let\savesum\relax%
  \showsumengine{#1}{#2}%
}
\newcommand\showsumengine[2]{%
  \xdef\opA{#1}%
  \xdef\opB{#2}%
  \lastdigits{\opA}{\opB}%
  \edef\colsum{\the\numexpr\digA+\digB+0\remainder\relax}%
  \substring[q]{\colsum}{$}{$}%
  \savestack{\thesum}{\ttfamily\Longstack[l]{%
    \tiny\brlap[.7\baselineskip]{\Vremainder} \VdigA{} \underline{\VdigB\,} \thestring}}%
  \substring[q]{\colsum}{1}{$-1}%
  \xdef\remainder{\thestring}%
  \if\relax\remainder\relax\xdef\Vremainder{}\else\xdef\Vremainder{\remainder}\fi%
  \savestack{\savesum}{\thesum\savesum}%
  \nextcolumn{\opA}{\opB}%
  \ifnum\numexpr0\opA+0\opB+0\remainder>0\relax\showsumengine{\opA}{\opB}\else
    \Longstack{\underline{\ttfamily+\,} {}}\savesum\fi%
}
\newcommand\lastdigits[2]{%
  \substring[q]{#1}{$}{$}%
  \xdef\digA{\thestring}%
  \xdef\VdigA{\digA}\if0\digA\ifnum#1=0\relax\xdef\VdigA{~}\fi\fi%
  \substring[q]{#2}{$}{$}%
  \xdef\digB{\thestring}%
  \xdef\VdigB{\digB}\if0\digB\ifnum#2=0\relax\xdef\VdigB{~}\fi\fi%
}
\newcommand\nextcolumn[2]{%
  \substring[q]{#1}{1}{$-1}%
  \xdef\opA{0\thestring}%
  \substring[q]{#2}{1}{$-1}%
  \xdef\opB{0\thestring}%
}
\begin{document}
\showsum{14}{7}\qquad
\showsum{56}{98}\qquad
\showsum{9236}{895}\qquad
\showsum{9236}{825}\bigskip

\showsum{9236}{455}\qquad
\showsum{98669}{985}\qquad
\showsum{98069}{905}
\end{document}

在此处输入图片描述

有 3 个加数的版本

使用大写“S”,\Showsum{<addend-1>}{<addend-2>}{<addend-3>}

\documentclass{article}
\usepackage{stringstrings,stackengine}
\newcommand\Showsum[3]{%
  \xdef\remainder{0}%
  \xdef\Vremainder{~}%
  \let\savesum\relax%
  \Showsumengine{#1}{#2}{#3}%
}
\newcommand\Showsumengine[3]{%
  \xdef\opA{#1}%
  \xdef\opB{#2}%
  \xdef\opC{#3}%
  \Lastdigits{\opA}{\opB}{\opC}%
  \edef\colsum{\the\numexpr\digA+\digB+\digC+0\remainder\relax}%
  \substring[q]{\colsum}{$}{$}%
  \savestack{\thesum}{\ttfamily\Longstack[l]{%
    \tiny\brlap[.7\baselineskip]{\Vremainder} \VdigA{} \VdigB{} \underline{\VdigC\,} %
      \thestring}}%
  \substring[q]{\colsum}{1}{$-1}%
  \xdef\remainder{\thestring}%
  \if\relax\remainder\relax\xdef\Vremainder{}\else\xdef\Vremainder{\remainder}\fi%
  \savestack{\savesum}{\thesum\savesum}%
  \Nextcolumn{\opA}{\opB}{\opC}%
  \ifnum\numexpr0\opA+0\opB+0\opC+0\remainder>0\relax%
    \Showsumengine{\opA}{\opB}{\opC}\else
    \Longstack{\underline{\ttfamily+\,} {}}\savesum\fi%
}
\newcommand\Lastdigits[3]{%
  \substring[q]{#1}{$}{$}%
  \xdef\digA{\thestring}%
  \xdef\VdigA{\digA}\if0\digA\ifnum#1=0\relax\xdef\VdigA{~}\fi\fi%
  \substring[q]{#2}{$}{$}%
  \xdef\digB{\thestring}%
  \xdef\VdigB{\digB}\if0\digB\ifnum#2=0\relax\xdef\VdigB{~}\fi\fi%
  \substring[q]{#3}{$}{$}%
  \xdef\digC{\thestring}%
  \xdef\VdigC{\digC}\if0\digC\ifnum#3=0\relax\xdef\VdigC{~}\fi\fi%
}
\newcommand\Nextcolumn[3]{%
  \substring[q]{#1}{1}{$-1}%
  \xdef\opA{0\thestring}%
  \substring[q]{#2}{1}{$-1}%
  \xdef\opB{0\thestring}%
  \substring[q]{#3}{1}{$-1}%
  \xdef\opC{0\thestring}%
}
\begin{document}
\Showsum{16}{7}{39}\qquad
\Showsum{898}{7}{439}\qquad
\Showsum{898032}{70405}{40309}\qquad
\Showsum{7040}{898032}{4030}
\end{document}

在此处输入图片描述

附录

以下是自动处理小数或整数的 2 位数加法:

\documentclass{article}
\usepackage{stringstrings,stackengine}
%%%%%% stringstrings BUG FIX (MISSING %)
\makeatletter
\renewcommand\testmatchingchar[3]{%
  \setbox0=\hbox{%
  \substring[e]{#1}{#2}{#2}\+%
  \isnextbyte[q]{\EscapeChar}{#3}%
  \if T\theresult%
    \isnextbyte[q]{\EscapeChar}{\thestring}%
    \if T\theresult%
      \edef\@testcode{\expandafter\@DiscardNextChar\expandafter{#3}}%
      \edef\@teststring{\@DiscardNextChar{\thestring}}%
      \if \@teststring\@testcode\matchingchartrue\else\matchingcharfalse\fi
    \else
      \global\matchingcharfalse%
    \fi
  \else
    \if \thestring#3\global\matchingchartrue\else\global\matchingcharfalse\fi
  \fi}%
\?}
\makeatother
%%%%%
\edef\decchar{.}
\newcounter{digits}
\newcounter{decrements}
\newcommand\showsum[2]{%
  \setcounter{digits}{0}%
  \xdef\remainder{0}%
  \xdef\Vremainder{~}%
  \let\savesum\relax%
  \whereischar[q]{#1}{\decchar}%
  \xdef\locA{\theresult}%
  \whereischar[q]{#2}{\decchar}%
  \xdef\locB{\theresult}%
  \ifnum\numexpr\locA+\locB=0\relax%
    \def\decloc{-1}%
    \showsumengine{#1}{#2}%
  \else
    \ifnum\locA=0\relax%
      \xdef\numA{#1\decchar}%
      \whereischar[q]{\numA}{\decchar}%
      \xdef\locA{\theresult}%
    \else
      \xdef\numA{#1}%
    \fi
    \stringlength[q]{\numA}%
    \xdef\lenA{\theresult}%
    \substring[q]{\numA}{1}{\numexpr\locA-1\relax}%
    \xdef\preA{\thestring}%
    \substring[q]{\numA}{\numexpr\locA+1\relax}{$}%
    \xdef\postA{\thestring}%
    \ifnum\locB=0\relax%
      \xdef\numB{#2\decchar}%
      \whereischar[q]{\numB}{\decchar}%
      \xdef\locB{\theresult}%
    \else
      \xdef\numB{#2}%
    \fi
    \stringlength[q]{\numB}%
    \xdef\lenB{\theresult}%
    \substring[q]{\numB}{1}{\numexpr\locB-1\relax}%
    \xdef\preB{\thestring}%
    \substring[q]{\numB}{\numexpr\locB+1\relax}{$}%
    \xdef\postB{\thestring}%
    \def\decsA{\numexpr\lenA-\locA}%
    \def\decsB{\numexpr\lenB-\locB}%
    \ifnum\decsA=\decsB%
    \xdef\decloc{\decsA}%
    \else\ifnum\decsA>\decsB%
        \xdef\decloc{\decsA}%
        \setcounter{decrements}{\the\numexpr\decsA-\decsB}%
        \paddecimal{\postB}%
      \else%
        \xdef\decloc{\decsB}%
        \setcounter{decrements}{\the\numexpr\decsB-\decsA}%
        \paddecimal{\postA}%
      \fi%
    \fi%
    \showsumengine{\preA\postA}{\preB\postB}%
  \fi%
}
\newcommand\paddecimal[1]{%
  \xdef#1{#1 }%
  \addtocounter{decrements}{-1}%
  \ifnum\value{decrements}>0\relax\paddecimal{#1}\fi%
}
\newcommand\showsumengine[2]{%
  \ifnum\value{digits}=\decloc\relax\savestack\savesum{%
    \Longstack{. \underline{.} .}\savesum}\fi
  \stepcounter{digits}%
  \xdef\opA{#1}%
  \xdef\opB{#2}%
  \lastdigits{\opA}{\opB}%
  \edef\colsum{\the\numexpr\digA+\digB+0\remainder\relax}%
  \substring[q]{\colsum}{$}{$}%
  \savestack{\thesum}{\ttfamily\Longstack[l]{%
    \tiny\brlap[.7\baselineskip]{\Vremainder} \VdigA{} \underline{\VdigB\,} \thestring}}%
  \substring[q]{\colsum}{1}{$-1}%
  \xdef\remainder{\thestring}%
  \if\relax\remainder\relax\xdef\Vremainder{}\else\xdef\Vremainder{\remainder}\fi%
  \savestack{\savesum}{\thesum\savesum}%
  \nextcolumn{\opA}{\opB}%
  \ifnum\numexpr0\opA+0\opB+0\remainder>0\relax\showsumengine{\opA}{\opB}\else
    \Longstack{\underline{\ttfamily+\,} {}}\savesum\fi%
}
\newcommand\lastdigits[2]{%
  \substring[q]{#1}{$}{$}%
  \xdef\digA{\thestring}%
  \xdef\VdigA{\digA}\if0\digA\ifnum#1=0\relax\xdef\VdigA{~}\fi\fi%
  \substring[q]{#2}{$}{$}%
  \xdef\digB{\thestring}%
  \xdef\VdigB{\digB}\if0\digB\ifnum#2=0\relax\xdef\VdigB{~}\fi\fi%
}
\newcommand\nextcolumn[2]{%
  \substring[q]{#1}{1}{$-1}%
  \xdef\opA{0\thestring}%
  \substring[q]{#2}{1}{$-1}%
  \xdef\opB{0\thestring}%
  \if.\thestring\nextcolumn{\opA}{\opB}\fi%
}
\begin{document}
\showsum{14}{7}\qquad
\showsum{56}{98}\qquad
\showsum{9236}{895}\qquad
\showsum{9236}{825}\bigskip

\showsum{9236}{455}\qquad
\showsum{98669}{985}\qquad
\showsum{98069}{905}\bigskip

\showsum{1.}{3.}\qquad
\showsum{1}{3.96}\qquad
\showsum{.2}{.94}\qquad
\showsum{121.24}{39.7}\qquad
\showsum{94.8}{121.2479}
\end{document}

在此处输入图片描述

附言:我感觉有个包裹正在过来……

答案2

您可以使用脫位包裹

\documentclass[border=5pt,tikz]{article}

\usepackage{xlop}

\begin{document}

\opadd{485,05}{178,4}


\opsub{245.25}{72.003}

\opsub[style=text]{72}{245}

\opsub[carrysub,lastcarry]{72}{245}

\end{document}

在此处输入图片描述

相关内容