是否可以通过创建一个可以接受公式然后打印和评估它的命令来减少以下 MWE,而无需为了评估和打印而以两种不同的形式编写两次,如下所示?
\documentclass[border=5mm]{standalone}
\usepackage{pgf,mathtools,siunitx}
\begin{document}
\newcommand{\toprint}{\frac{-4+\sqrt{4^2-4*1*3}}{2}}
\newcommand{\toevaluate}{(-4+sqrt(4^2-4*1*3))/2}
\pgfmathparse{\toevaluate}
The first root is evaluated by $x_1 = \toprint = \SI{\pgfmathresult}{\cm} $
\end{document}
答案1
据我所知,没有这样的功能,但我可能是错的。你可以编写自己的解析器,在本地重新定义打印内容的宏,将其包装到相应函数中。在下面的代码中,我为\frac
和执行了此\sqrt
操作。这在本例中有效,也是因为您非常善良,明确说明了乘法,甚至还*
为它们使用了乘法。显然,这个“解析器”很脆弱,但如果您真的觉得值得,您可以添加其他函数,例如\sin
和 等等。
\documentclass[border=5mm]{standalone}
\usepackage{pgf,mathtools,siunitx}
\begin{document}
\newcommand{\toprint}{\frac{-4+\sqrt{4^2-4*1*3}}{2}}
%\newcommand{\toevaluate}{(-4+sqrt(4^2-4*1*3))/2}
\newcommand{\DiaaParse}[1]{\begingroup\def\frac##1##2{((##1)/(##2))}%
\def\sqrt##1{sqrt(##1)}%
\edef\ret{#1}%
\pgfmathparse{\ret}\pgfmathprintnumber{\pgfmathresult}%
\endgroup}
%\pgfmathparse{\toevaluate}
The first root is evaluated by $x_1 = \toprint = \DiaaParse{\toprint}$
\end{document}
此版本不适用于\SI
,也是因为我不明白单位cm
来自哪里,但这可以改变。
如果你希望解析器仅解析并将结果存储在中\pgfmathresult
,则可以使用
\documentclass[border=5mm]{standalone}
\usepackage{pgf,mathtools,siunitx}
\begin{document}
\newcommand{\toprint}{\frac{-4+\sqrt{4^2-4\times1\times 3}}{2}}
\newcommand{\DiaaParse}[1]{\begingroup\def\frac##1##2{((##1)/(##2))}%
\def\sqrt##1{sqrt(##1)}%
\def\cdot{*}%
\def\times{*}%
\def\exp##1{exp(##1)}%
\def\log##1{log(##1)}%
\def\ln##1{ln(##1)}%
\def\arcsin##1{asin(##1)}%
\def\cot##1{cot(##1)}%
\def\sin##1{sin(##1)}%
\def\sinh##1{sinh(##1)}%
\def\arccos##1{acos(##1)}%
\def\cot##1{cot(##1)}%
\def\cos##1{cos(##1)}%
\def\arctan##1{atan(##1)}%
\def\cot##1{cot(##1)}%
\def\tan##1{tan(##1)}%
\def\tanh##1{tanh(##1)}%
\def\arccot##1{acot(##1)}%
\def\cot##1{cot(##1)}%
\def\cot##1{cot(##1)}%
\edef\ret{#1}%
\pgfmathparse{\ret}%
\pgfmathsmuggle\pgfmathresult%
\endgroup}
The first root is evaluated by $x_1 = \toprint =\DiaaParse{\toprint}
\SI{\pgfmathresult}{\cm}$
\end{document}
如您所见,这确实适用于\SI
等,因为它将额外的解析包装在 周围\pgfmathparse
。这也定义了其他命令的替换规则,但我强调它很脆弱。请注意,这需要较新版本的 pgf(我认为是 3.1.1 或更高版本),其中包含\pgfmathsmuggle
。对于较旧的版本,您必须使用其他走私技术,请参阅答案这个问题寻找可能的方法。
总的来说,这确实做了你所建议的事情,但我强调它很脆弱。如果用户想要计算,比如说,怎么办\log_{7} 29
?是的,可以扩展解析器来处理这个问题,但这将需要更多的努力。然后下一个用户想要\sqrt[3]{19}
。这也是可能的,但需要更多的努力。那么\log_{10} 3\frac{1}{4}
,解析器如何知道这是log(13/4)/log(7)
?当然,如果你使用外部程序,你可以避免重复,例如 Mathematica 有 TeXForm 将某些模块的结果转换为不太好但大多数时候有效的 (La)TeX 代码。
答案2
几年前,我遇到过同样的问题。
由于编写一个健壮的解析器并非易事,我决定不在 TeX 中尝试,而是使用 Python(版本 3.6 或更高版本)。
结果是计算模块。
输入如下:
from texcalc import Calculation
c = Calculation()
c.add('rho_f', '1.62', 'g/cm^3', 'Fiber density')
c.add('rho_r', '1.2', 'g/cm^3', "Resin density")
c.add('v_f', '0.3', '-', 'Fiber volume fraction')
c.add('W_f', '450', 'g/m^2', "Area weight fibers", fmt=".0f")
c.add('t_f', 'W_f/(10000*rho_f)*10', 'mm')
c.add('t', 't_f/v_f', 'mm', "Laminate thickness")
c.add('t_r', 't-t_f', 'mm')
c.add('W_r', 't_f/10*(10000*rho_r)', 'g/m^2', "Area weight resin", fmt=".0f")
print(c)
它输出一个align*
环境(来自amsmath
包)并用来siunitx
排版单位。经过 LaTeX 处理后,输出如下所示。
根据要求调整至 MWE
以下是mwe.py
from texcalc import Calculation
c = Calculation()
c.add('b', 4)
c.add('a', 1)
c.add('c', 3)
c.add('x1', '(-b+sqrt(b**2-4*a*c))/2', 'cm', 'first root')
c.add('x2', '(-b-sqrt(b**2-4*a*c))/2', 'cm', 'second root')
print(c)
运行如下命令python3 mwe.py > foo.tex
这是mwe.tex
:
\documentclass[preview=true]{standalone}
\usepackage{amsmath,siunitx}
\begin{document}
\input{foo.tex}
\end{document}
用 运行它pdflatex mwe.tex
。
TeXcalc 的目标是阐明具有多个步骤的复杂计算,如第一个示例所示。这样其他人就更容易理解。
所以它不能确切地与您的 MWE 匹配,因为它不产生内联数学。尽管在这种情况下,您可以从中提取必要的数据foo.tex
。
答案3
正如我在评论中承诺的那样回答在我使用calculator
包的地方,我很高兴地包括了我的代码,其中有一个有点令人困惑的清晰算法 :-),它可以改进为比这个 MWE 更短。但它确实有效。
%% Compile and read me!
\documentclass[a4paper,12pt]{article}
\usepackage{mathtools,amssymb}
\usepackage{calculator}
\begin{document}
\SQUARE{4}{\tempA}
\COPY{-4}{\tempB}
\COPY{4}{\tempC}
\COPY{1}{\tempD}
\COPY{3}{\tempE}
\COPY{2}{\tempG}
\MULTIPLY{\tempC}{\tempD}{\solA}
\MULTIPLY{\solA}{\tempE}{\solB}
\SUBTRACT{\tempA}{\solB}{\sol}
\SQUAREROOT{\sol}{\tempF}
\ADD{\tempB}{\tempF}{\result}
\DIVIDE{\result}{\tempG}{\divisio}
\TRUNCATE[1]{\divisio}{\division}
\begin{align*}
\frac{-4+\sqrt{4^2-4\times 1\times 3}}{2}
&= \frac{\tempB+\tempF}{\tempG}\\
&= \division \text{ cm }
\end{align*}
\end{document}