\documentclass{article}
\usepackage{xintexpr}[2018/05/18]% because we use randrange()
\newcommand{\BaseTenAddition}{%
% temporarily make definitions have global scope, because
% xint creation of variable is scope obedient and is lacking
% user interface for global scope (should be added in future)
\globaldefs1
%
% no need to reset \globaldefs afterwards explicitely
% as its setting will be extinguished after first cell...
%
%% create 2 integer-valued random numbers, <1000
\xintdefiivar num1 := randrange(1000);%
\xintdefiivar num2 := randrange(1000);%
%
%
%% Get base10 elements of num1 and num2
\xintdefiivar num1_1 := num1 /: 10;% /: is modulo operator
\xintdefiivar num1_10 := num1 /: 100 - num1_1;%
\xintdefiivar num1_100 := num1 - num1_10 - num1_1;%
\xintdefiivar num1_1000 := 0 ;%
\xintdefiivar num2_1 := num2 /: 10;%
\xintdefiivar num2_10 := num2 /: 100 - num2_1;%
\xintdefiivar num2_100 := num2 - num2_10 - num2_1;%
\xintdefiivar num2_1000 := 0 ;%
%
%
%% show the two numbers and their base-10 reps
&\xinttheiiexpr num1\relax
&=&\xinttheiiexpr num1_1000\relax
&+&\xinttheiiexpr num1_100\relax
&+&\xinttheiiexpr num1_10\relax
&+&\xinttheiiexpr num1_1\relax\\
&\xinttheiiexpr num2\relax
&=&\xinttheiiexpr num2_1000\relax
&+&\xinttheiiexpr num2_100\relax
&+&\xinttheiiexpr num2_10\relax
&+&\xinttheiiexpr num2_1\relax\\
\cmidrule(l){9-10}
+\\ \addlinespace
%
%
%% check if overflow in 1s column
\globaldefs1
\xintdefiivar num2_1:=num1_1+num2_1;%
\xintifbooliiexpr{num2_1 > 9}
{\xintdefiivar num2_1 := num2_1-10;%
\xintdefiivar carry := 10;%
&\mbox{}&&&&&+&10\\
}
{\xintdefiivar carry := 0;}%
&&&\xinttheiiexpr num1_1000\relax
&+&\xinttheiiexpr num1_100\relax
&+&\xinttheiiexpr num1_10\relax
\\
&&&\xinttheiiexpr num2_1000\relax
&+&\xinttheiiexpr num2_100\relax
&+&\xinttheiiexpr num2_10\relax
&+&\xinttheiiexpr num2_1\relax
\\
\cmidrule(lr){7-8}
+\\ \addlinespace
%
%
%% check if overflow in 10s column
\globaldefs1
\xintdefiivar num2_10:=num1_10+num2_10+carry;%
\xintifbooliiexpr{num2_10 > 90}
{\xintdefiivar num2_10 := num2_10-100;%
\xintdefiivar carry := 100;%
&\mbox{}&&& + &100\\
}
{\xintdefiivar carry := 0;}%
&&&\xinttheiiexpr num1_1000\relax
&+&\xinttheiiexpr num1_100\relax\\
&&&\xinttheiiexpr num2_1000\relax
&+&\xinttheiiexpr num2_100\relax
&+&\xinttheiiexpr num2_10\relax
&+&\xinttheiiexpr num2_1\relax\\
\cmidrule(lr){5-6}
+\\ \addlinespace
%
%
%% check if overflow in 100s column
\globaldefs1
\xintdefiivar num2_100:=num1_100+num2_100+carry;%
\xintifbooliiexpr{num2_100 > 900}
{\xintdefiivar num2_100 := num2_100-1000;%
\xintdefiivar carry := 1000;%
&\mbox{}&& 1000 \\
}
{\xintdefiivar carry := 0;}%
\xintifbooliiexpr{carry>0}{&&&}{&&=&}%
\xinttheiiexpr num2_1000\relax
&+&\xinttheiiexpr num2_100\relax
&+&\xinttheiiexpr num2_10\relax
&+&\xinttheiiexpr num2_1\relax
\\
\xintifbooliiexpr{carry > 0}
{\cmidrule(lr){4-4}+\\}
{\midrule}%
%
%% print the final base-10 rep
\globaldefs1
\xintifbooliiexpr{carry>0}
{\xintdefiivar num2_1000:=num2_1000+carry;%
&&=&\xinttheiiexpr num2_1000\relax
&+&\xinttheiiexpr num2_100\relax
&+&\xinttheiiexpr num2_10\relax
&+&\xinttheiiexpr num2_1\relax
\\
\midrule}
{}% no false branch
%
%
%% print the final result
=&\xinttheiiexpr num1+num2\relax
}
\usepackage{array,booktabs}
\newlength\mylen
\settowidth\mylen{} % define width of 2nd col.
\begin{document}
\[
\begin{array}{@{} l w{r}{\mylen} *{4}{cr} @{}}
&&&1000\mbox{s}&\star& 100\mbox{s}&\star & 10\mbox{s}& \star &1\mbox{s}\\
\midrule
\BaseTenAddition % the xintexpr-based macro does almost all the work
\end{array}
\]
Again
\[
\begin{array}{@{} l w{r}{\mylen} *{4}{cr} @{}}
&&&1000\mbox{s}&\star& 100\mbox{s}&\star & 10\mbox{s}& \star &1\mbox{s}\\
\midrule
\BaseTenAddition % the xintexpr-based macro does almost all the work
\end{array}
\]
\thispagestyle{empty}
\end{document}
很抱歉我没有说清楚(因为这个问题被删除了),但这是使用十的幂来显示加法的代码,我希望它对减法也能做同样的事情。我需要重新编码所有内容吗?还是我可以只改变一些东西?我知道数组和随机数可以工作,但我只知道我是否可以将其从加法改为减法。
答案1
将 some 改为+
,-
some-
改为+
,some >9
,,改为,>90
并添加一些空格以允许出现负数结果。>900
< 0
\documentclass{article}
\usepackage{xintexpr}[2018/05/18]% because we use randrange()
\newcommand{\BaseTenAddition}{%
% temporarily make definitions have global scope, because
% xint creation of variable is scope obedient and is lacking
% user interface for global scope (should be added in future)
\globaldefs1
%
% no need to reset \globaldefs afterwards explicitely
% as its setting will be extinguished after first cell...
%
%% create 2 integer-valued random numbers, <1000
\xintdefiivar num1 := randrange(1000);%
\xintdefiivar num2 := randrange(1000);%
%
%
%% Get base10 elements of num1 and num2
\xintdefiivar num1_1 := num1 /: 10;% /: is modulo operator
\xintdefiivar num1_10 := num1 /: 100 - num1_1;%
\xintdefiivar num1_100 := num1 - num1_10 - num1_1;%
\xintdefiivar num1_1000 := 0 ;%
\xintdefiivar num2_1 := num2 /: 10;%
\xintdefiivar num2_10 := num2 /: 100 - num2_1;%
\xintdefiivar num2_100 := num2 - num2_10 - num2_1;%
\xintdefiivar num2_1000 := 0 ;%
%
%
%% show the two numbers and their base-10 reps
&\xinttheiiexpr num1\relax
&=&\xinttheiiexpr num1_1000\relax
&+&\xinttheiiexpr num1_100\relax
&+&\xinttheiiexpr num1_10\relax
&+&\xinttheiiexpr num1_1\relax\\
&\xinttheiiexpr num2\relax
&=&\xinttheiiexpr num2_1000\relax
&+&\xinttheiiexpr num2_100\relax
&+&\xinttheiiexpr num2_10\relax
&+&\xinttheiiexpr num2_1\relax\\
\cmidrule(l){9-10}
-\\ \addlinespace
%
%
%% check if overflow in 1s column
\globaldefs1
\xintdefiivar num2_1:=num1_1-num2_1;%
\xintifbooliiexpr{num2_1 < 0}
{\xintdefiivar num2_1 := num2_1+10;%
\xintdefiivar carry := -10;%
&\mbox{}&&&&&-&10\\
}
{\xintdefiivar carry := 0;}%
&&&\xinttheiiexpr num1_1000\relax
&+&\xinttheiiexpr num1_100\relax
&+&\xinttheiiexpr num1_10\relax
\\
&&&\xinttheiiexpr num2_1000\relax
&+&\xinttheiiexpr num2_100\relax
&+&\xinttheiiexpr num2_10\relax
&+&\xinttheiiexpr num2_1\relax
\\
\cmidrule(lr){7-8}
-\\ \addlinespace
%
%
%% check if overflow in 10s column
\globaldefs1
\xintdefiivar num2_10:=num1_10-num2_10+carry;%
\xintifbooliiexpr{num2_10 < 0}
{\xintdefiivar num2_10 := num2_10+100;%
\xintdefiivar carry := -100;%
&\mbox{}&&& - &100\\
}
{\xintdefiivar carry := 0;}%
&&&\xinttheiiexpr num1_1000\relax
&+&\xinttheiiexpr num1_100\relax\\
&&&\xinttheiiexpr num2_1000\relax
&+&\xinttheiiexpr num2_100\relax
&+&\xinttheiiexpr num2_10\relax
&+&\xinttheiiexpr num2_1\relax\\
\cmidrule(lr){5-6}
-\\ \addlinespace
%
%
%% check if overflow in 100s column
\globaldefs1
\xintdefiivar num2_100:=num1_100-num2_100+carry;%
\xintifbooliiexpr{num2_100 < 0}
{\xintdefiivar num2_100 := num2_100+1000;%
\xintdefiivar carry := -1000;%
&\mbox{}&& -1000 \\
}
{\xintdefiivar carry := 0;}%
\xintifbooliiexpr{carry>0}{&&&}{&&=&}%
\xinttheiiexpr num2_1000\relax
&+&\xinttheiiexpr num2_100\relax
&+&\xinttheiiexpr num2_10\relax
&+&\xinttheiiexpr num2_1\relax
\\
\xintifbooliiexpr{carry > 0}
{\cmidrule(lr){4-4}+\\}
{\midrule}%
%
%% print the final base-10 rep
\globaldefs1
\xintifbooliiexpr{carry>0}
{\xintdefiivar num2_1000:=num2_1000+carry;%
&&=&\xinttheiiexpr num2_1000\relax
&+&\xinttheiiexpr num2_100\relax
&+&\xinttheiiexpr num2_10\relax
&+&\xinttheiiexpr num2_1\relax
\\
\midrule}
{}% no false branch
%
%
%% print the final result
=~~~&\xinttheiiexpr num1-num2\relax
}
\usepackage{array,booktabs}
\newlength\mylen
\settowidth\mylen{} % define width of 2nd col.
\begin{document}
\[
\begin{array}{@{} l w{r}{\mylen} *{4}{cr} @{}}
&&&1000\mbox{s}&\star& 100\mbox{s}&\star & 10\mbox{s}& \star &1\mbox{s}\\
\midrule
\BaseTenAddition % the xintexpr-based macro does almost all the work
\end{array}
\]
Again
\[
\begin{array}{@{} l w{r}{\mylen} *{4}{cr} @{}}
&&&1000\mbox{s}&\star& 100\mbox{s}&\star & 10\mbox{s}& \star &1\mbox{s}\\
\midrule
\BaseTenAddition % the xintexpr-based macro does almost all the work
\end{array}
\]
\thispagestyle{empty}
\end{document}