我想要一个命令\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
}}