Unités (siunitx)

L’espace entre le nombre et l’unité dans « 9,81 m/s² » n’est pas là pour faire joli. La Brochure SI, publiée par la Conférence générale des poids et mesures, précise que cet espace est un signe de multiplication : une grandeur forme donc un tout indivisible, qu’il ne faut pas couper en fin de ligne. Le package siunitx est l’outil LaTeX qui prend en charge toute cette famille de règles. Cette page suit les trois piliers de la version 3 actuelle, \num, \unit et \qty, et répond au passage : pourquoi les unités se composent en romain droit, pourquoi les chiffres se groupent par une espace et non par une virgule, comment la colonne S aligne un tableau sur le séparateur décimal, et comment traduire les \SI et \si croisés dans les vieux billets.

Pourquoi ne pas écrire \mathrm{kg} à la main

À la main, cela casse parce que ce qui doit être respecté n’est pas une affaire de goût mais une norme internationale, et que trois de ses règles s’appliquent en même temps. La première concerne la police. La Brochure SI prescrit que les symboles d’unité « sont imprimés en romain droit, quelle que soit la police du texte environnant », car m, kg et s ne sont pas des variables. Or, en mode mathématique LaTeX, les lettres sont inclinées par défaut : un $9.81 kg$ brut donne à l’unité l’allure du produit d’un k et d’un g italiques. Écrire \mathrm{kg} corrige cet endroit-là — et un article en compte plusieurs dizaines.

La deuxième règle est l’espace. La section 5.4.3 de la Brochure énonce que la valeur numérique précède toujours l’unité et qu’une espace sépare toujours les deux — puis explique que cette espace est considérée comme un signe de multiplication. Ni 9.81kg ni 9.81 kg ne sont donc corrects. La seule exception admise par la norme concerne le degré, la minute et la seconde d’angle plan (°, , ), devant lesquels aucune espace n’est laissée. C’est pourquoi 30,2 °C et 22,20° peuvent voisiner dans le même paragraphe : le Celsius garde son espace, l’angle non. Un document contient donc les deux cas, « espace avant ° » et « pas d’espace avant ° », et tenir cette distinction à la main sur quelques centaines d’occurrences n’est franchement pas réaliste.

La troisième règle : le couple ne doit pas se séparer. Puisqu’une grandeur est le produit d’un nombre et d’une unité, 9,81 ne doit jamais rester en fin de ligne pendant que m/s² ouvre la suivante. siunitx interdit cette coupure par défaut ; on ne l’autorise que délibérément, via allow-quantity-breaks. Si une colonne étroite signale une underfull hbox, cet avertissement n’est donc pas un incident mais la règle qui fait son travail. Ces trois points se règlent d’une seule ligne dans le préambule, \usepackage{siunitx} — avec ce bénéfice annexe qu’un unique réglage modifié ensuite change l’aspect dans tout le document.

latex
\usepackage{siunitx}

% by hand: three separate things to remember, every time
$9.81\,\mathrm{m}\,\mathrm{s}^{-2}$

% with siunitx: one command, and the standard is applied for you
\qty{9.81}{\metre\per\second\squared}
\qty{100}{\degreeCelsius}   % 100 °C   - space kept before the degree
\qty{10}{\percent}          % 10 %     - space here too
\ang{22.20}                 % 22.20°   - but no space for a plane angle

\num : ce qui arrive à un nombre nu

\num{…} prend un nombre seul et règle groupement, exposants, signes et zéro initial conformément à la norme. \num{12345} donne 12 345, \num{1.234e5} donne 1,234 × 10⁵ et \num{.5} donne 0,5. Ce dernier point compte discrètement : la Brochure SI exige que, pour un nombre compris entre +1 et −1, le séparateur décimal soit toujours précédé d’un zéro — donc 0,234 et non ,234. Taper .5 dans la source et obtenir 0,5 à l’impression épargne plus de frappes qu’on ne l’imagine.

Grouper les chiffres par une espace et non par une virgule n’est pas un goût de l’auteur du package. C’est la résolution 7 de la 9ᵉ Conférence générale des poids et mesures, en 1948, qui l’a fixé : les nombres peuvent être divisés en groupes de trois pour faciliter la lecture, et « ni points ni virgules ne sont jamais insérés dans les espaces entre les groupes ». La même résolution décrit le séparateur décimal comme « la virgule (usage français) ou le point (usage britannique) » — une formulation qu’on relit aujourd’hui avec un certain charme. Conforme : 43 279,168 29 ; non conforme : 43.279,168.29. La valeur par défaut de group-separator dans siunitx est précisément cette espace fine, \,.

