![进行涉及长度的一般算术计算最方便的方法是什么?](https://linux22.com/image/267734/%E8%BF%9B%E8%A1%8C%E6%B6%89%E5%8F%8A%E9%95%BF%E5%BA%A6%E7%9A%84%E4%B8%80%E8%88%AC%E7%AE%97%E6%9C%AF%E8%AE%A1%E7%AE%97%E6%9C%80%E6%96%B9%E4%BE%BF%E7%9A%84%E6%96%B9%E6%B3%95%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F.png)
我知道 LaTeX 至少可以存储两种类型的数字:无量纲量(即 1、pi 等)和长度(即1pt
、\textwidth
等)。是否存在一些方便、通用的方法来进行计算,使用或多或少复杂的算术表达式,可以同时涉及无量纲量和长度?
例如,如何最轻松地计算表达式1/(1/a+1/b)
,其中a
和b
是长度,并将结果存储为新长度?或者如何计算和存储直角三角形的斜边,其中 和a
是b
两个最短边,squareroot(a^2+b^2)
?是否可以计算和存储面积(例如a*b
)?
是否有一些简单的方法可以立即进行此类计算,或者您是否必须通过将其除以(例如,1pt
(我只是随机选择了一个参考长度))将长度转换为无量纲量,然后才能这样做?
答案1
几乎所有计算系统都使用实数,而不是长度,并且肯定不允许在计算中使用任意维度。(尝试在 Excel 中计算面积:您需要将长度转换为实数,然后将面积计算为单位分开的实数。)
TeX 提供了一种“原生”的方式来存储尺寸,因为它们是排版所需要的。从计算角度来看,这些是有限的,因为 Knuth 预计它们将广泛用于“已知量”。正如评论中指出的那样,有多种方法可以在 TeX 之上构建计算引擎:考虑到问题的描述,最合适的可能是内置于 中的引擎pgf
:pgfmath
。这允许一系列计算采用实数和长度的混合,并包括用于计算例如平方根的代码。面积和其他“高阶”的东西仍然需要先手动转换。
答案2
通过在长度前加上 ,可以将长度转换为数字\number
。这样可以给出以单位表示的值,单位为sp
。但是,将两个这样的数字相乘很容易超出 TeX 对整数的限制,即。 中没有面积概念,也没有提供面积概念。1/65536
pt
2^31
TeX
\areaexpr
e-TeX
还要注意,尽管您可以TeX
以各种单位输入长度pt
,,,等,但无法转换回来,并以单位打印一个值(我刚刚意识到似乎没有命令供用户显示由定义和设置的长度寄存器的值;人们只能使用来自的原语和)。cm
in
\the\<dimen>
pt
LaTeX
\newlength
\setlength
\the
\number
TeX
作为xintexpr对任意大数进行精确的代数计算,并且知道提取平方根(默认)精度为 16 位,您可以将它(与 结合\dimexpr
)用于解决您的问题。
\documentclass{article}
\usepackage{xintexpr}
\newlength{\lenA}
\newlength{\lenB}
\newlength{\lenC}
\newlength{\lenD}
\xintNewExpr{\Harmonic}[2]{round(2/(1/#1+1/#2))} % I added a 2 here
\newcommand{\HarmonicLen}[2]{\dimexpr\Harmonic {\number#1}{\number#2}sp\relax}
\xintNewExpr{\Pythagore}[2]{round(sqrt(#1^2+#2^2))}
\newcommand{\PythagoreLen}[2]{\dimexpr\Pythagore {\number#1}{\number#2}sp\relax}
% 1sp = 1/65536 pt.
% 1pt = 1/72.27 in.
% 1in = 2.54cm
% 1 sp^2 = 1/65536*1/65536 * 1/72.27 * 1/72.27 * 2.54 * 2.54 cm^2
%
\edef\ConvFactor {\xinttheexpr 1/65536*1/65536 * 1/72.27 * 1/72.27 * 2.54 *
2.54\relax }
\newcommand{\RectArea}[2]{%
\xintRound{4}{\xintPrd{{\number#1}{\number#2}{\ConvFactor}}}}
\begin{document}
\setlength{\lenA}{10pt}
\setlength{\lenB}{10pt}
\setlength{\lenC}{\HarmonicLen{\lenA}{\lenB}}
\setlength{\lenD}{\PythagoreLen{\lenA}{\lenB}}
\the\lenA,\the\lenB$\to$\the\lenC,\the\lenD (or directly: \the\HarmonicLen{\lenA}{\lenB},
\the\PythagoreLen{\lenA}{\lenB})
\setlength{\lenA}{1cm}
\setlength{\lenB}{1cm}
\setlength{\lenC}{\HarmonicLen{\lenA}{\lenB}}
\setlength{\lenD}{\PythagoreLen{\lenA}{\lenB}}
\the\lenA,\the\lenB$\to$\the\lenC,\the\lenD
% (or directly: \the\HarmonicLen{\lenA}{\lenB},
% \the\PythagoreLen{\lenA}{\lenB})
\setlength{\lenA}{1cm}
\setlength{\lenB}{2cm}
\setlength{\lenC}{\HarmonicLen{\lenA}{\lenB}}
\setlength{\lenD}{\PythagoreLen{\lenA}{\lenB}}
\the\lenA,\the\lenB$\to$\the\lenC,\the\lenD
% (or directly:
% \the\HarmonicLen{\lenA}{\lenB},
% \the\PythagoreLen{\lenA}{\lenB})
\setlength{\lenA}{1in}
\setlength{\lenB}{2in}
\setlength{\lenC}{\HarmonicLen{\lenA}{\lenB}}
\setlength{\lenD}{\PythagoreLen{\lenA}{\lenB}}
\the\lenA,\the\lenB$\to$\the\lenC,\the\lenD
% (or directly: \the\HarmonicLen{\lenA}{\lenB},
% \the\PythagoreLen{\lenA}{\lenB})
\setlength{\lenA}{5cm}
\setlength{\lenB}{7cm}
The rectangle with sides of lengths 5cm (\the\lenA) and 7cm (\the\lenB) has an
area equal to \RectArea{\lenA}{\lenB} cm${}^2$.
\setlength{\lenC}{5in}
\setlength{\lenD}{7in}
The rectangle with sides of lengths 5in (\the\lenC) and 7in (\the\lenD) has an
area equal to \RectArea{\lenC}{\lenD} cm${}^2$.
The ratio of these two areas is \xinttheexpr
round(\RectArea{\lenC}{\lenD}/\RectArea{\lenA}{\lenB},4)\relax{}
and the square or
2.54 is \xinttheexpr round(sqr(2.54),4)\relax.
\end{document}
答案3
xfp
提供了一种对无量纲量和长度进行算法计算的通用方法。“维度自动以点表示,例如,pc
是12
“(来自xfp
文档)。
\documentclass{article}
\usepackage{xfp}
\begin{document}
\newlength{\lengthA}
\setlength{\lengthA}{2em}% 20.00003pt
\newlength{\lengthB}
\setlength{\lengthB}{8bp}% 8.03pt
Using \TeX: \the\dimexpr\lengthA + \lengthB + 12pt\relax % 40.03003pt
Using \verb|xfp|: \fpeval{round(\lengthA + \lengthB + 12pt, 5)}pt % 40.03003pt
Hypotenuse: \fpeval{sqrt(\lengthA^2 + \lengthB^2)}pt
Other length calculation: \fpeval{1 / ((1 / \lengthA) + (1 / \lengthB))}pt
\end{document}
由于\fpeval
(和\inteval
) 是可扩展的,因此您也可以在长度分配中使用它:
\newlength{\hypotenuse}
\setlength{\hypotenuse}{\fpeval{sqrt(\lengthA^2 + \lengthB^2)}pt} % 21.55185pt
答案4
在语境(至少是 mkii),与在 eTeX 中一样,您可以使用命令\numexpr
、\dimexpr
、\glueexpr
和\muexpr
。例如
\ifdim\dimexpr (2pt-5pt)*\numexpr 3-3*13/5\relax + 34pt/2<\wd20
我不确定这是否有助于解决您的特定用例。它确实允许您在表达式中组合类型,但我不确定您是否可以避免您试图避免的转换。
尽管如此,我还是想在这个页面上引用这些命令,因为我正在寻找它们,而这个问题是我能找到的最接近我需要的东西。
也可以看看\dimexpr \numexpr 的参考资料。