宏中的宏参数数学

宏中的宏参数数学

是否可以获取宏的参数,并实际用它们进行数学运算?我需要计算“总计”以放入由宏构建的表中,即:

\documentclass[]{article}
\newcommand{\mytest}[3]{\
\textbf{Marking Grid}

Logic (50\%): #1 

Spelling (25\%): #2

Scholarly engagement (25\%): #3

Total: a*.5 + b*.25 + c*.25
 }

\begin{document}
\mytest{10}{20}{30}
\end{document}

答案1

这是一个简单的 expl3 解决方案:

网格

\documentclass[]{article}

\usepackage{expl3,xparse}

\ExplSyntaxOn
\NewDocumentCommand { \mytest } { m m m }
    {
        \textbf{Marking ~ Grid}\par 
        Logic ~ (50\%): ~ #1\par    
        Spelling ~ (25\%): ~ #2\par
        Scholarly ~ engagement ~ (25\%): ~#3\par
        Total: ~ \fp_eval:n{#1*.5 + #2*.25 + #3*.25}
    }
\ExplSyntaxOff
\begin{document}
\mytest{10}{20}{30}
\end{document}

答案2

还:

\documentclass{article}
\usepackage{xintexpr}

\newcommand{\mytest}[3]{%
\textbf{Marking Grid}

Logic (50\%): #1 

Spelling (25\%): #2

Scholarly engagement (25\%): #3

% [2] means to print with 2 digits after decimal mark
% Total: \xinttheiexpr [2] (#1)*.5 + (#2)*.25 + (#3)*.25\relax
% or, as xintexpr understands fractions:
Total: \xinttheiexpr [2] #1/2 + #2/4 + #3/4\relax
% (I hesitated using parentheses to allow #1, #2, #3 being expressions
% but they are used "naked" already above so I take they should be
% integers only)
}

\begin{document}
\mytest{10}{20}{30}
\end{document}

定义中间变量的替代方法,如果它发展的话,这对于提高源的可读性很有用。

\documentclass{article}
\usepackage{xintexpr}

\newcommand{\mytest}[3]{%
\textbf{Marking Grid}

\xintdefvar logic:= #1;%
Logic (50\%): \xinttheexpr logic\relax

\xintdefvar spelling:= #2;%
Spelling (25\%): \xinttheexpr spelling\relax

\xintdefvar schol_engag:= #3;%
Scholarly engagement (25\%): \xinttheexpr schol_engag\relax

Total: \xinttheiexpr [2] logic/2 + spelling/4 + schol_engag/4\relax
}

\begin{document}
\mytest{10}{20}{30}
\end{document}

在此处输入图片描述

答案3

下面的例子

  • 使用 e-TeX 进行计算
  • 并将条目格式化为表格形式。
\documentclass[]{article}
\usepackage{booktabs}
\usepackage{siunitx}

\makeatletter
\newcommand{\mytest}[3]{%
  \begin{tabular}{@{}l@{ }r@{}}
    \multicolumn{2}{@{}l@{}}{\textbf{Marking Grid}}\\
    Logic (\SI{50}{\percent}): & #1 \\
    Spelling (\SI{25}{\percent}): & #2 \\
    Scholarly engagement (\SI{25}{\percent}): & #3 \\
    Total: &
    \strip@pt\dimexpr
      .5\dimexpr(#1pt)\relax +
      .25\dimexpr(#2pt)\relax +
      .25\dimexpr(#3pt)\relax
    \relax
  \end{tabular}%
}
\newcommand{\mytesti}[3]{%
  \begin{tabular}{@{}l@{ }rr@{}}
    \multicolumn{3}{@{}l@{}}{\textbf{Marking Grid}}\\
    Logic: & #1 & (\SI{50}{\percent})\\
    Spelling: & #2 & (\SI{25}{\percent})\\
    Scholarly engagement: & #3 & (\SI{25}{\percent}) \\
    \cmidrule{2-2}
    Total: &
    \strip@pt\dimexpr
      .5\dimexpr(#1pt)\relax +
      .25\dimexpr(#2pt)\relax +
      .25\dimexpr(#3pt)\relax
    \relax
  \end{tabular}%
}
\makeatother

\begin{document}
  \noindent
  \mytest{10}{20}{30}

  \medskip
  \noindent
  \mytesti{9}{17}{31}
\end{document}

结果

小数点处自动对齐

下面的示例分析数字并计算整数和小数,并将计数传递table-format给包的列类型S的选项siunitx

\documentclass[]{article}
\usepackage{booktabs}
\usepackage{siunitx}

\makeatletter
\newcommand{\mytest}[3]{%
  \begingroup
    \edef\NumberA{\strip@pt\dimexpr(#1pt)\relax}%
    \edef\NumberB{\strip@pt\dimexpr(#2pt)\relax}%
    \edef\NumberC{\strip@pt\dimexpr(#3pt)\relax}%
    \edef\Total{%
      \strip@pt\dimexpr
        .5\dimexpr(#1pt)\relax +
        .25\dimexpr(#2pt)\relax +
        .25\dimexpr(#3pt)\relax
      \relax
    }%
    \edef\FiguresInteger{1}%
    \edef\FiguresDecimal{0}%
    \expandafter\mytest@measure\NumberA..\@nil
    \expandafter\mytest@measure\NumberB..\@nil
    \expandafter\mytest@measure\NumberC..\@nil
    \expandafter\mytest@measure\Total..\@nil
    \begin{tabular}{@{}lS[table-format=\FiguresInteger.\FiguresDecimal]r@{}}
      \multicolumn{3}{@{}l@{}}{\textbf{Marking Grid}}\\
      Logic: & \NumberA & (\SI{50}{\percent})\\
      Spelling: & \NumberB & (\SI{25}{\percent})\\
      Scholarly engagement: & \NumberC & (\SI{25}{\percent}) \\
      \cmidrule(lr){2-2}
      Total: & \Total & \\
    \end{tabular}%
  \endgroup
}
\def\mytest@measure#1.#2.#3\@nil{%
  % Count digits before decimal marker
  \edef\tmp{\the\numexpr-1+\mytest@count0#1\relax}%
  \ifnum\tmp>\FiguresInteger\relax
    \let\FiguresInteger\tmp
  \fi
  % Count digits after decimal marker
  \edef\tmp{\the\numexpr-1+\mytest@count0#2\relax}%
  \ifnum\tmp>\FiguresDecimal\relax
    \let\FiguresDecimal\tmp
  \fi
}
\def\mytest@count#1{%
  \ifx#1\relax
  \else
    +1%
    \expandafter\mytest@count
  \fi
}
\makeatother

\begin{document}
  \noindent
  \mytest{10}{20}{30}

  \medskip
  \noindent
  \mytest{9.5}{23}{31.25}
\end{document}

结果与小数点对齐

相关内容