L’entrée, en revanche, est indulgente. La valeur par défaut de input-decimal-markers est la paire .,, si bien que \num{0,1234} et \num{0.1234} donnent le même résultat. Celle de input-exponent-markers est le quatuor dDeE, si bien que le 3.45d-4 d’allure Fortran est lu comme 3,45 × 10⁻⁴. En pratique, des nombres collés tels quels depuis un fichier CSV ou un journal d’instrument peuvent être insérés sans uniformisation préalable. La seule chose que \num ne fait pas, c’est multiplier : en v3, les produits de nombres passent par la commande dédiée \numproduct{1.2 x 3.4} (termes séparés par x). Cette répartition suit elle aussi la norme, qui impose de n’utiliser que le signe × pour multiplier des nombres.

latex
\num{12345}        % 12 345      - grouped with a thin space, never a comma
\num{43279.16829}  % 43 279.168 29
\num{1.234e5}      % 1.234 x 10^5
\num{3.45d-4}      % 3.45 x 10^-4  - Fortran-style d also works
\num{0,1234}       % 0.1234       - comma accepted on input
\num{.5}           % 0.5          - leading zero supplied
\num{-15673}       % -15 673
\numproduct{1.2 x 3.4}   % 1.2 x 3.4   - products need their own command

Point ou virgule décimale ? locale et output-decimal-marker

Les deux sont corrects : telle est la réponse de la norme. La résolution 10 de la 22ᵉ Conférence générale des poids et mesures, en 2003, a établi que le séparateur décimal « doit être soit le point sur la ligne, soit la virgule sur la ligne », et que celui qui est retenu « doit être celui qui est usuel dans la langue et le contexte concernés ». Composer 9,81 m/s² dans un document français, allemand ou espagnol est donc correct exactement au même titre que 9.81 m/s² dans un document anglais. Aucun n’est la vraie version dont l’autre serait l’accent. siunitx est honnête sur ce point dans sa conception : il sépare le format de l’entrée de celui de la sortie.

Il y a deux façons de basculer. Pour un contrôle fin, on règle séparément le séparateur décimal de sortie avec output-decimal-marker et le groupement des chiffres avec group-separator. Pour changer d’un coup toute une convention régionale, on utilise l’option locale ; le package fournit des configurations pour UK, US, DE (Allemagne), PL (Pologne), FR (France), SI (Slovénie) et ZA (Afrique du Sud). L’essentiel est que la source n’a pas à changer : \qty[locale = DE]{6.789}{\metre} garde le point dans le source et imprime 6,789 m. C’est ce qui rend praticable la publication d’un même manuscrit en édition anglaise et en édition allemande.

Pour une région non fournie — l’espace hispanophone ou italophone, par exemple — locale n’offre rien : il faut l’écrire soi-même, avec \sisetup{output-decimal-marker = {,}}. Un piège guette alors : passer le séparateur décimal à la virgule, puis mettre aussi la virgule comme séparateur de groupes. Avec group-separator = {,} et output-decimal-marker = {,} en vigueur, \num{12345.678} imprime 12,345,678, et aucun lecteur ne peut dire quelle virgule est décimale. C’est le moment où l’on comprend concrètement pourquoi la résolution de 1948 a pris soin de préciser qu’aucun point ni virgule n’est jamais inséré entre les groupes. Laisser le séparateur de groupes sur l’espace fine par défaut est le choix sûr.

latex
\qty[locale = DE]{6.789}{\metre}       % 6,789 m   - source keeps the point
\num[output-decimal-marker = {,}]{1.23}  % 1,23
\num[group-separator = {,}]{12345}       % 12,345    - US/UK habit, not SI

% document-wide, for a locale siunitx does not ship
\sisetup{output-decimal-marker = {,}}    % group-separator stays a thin space

% do NOT do this: the output 12,345,678 is unreadable
% \sisetup{output-decimal-marker = {,}, group-separator = {,}}

\unit : deux façons d’écrire une unité, et le rôle de \per

