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]