在包或类内部执行算术运算有一些可能性。
TeX
TeX 支持\advance
或\multiply
来\divide
执行算术运算。但是语法或多或少“需要习惯”。例如:
\@tempdima=35pt
\advance\@tempdima by 10pt
\divide\@tempdima by 5
特克斯
特克斯支持命令\dimexpr
和\numexpr
。这将简化上述示例,如下所示:
\@tempdima=\dimexpr (35pt+10pt)/5 \relax
LaTeX3
LaTeX3可以与eTeX进行比较。
\dim_set:Nn \l_tmpa_dim { (35pt+10pt) / 5 }
套餐
我知道有些软件包也允许算术运算。例如计算或者前列腺素。这些软件包也可以与 eTeX 进行比较。
但是,在包/类内部进行算术运算的推荐方法是什么?不同方法的优点/缺点是什么?
答案1
时间差异可能并不重要,以下测试表明,在我的计算机上,tex 基元比 etex 快一点(并且人们会认为 latex3 或 pgf 或 fp 宏会更慢)。但是 16^6 是很多操作,而这个文件不执行其他操作。在实际文档中,TeX 会花时间排版或打开或写入文件,因此计算速度的细微差异可能并不重要。
更重要的是计算不同:加法和乘法相同,但 etex 使用舍入而不是截断除法(这还算可以,但对于长度来说不同,但对于整数计数来说毫无用处)测试文件生成
6.85713pt
6.85715pt
第一个值来自\divide
,第二个值来自 etex /
。
\makeatletter
\def\a{\@tempdima=38pt
\advance\@tempdima by 10pt
\divide\@tempdima by 7 }
\a\typeout{\the\@tempdima}
\def\b{\@tempdima=\dimexpr (38pt+10pt)/7 \relax}
\b\typeout{\the\@tempdima}
\def\c{\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a}
%\def\c{\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b}
\def\d{\c\c\c\c\c\c\c\c\c\c\c\c\c\c\c\c}
\def\e{\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d}
\def\f{\e\e\e\e\e\e\e\e\e\e\e\e\e\e\e\e}
\def\g{\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f}
\g\g\g\g\g\g\g\g\g\g\g\g\g\g\g\g
\stop
時間:
特克斯
real 0m18.979s
user 0m18.408s
sys 0m0.124s
埃泰克斯
real 0m20.351s
user 0m19.749s
sys 0m0.124s
答案2
传统 TeX 计算和 e-TeX 扩展之间的最大区别在于,后者允许“即时”计算,无需赋值。这会以牺牲速度为代价,因为\numexpr
和\dimexpr
比\glueexpr
使用寄存器要慢。
然而,在编写代码时,
\setlength\@tempdima {\paperwidth}
\addtolength\@tempdima {-\textwidth}
\setlength\oddsidemargin {.5\@tempdima}
\addtolength\oddsidemargin {-1in}
\setlength\marginparwidth {.5\@tempdima}
\addtolength\marginparwidth {-\marginparsep}
\addtolength\marginparwidth {-0.4in}
\addtolength\marginparwidth {-.4in}
(这可以在size10.clo
)中发现,可以翻译成也许更清楚的
\setlength\oddsidemargin{%
\dimexpr (\paperwidth - \textwidth)/2 - 1in \relax
}
\setlength\marginparwidth{%
\dimexpr (\paperwidth - \textwidth)/2 - \marginparsep - 0.4in - 0.4in \relax}
(通过比较期权生效-0.4in
时的类似分配可以理解双重)。twoside
由于操作执行方式的细微差别(e-TeX 除法四舍五入,而传统的使用寄存器的 TeX 除法会截断),现在无法将标准类更改为使用更简单的语法,因为旧文档会受到影响。
相反,只要新包坚持一种语法,我会说更清晰的方法是首选:代码更少晦涩且更易于维护。
按照 LaTeX3 的说法,这两项作业将变成
\dim_set:Nn \oddsidemargin { (\paperwidth - \textwidth)/2 - 1in }
\dim_set:Nn \marginparwidth { (\paperwidth - \textwidth)/2 - \marginparsep - 0.4in - 0.4in }
这更加清晰了。