\unit{…} compose une unité seule, et l’argument s’écrit de deux façons. Le style littéral tape les symboles directement, comme dans \unit{kg.m/s^2}, où le point . est un produit entre unités, / un quotient et ^ un exposant. Le style macro construit l’unité mot à mot à partir de préfixes, d’unités et de puissances — \unit{\kilo\gram\metre\per\second\squared} —, à peu près comme on lirait l’unité à voix haute en anglais. Le partage pratique est net : littéral pour une unité ponctuelle écrite à la hâte, macro quand on voudra peut-être changer plus tard l’apparence de toutes les unités d’un coup. Les options n’ont prise que sur la forme macro.

MacroSensSortie
\gramMacro d’unité de base ; de même \metre \second \ampere \kelvin \mole \candelag
\kiloUn préfixe ; jamais valide seul, une unité doit suivrek
\kilogramUnité préfixée en un seul mot ; même résultat que \kilo\gramkg
\perEnvoie l’unité suivante au dénominateur : \joule\per\moleJ mol⁻¹
\squaredMet au carré l’unité précédente (suffixe) ; \cubed pour le cube
\squareMet au carré l’unité suivante (préfixe) ; \cubic pour le cube
\degreeCelsiusDegré Celsius ; une espace est conservée devant, comme l’exige la norme°C
\percentPour cent ; reconnu pour l’usage avec le SI, également précédé d’une espace%

L’apparence de \per est décidée par l’option per-mode — et c’est là que les vieux tutoriels se trompent le plus souvent : le défaut est la puissance négative. \unit{\metre\per\second\squared} imprime m s⁻² et non m/s², et \unit{\kilo\gram\per\cubic\metre} imprime kg m⁻³ et non kg/m³. Pour une barre oblique, per-mode = symbol ; pour une fraction empilée, per-mode = fraction. Un seul \sisetup{per-mode = symbol} dans le préambule et toutes les unités du document suivent cette politique.

Quand la barre est choisie, siunitx ajoute discrètement des parenthèses. La section 5.4.6 de la Brochure impose en effet, lors d’une division par barre oblique, l’emploi de parenthèses pour lever l’ambiguïté : (a/b)/c est admis, a/b/c ne l’est pas. Ainsi \unit[per-mode = symbol]{\joule\per\mole\per\kelvin} imprime J/(mol K) et non J/mol/K. Une règle qui, à la main, se réduit à « penser à surveiller la deuxième barre » est ici garantie structurellement. Le manuel ajoute que, dans les cas compliqués, les exposants négatifs sont préférables — d’où précisément le défaut per-mode = power.

latex
\unit{kg.m/s^2}                          % kg m/s^2   - literal input, slash kept
\unit{\kilo\gram\metre\per\second\squared}   % kg m s^-2  - default per-mode = power
\unit[per-mode = symbol]{\kilo\gram\per\cubic\metre}   % kg/m^3

\unit{\joule\per\mole\per\kelvin}                      % J mol^-1 K^-1
\unit[per-mode = symbol]{\joule\per\mole\per\kelvin}   % J/(mol K)  - brackets added

\sisetup{per-mode = symbol}   % one policy for the whole document

\qty réunit nombre et unité — plages, listes et angles

\qty{nombre}{unité} confie son premier argument à \num, son second à \unit, et place entre les deux l’espace prescrite. Il n’y a donc aucune notation nouvelle à apprendre : ce qui s’écrivait pour \num et ce qui s’écrivait pour \unit se juxtaposent simplement. La partie unité peut être en forme macro (\metre\per\second\squared) ou littérale (m/s). \qty est l’idée du début de cette page — une grandeur est le produit d’un nombre et d’une unité — traduite directement en commande.

Les plages et les listes ont leurs propres commandes, et la sortie de \qtyrange{10}{20}{\metre} est la plus frappante : elle imprime 10 m to 20 m et non 10–20 m. Cela vient là encore de la norme. La Brochure avertit que des grandeurs physiques reliées par un tiret risquent d’être lues comme des valeurs négatives, qu’écrire les valeurs avec un tiret demi-cadratin suivi d’une seule unité est tout aussi incorrect puisqu’une grandeur forme une seule entité mathématique, et qu’il est fortement recommandé d’employer le mot « to ». L’envie d’écrire 10–20 m dans un en-tête de tableau est forte, et elle est contraire à la norme. \qtylist{10;20;30}{\metre} compose 10 m, 20 m and 30 m.

