解析简单算术并返回结果

解析简单算术并返回结果

我想要一个命令\ca,它以简单的算术计算作为参数,并返回带有正确小数位的结果。此外,我想要一个布尔参数,它决定是只打印结果还是打印整个计算。

例如

\ca{8.12 - 2.2 + 1}

应该只打印 6.92。

或者

\ca[t]{8.12 - 2.2 + 1}

应该打印 8.12 - 2.2 + 1 = 6.92

问题如何将两个值相加并将结果存储在其他变量中?我这样做了:

\documentclass{article}
\usepackage[nomessages]{fp}% http://ctan.org/pkg/fp
\usepackage{ifthen}

\newcommand{\ca}[2][f]{
\FPeval{\result}{clip(#2)}
\ifthenelse{\equal{#1}{t}}{
$#2=  \result$}
{
\result
}
}



\begin{document}
\ca[t]{3*(2.2 + 2.3)}

\ca{2.5 + 2.78}
\end{document}

是否可以达到相同的效果,使得在显示的内容中使用德语逗号表示法(即 8,2 而不是 8.2),并且在打印计算结果的情况下将 * 打印为\dcot

答案1

以下是使用以下粗略方法将输出修改为特定于\cdot和的,xstring. 使用的原因xstring是因为fp#2否则,必须对( ) 进行解析,并将其分离为运算符和操作数,才能numprint用法(说)。

在此处输入图片描述

\documentclass{article}
\usepackage[nomessages]{fp}% http://ctan.org/pkg/fp
\usepackage{xstring}% http://ctan.org/pkg/xstring
\usepackage{xparse}% http://ctan.org/pkg/xparse

\NewDocumentCommand{\ca}{s m}{
  \FPeval{\result}{clip(#2)}
  \IfBooleanTF{#1}% Condition on starred/unstarred version
    {% starred version \ca*{...}
      \StrSubstitute{\result}{.}{,}
    }{% unstarred version \ca{...}
      \StrSubstitute{#2}{.}{,\!}[\temp]% '.' -> ','
      \StrSubstitute{\temp}{*}{\cdot}[\temp]% '*' -> '\cdot'
      $\temp=\StrSubstitute{\result}{.}{,\!}$
    }
}

\begin{document}
\ca{3*(2.2 + 2.3)}

\ca*{2.5 + 2.78}
\end{document}​

xparse用于提供带星号/无星号版本,\ca其中无星号版本\ca打印表达式,而带星号版本\ca*则不打印。

答案2

我认为你的意思\cdot不是\dot。在这种情况下,你可以使用:

\documentclass{article}
\usepackage[nomessages]{fp}% http://ctan.org/pkg/fp
\usepackage{ifthen}

\begingroup
\catcode`\.=\active
\catcode`\*=\active
\newcommand{\germannotation}[1]{%
  \begingroup
    \catcode`\.=\active
    \def.{{,}}%
    \catcode`\*=\active
    \def*{\cdot}%
    \scantokens{#1}%
  \endgroup
}
\global\let\germannotation\germannotation
\endgroup

\newcommand{\ca}[2][f]{%
  \FPeval{\result}{clip(#2)}%
  \edef\result{\noexpand\germannotation{\result}}%
  \ifthenelse{\equal{#1}{t}}{%
    $\germannotation{#2}=\result$%
  }{%
    \result
  }%
}

\begin{document}
\ca[t]{3*(2.2 + 2.3)}

\ca{2.5 + 2.78}
\end{document}

答案3

这是一个用于数学计算的版本pgf,它允许更复杂的数学表达式(例如tan(deg(pi/4))下面),并且包裹numprint输出格式:

在此处输入图片描述

笔记:

  • 输入的德语格式以及将*输入中的 更改为\cdot(添加pi\tan,等等...) 改编自@Werner 的解决方案。

进一步增强:

  • 使用numprint输入中的数字,因为这样比仅仅将 更改为 具有更大的.灵活性,
  • 处理更复杂的数学表达式的格式,例如更改exp(a/b)\e^{a/b}

代码:

\documentclass{article}
\usepackage{pgf}
\usepackage{xparse}
\usepackage{xstring}
\usepackage{numprint}

\newcommand*{\AdjustInput}[1]{%
    \StrSubstitute{#1}{.}{,\!}[\temp]%
    \StrSubstitute{\temp}{*}{\cdot}[\temp]% 
    \StrSubstitute{\temp}{sin}{\sin}[\temp]% 
    \StrSubstitute{\temp}{cos}{\cos}[\temp]% 
    \StrSubstitute{\temp}{tan}{\tan}[\temp]% 
    \StrSubstitute{\temp}{deg}{}[\temp]% 
    \StrSubstitute{\temp}{((}{(}[\temp]% 
    \StrSubstitute{\temp}{))}{)}[\temp]% 
    \StrSubstitute{\temp}{pi}{\pi}[\temp]% 
    \temp%
}%

\NewDocumentCommand{\ca}{s m}{%
    \pgfmathsetmacro{\var}{#2}%
    \IfBooleanTF{#1}{%
        \ensuremath{\numprint{\var}}%
    }{%
        \ensuremath{\AdjustInput{#2}=\numprint{\var}}%
    }%
}%

\begin{document}
\ca*{8.12 - 2.2 + 1}% starred version only prints result

\ca{3*(2.2 + 2.3)}

\ca{8.12 - 2.2 + tan(deg(pi/4))}
\end{document}

答案4

我有点犹豫是否要添加这个答案,因为我只是在摸索 Lua。请随意编辑和改进代码。

无论如何,正如上面所暗示的,这是一种需要使用编译的方法lualatex,因为计算是用 Lua 完成的。

\documentclass{article}
\usepackage{luacode}
\newcommand{\ca}[2][f]{%
\luaexec{
    check = "#1"
    input = #2
    answer = tostring(input)
    answer = string.gsub(answer, "\%.", "{,}")
    calculation = "#2"
    calculation = string.gsub(calculation, "*", "\\cdot ")
    calculation = string.gsub(calculation, "\%.", "{,}")
    if check == "f" then
       tex.sprint("\\ensuremath{", answer, "}")
    else
       tex.sprint("\\ensuremath{", calculation, "=", answer, "}")
    end
}}
\begin{document}
\ca{1+2.2 - 5/2} \par
\ca[t]{3+1-2.34*3}
\end{document}

在此处输入图片描述

也可以通过将命令的定义更改为来扩展以允许sin、等cos

\newcommand{\ca}[2][f]{%
\luaexec{
    local sin, cos, tan, pi, exp, ln, log = math.sin, math.cos, math.tan, math.pi, math.exp, math.log, math.log10
    check = "#1"
    input = #2
    answer = tostring(input)
    answer = string.gsub(answer, "\%.", "{,}")
    calculation = "#2"
    calculation = string.gsub(calculation, "*", "\\cdot ")
    calculation = string.gsub(calculation, "\%.", "{,}")
    calculation = string.gsub(calculation, "pi*", "\\pi ")
    calculation = string.gsub(calculation, "sin", "\\sin ")
    calculation = string.gsub(calculation, "cos", "\\cos ")
    calculation = string.gsub(calculation, "tan", "\\tan ")
    calculation = string.gsub(calculation, "exp", "\\exp ")
    calculation = string.gsub(calculation, "ln", "\\ln ")
    calculation = string.gsub(calculation, "log", "\\log ")
    if check == "f" then
       tex.sprint("\\ensuremath{", answer, "}")
    else
       tex.sprint("\\ensuremath{", calculation, "=", answer, "}")
    end
}}

相关内容