Précédent: \settowidth, Monter: Lengths [Table des matières][Index]
Synopsis, l’un parmi :
\numexpr expression \dimexpr expression \glueexpr expression \muglue expression
En tout lieu où vous pourriez écrire un entier, une dimen, une muglue ou une glue de TeX, vous pouvez à la place écrire une expression pour écrire ce genre de quantité.
Un exemple est que \the\dimexpr\linewidth-4pt\relax produit en
sortie la longueur égale à quatre points de moins que la largeur de la
ligne (le seul usage de \the est d’afficher le résultat dans le
document). De même, \romannumeral\numexpr6+3\relax produit
‘ix’, et \the\glueexpr 5pt plus 1pt * 2 \relax produit
‘10.0pt plus 2.0pt’.
Une commodité ici par rapport à effectuer les calculs en allouant des
registres et en utilisant \advance, etc., est que l’évaluation
d’expression n’implique par d’affectations et peut donc être effectuée à
des endroits où les affectations ne sont pas autorisées. L’exemple suivant
calcule la largeur de la \parbox.
\newlength{\offset}\setlength{\offset}{2em}
\begin{center}
\parbox{\dimexpr\linewidth-\offset*3}{Sans animosité envers
quiconque, charitables envers tous, et sûrs de notre droit en tant que
Dieu nous en accorde conscience, mettons-nous à l'œuvre afin d'achever
la tâche qui nous occupe, de panser les blessures de notre nation, de
porter soin à l'homme qui a affronté le combat et soulagement à sa veuve
et à son orphelin, enfin de faire tout pour réaliser et honorer une paix
juste et durable entre nous et avec toutes les nations. --- Abraham
Lincoln, second discours d'investiture, inscrit dans le mémorial
Lincoln}
\end{center}
L’expression consiste en un ou plusieurs termes du même type
(entier, dimension, etc.) qui sont ajoutés ou soustraits. Un terme est
un type de nombre, dimension, etc., et consiste en un facteur de ce
type, optionnellement multiplié ou divisé par des facteurs. Un facteur
d’un type est soit une quantité de ce type ou une sous-expression
parenthésés. L’expression produit un résultat du type donné, de sorte
que \numexpr produit un entier, \dimexpr produit une
dimension dimension, etc.
Dans l’exemple de citation donné plus haut, changer l’expression en
\dimexpr\linewidth-3*\offset produit l’erreur Illegal unit
of measure (pt inserted). La raison en est que pour \dimexpr et
\glueexpr, l’entrée consiste en une valeur de dimension ou de
glue suivie par un facteur multiplicatif optionnel, et non
l’inverse. Ainsi \the\dimexpr 1pt*10\relax est valide et produit
‘10.0pt’, mais \the\dimexpr 10*1pt\relax produit l’erreur
Illegal unit.
Les expressions absorbent les unités lexicales et effectuent les
opérations mathématiques appropriées jusqu’à ce qu’un \relax (qui
est absorbé), ou jusqu’à ce que la première unité lexicale non valide
soit rencontrée. Ainsi, \the\numexpr2+3px imprime ‘5px’,
parce que LaTeX lit le \numexpr2+3, ce qui est composé de
nombres, et ensuite trouve la lettre p, qui ne peut pas faire
partie d’un nombre. Il termine alors l’expression et produit le ‘5’,
suivi par le texte ordinaire ‘px’.
Ce comportement de terminaison est utile dans les comparaisons. Dans
\ifnum\numexpr\parindent*2 < 10pt Oui\else Non\fi, le signe
inférieur à termine l’expression et le résultat est ‘Non’ (dans un
document de classe LaTeX standarde article).
Les expressions peuvent utiliser les opérateurs +, -,
* et / ainsi que les parenthèses pour les
sous-expressions, (...). Dans les expressions glue les parties
en plus et minus ne nécessitent pas de parenthèses pour
être affectés par un facteur. Ainsi le résultat de \the\glueexpr
5pt plus 1pt * 2 \relax est ‘10pt plus 2pt’.
TeX convertit les autres types numériques de la même façon que
lorsqu’il fait une affectation à un registre. Ainsi le résultat de
\the\numexpr\dimexpr 1pt\relax\relax est ‘65536’, ce qui est
1pt exprimé en points proportionnés (voir sp, l’unité interne de TeX) et ensuite converti en entier.
Si ça avait été une \glueexpr, on aurait laissé tomber la
dilatation et la contraction. Dans l’autre sens, une \numexpr au
sein d’une \dimexpr ou d’une \glueexpr nécessite l’ajout
d’unité appropriées, comme dans \the\dimexpr\numexpr 1 + 2\relax
pt\relax, ce qui produit ‘3.0pt’.
Voici les détails de l’arithmétique : chaque facteur est vérifié comme
étant compris dans l’intervalle autorisé, les nombres doivent être
inférieurs à 2^{31} en valeur absolue, et les composantes de
dimensions ou glues doivent être inférieures à 2^{14} points, ou
mu, ou fil, etc. Les opérations arithmétiques sont
effectuées individuellement, sauf pour les opérations de dilatation (une
multiplication immédiatement suivie d’une division) qui sont faites
comme une opération combinée avec un produit sur 64-bit comme valeur
intermédiaire. Le résultat de chaque opération est de nouveau vérifié
comme appartenant à l’intervalle autorisé.
Finalement, on notera que les divisions et dilatations sont faites avec
un arrondi au plus proche (contrairement à l’opération \divide de
TeX qui prend un arrondi vers zéro). Ainsi \the\dimexpr
5pt*(3/2)\relax met ‘10.0pt’ dans le document, parce qu’il arrondit
3/2 en 2, tandis que \the\dimexpr 5pt*(4/3)\relax
produit ‘5.0pt’.
Précédent: \settowidth, Monter: Lengths [Table des matières][Index]