Les angles sont le seul cas traité par \ang plutôt que par \qty. Comme indiqué plus haut, \ang{45} imprime 45° sans espace, et passer degrés, minutes et secondes séparés par des points-virgules donne \ang{45;30;15} sous la forme 45° 30′ 15″. C’est la première forme qu’il faut privilégier : la Brochure indique que, pour les angles plans, il est généralement préférable de diviser le degré décimalement, si bien que 22,20° est préféré à 22° 12′, sauf dans des domaines comme la navigation, la cartographie, l’astronomie et la mesure de très petits angles. Les minutes et les secondes sont un outil pour les disciplines qui en ont besoin.

latex
\qty{9.81}{\metre\per\second\squared}   % 9.81 m s^-2
\qty{1.234e5}{\kilo\gram\per\cubic\metre}  % 1.234 x 10^5 kg m^-3
\qty{2.998e8}{m/s}                       % literal units work here too

\qtyrange{10}{20}{\metre}    % 10 m to 20 m       - the word "to", not a dash
\qtylist{10;20;30}{\metre}   % 10 m, 20 m and 30 m

\ang{22.20}       % 22.20°     - decimal degrees are preferred
\ang{45;30;15}    % 45° 30' 15"  - degrees; minutes; seconds

L’incertitude entre parenthèses : \num{1.234(5)}

Une valeur mesurée s’accompagne d’une incertitude. siunitx lit les parenthèses de l’entrée exactement comme telles, si bien que \num{1.234(5)} compose 1,234(5). Cette notation entre parenthèses n’est pas une invention de siunitx : c’est la forme donnée par la Brochure SI à la section 5.4.5, où la masse du neutron s’écrit mₙ = 1,674 927 471(21) × 10⁻²⁷ kg, le nombre entre parenthèses étant l’incertitude-type rapportée aux derniers chiffres de la valeur citée. Passer (…) à \num, c’est donc écrire l’entrée telle que la norme la suppose déjà.

La présentation se choisit avec uncertainty-mode. Le défaut, compact, imprime le nombre entre parenthèses comme des chiffres du rang le moins significatif (\num{123.45(120)}123,45(120)), tandis que full imprime l’incertitude comme valeur complète (→ 123,45(1,20)). Activer separate-uncertainty donne la forme avec \pm, 1,234 ± 0,005. Ce qui mérite attention ici, c’est ce à quoi se rattache l’unité : écrit 12,3 ± 0,4 kg, le ±0,4 semble n’en porter aucune. siunitx le sait, et \qty[separate-uncertainty]{12.3(4)}{\kilogram} fournit lui-même les parenthèses, imprimant (12,3 ± 0,4) kg.

latex
\num{1.234(5)}                              % 1.234(5)
\num{123.45(120)}                           % 123.45(120)  - compact, the default
\num[uncertainty-mode = full]{123.45(120)}  % 123.45(1.20)
\num[separate-uncertainty]{1.234(5)}        % 1.234 +- 0.005

\qty{12.3(4)}{\kilogram}                        % 12.3(4) kg
\qty[separate-uncertainty]{12.3(4)}{\kilogram}  % (12.3 +- 0.4) kg  - brackets added

Aligner un tableau sur le séparateur décimal : colonne S et table-format

Écrire S dans la spécification de colonne à la place de c, l ou r, et les nombres de cette colonne s’alignent sur le séparateur décimal. Le contenu des cellules est lu par le même analyseur que \num, si bien que 1.2e3 devient 1,2 × 10³ et qu’un 975,31 écrit avec virgule devient 975,31 — une colonne déversée depuis un fichier CSV se range d’elle-même. Cela répond là encore à une exigence de la norme : la Brochure SI y consacre une phrase brève mais sans ambiguïté — pour les nombres d’un tableau, le format employé ne doit pas varier au sein d’une même colonne.

Le premier faux pas concerne presque toujours l’en-tête de colonne. Placez du texte dans une cellule de colonne S et siunitx tentera de le lire comme partie d’un nombre : les en-têtes s’entourent donc d’accolades, {Mass} — l’oublier fait s’effondrer l’alignement de cette ligne-là. Idem pour les en-têtes portant unités ou appels de note : protéger l’ensemble, {Mass / \unit{\gram}}. Pour stabiliser la largeur de la colonne, on déclare « chiffres entiers.chiffres décimaux » avec table-format. S[table-format = 4.1] réserve d’avance la place de quatre chiffres entiers et d’une décimale, si bien qu’ajouter des lignes ensuite ne déplace pas la colonne. Avec incertitudes : S[table-format = 2.2(1), separate-uncertainty] ; avec exposants : S[table-format = 1.3e2].

