Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

There are some possibilities to execute arithmetic operations inside a package or class.

TeX

TeX supports \advance, \multiply or \divide to execute arithmetic operations. However the syntax is more or less "needs getting used to". Example:

\@tempdima=35pt
\advance\@tempdima by 10pt
\divide\@tempdima by 5

eTeX

eTeX supports the commands \dimexpr and \numexpr. This simplify the example above as follows:

\@tempdima=\dimexpr (35pt+10pt)/5 \relax

LaTeX3

LaTeX3 can be compared with eTeX.

\dim_set:Nn \l_tmpa_dim { (35pt+10pt) / 5 }

Packages

I know there are some packages which allow arithmetic operations, too. E.g. calc or pgf. Those packages can be compared with eTeX, too.



However what is the recommended way of doing arithmetic operations inside a package/class? What are the benefits/drawbacks of the different approaches?

share|improve this question
    
You might want to specify a bit more detail, e.g. type [integers, dimensions, skips, (floating points)], expandability, etc. –  Joseph Wright May 25 '13 at 8:04
    
@JosephWright: I don't see any differences between the usage of skip nor dimension etc.? –  Marco Daniel May 25 '13 at 8:09
    
For a package written in expl3 using expl3's possibilities seems natural. For a package written in LaTeX2e syntax I'd probably use etoolbox's wrappers for the eTeX primitives. etoolbox has very handy 2e writing tools, anyway. –  cgnieder May 25 '13 at 9:30
    
@cgnieder: A package using LaTeX ought use the functions of expl3. I think this is clear. As I wrote my package mdframed I used dimexpr. At comp.text.tex a guy told me that dimexpr is too slow and I should use TeX commands. So I switched. Now I want to switch back but is it recommended? –  Marco Daniel May 25 '13 at 9:38
1  
Note that expl3 is really using a very thin wrapper around the e-TeX primitives here (with the exception of fp operations, where there is no e-TeX support). As such, there will be very little in it performance wise between those two methods. –  Joseph Wright May 25 '13 at 14:08

2 Answers 2

up vote 8 down vote accepted

Time differences are not likely to really matter, the following test shows that tex primitives are fractionally faster than etex on my machine (and one would assume that latex3 or pgf or fp macros would be slower still). However 16^6 is a lot of operations and this file does nothing else. In a real document TeX spends time typesetting or opening or writing files, so minor differences in computational speed are not likely to matter.

What matters more is that the computations are different: addition and multiplication are the same but etex uses rounding rather than truncating division (which is sort of OK, but different for lengths but is fairly useless for integer counts) The test file produces

6.85713pt
6.85715pt

with the first value being from \divide and the second from 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

Times:

tex

real    0m18.979s
user    0m18.408s
sys     0m0.124s

etex

real    0m20.351s
user    0m19.749s
sys     0m0.124s
share|improve this answer

The biggest difference between traditional TeX computations and e-TeX extensions is that the latter allow for "on the fly" calculations, without assignments. This goes at the expense of speed, as \numexpr, \dimexpr and \glueexpr are slower than using registers.

However, in writing code, something like

\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}

(this is found in size10.clo) could be translated into the perhaps clearer

\setlength\oddsidemargin{%
  \dimexpr (\paperwidth - \textwidth)/2 - 1in \relax
}
\setlength\marginparwidth{%
  \dimexpr (\paperwidth - \textwidth)/2 - \marginparsep - 0.4in - 0.4in \relax}

(the double -0.4in can be understood by comparing the similar assignments when the twoside option is in force).

Due to the small differences in the way operations are performed (e-TeX division rounds, while traditional TeX division with registers truncates), it's not feasible now to change the standard classes into using the easier syntax, because older documents would be affected.

To the contrary, so long as a new package sticks to one syntax, I'd say that a clearer method is to be preferred: the code is less obscure and more easily maintained.

In LaTeX3 parlance, the two assignments would become

\dim_set:Nn \oddsidemargin  { (\paperwidth - \textwidth)/2 - 1in }
\dim_set:Nn \marginparwidth { (\paperwidth - \textwidth)/2 - \marginparsep - 0.4in - 0.4in }

which is even clearer.

share|improve this answer
    
I prefer the clearer method. Thanks. –  Marco Daniel May 25 '13 at 12:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.