latex
\begin{tabular}{@{}cS[table-format = 4.1]@{}}
  \toprule
  Entry & {Mass / \unit{\gram}} \\   % braces protect the heading text
  \midrule
  1 & 1234.5 \\
  2 &   12.0 \\
  3 &    6.7 \\
  \bottomrule
\end{tabular}

% uncertainties and exponents get their own formats
% S[table-format = 2.2(1), separate-uncertainty]  ->  12.34 +- 0.05
% S[table-format = 1.3e2]

Il existe aussi une convention établie pour placer l’unité dans l’en-tête : non pas Length [m] mais Length / m, c’est-à-dire la division par l’unité. La raison est un conflit de notations — en mathématiques, [x] signifie « la dimension de x ». Détourner les crochets en récipient à unités rend [a] ambigu entre « dimension de l’accélération » et « l’unité est m/s² ». Diviser par l’unité ne laisse dans le corps du tableau que des nombres sans dimension, ce qui s’emboîte proprement avec le travail de la colonne S. Enfin, pour obtenir le même alignement à l’intérieur de \multicolumn ou \multirow, on utilise \tablenum[table-format = …]{…}, l’équivalent macro de la colonne S.

La différence entre \SI et \qty : passer de la v2 à la v3

Ce sont l’ancien et le nouveau nom de commandes qui font le même travail : \SI relève de la v2, \qty de la v3. L’auteur de siunitx, Joseph Wright, a réécrit le package de l’intérieur pour la v3.0.0, publiée le 17 mai 2021, et a rendu les noms des commandes de document « plus descriptifs ». Le manuel précise que \SI, \si, \SIrange et \SIlist restent disponibles mais ne sont pas recommandés pour les nouveaux documents ; il faut leur préférer la famille \qty…. Seuls \num et \ang ont conservé leur nom au fil du changement.

v2 (ancien nom)v3 (actuel)Rôle
\SI\qty{9.81}{\metre\per\second\squared}Nombre et unité
\si\unit{\kilo\gram}L’unité seule
\SIrange\qtyrange{10}{20}{\metre}Une plage (10 m to 20 m)
\SIlist\qtylist{10;20;30}{\metre}Une liste (10 m, 20 m and 30 m)
\num\num{1.234e5} (nom inchangé)Le nombre seul
\ang\ang{22.20} (nom inchangé)Un angle plan

La v3 a aussi resserré l’entrée. Le cas le plus visible est celui des préfixes : un préfixe sans unité n’est plus admis, et \unit{\kilo} s’arrête sur ! Package siunitx Error: Found prefix part with no unit. Ce n’est pas une pédanterie mais un alignement sur la norme — la section 5.2 de la Brochure SI dit depuis longtemps qu’un préfixe n’est jamais employé isolément et que les préfixes composés ne sont jamais utilisés. Une partie au moins de ce qui ressemble à une rupture en v3 n’est que le package rattrapant les règles. Dans le même esprit, les produits de nombres sont passés à \numproduct, ceux de grandeurs à \qtyproduct, et les valeurs complexes à la commande dédiée \complexnum.

Quand un vieux document refuse absolument de compiler en v3, le comportement hérité peut être invoqué au chargement : \usepackage{siunitx}[=v2]. À considérer toutefois comme un maintien en vie. La v3 fait correspondre en interne beaucoup d’anciens noms d’options aux nouveaux et consigne chaque fois un avertissement dans le journal. Un document dont le journal est bordé d’avertissements siunitx signale qu’il est temps de renommer. Pour un travail neuf, trois commandes suffisent : \num, \unit et \qty — le nombre seul, l’unité seule, et les deux ensemble. Tous les détails de la norme abordés sur cette page se règlent à l’intérieur de ces trois-là.

latex
% v2 names: still work, no longer recommended for new documents
\SI{9.81}{\metre\per\second\squared}
\si{\kilo\gram}

% v3 names: use these
\qty{9.81}{\metre\per\second\squared}
\unit{\kilo\gram}

% a prefix on its own is now an error:
% ! Package siunitx Error: Found prefix part with no unit.
\unit{\kilo}

% last resort for a document that will not build with v3
\usepackage{siunitx}[=v2]