72

I know there are a few packages related to typesetting units:

  • unitsdef
  • units, which can be seen as a "base package" used by unitsdef
  • SIunits
  • siunitx, which is the successor to SIunits
  • maybe others? like cjwunits and hepunits

What is the difference between them? Do they also work inside Math mode? And, more importantly, which one should I use?

Suggestion for people trying to answer this question: show some examples of how to typeset both simple and complex units. For instance, try typesetting these items:

  • 100 Celsius
  • 3 x 10^5 km/s
  • gravitational constant is measured in N m^2/kg^2
  • 10 kHz = 1 s^{-4}
  • sin(x) meters

I think these examples cover most needs when writing scientific texts: simple measurements (value + simple unit), values written in scientific notation, simple fractional units, complex fractional and squared units, units without any value accompanying them, units with arbitrary exponents, and arbitrary math code instead of a simple value.

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036

4 Answers4

99

As the author of siunitx I have some idea about the relative strengths of the various alternatives. There are various things that need to be done for units:

  • Semantic input of units, so \kilo\metre rather than km: this allows special effects such as reformatting fractions 'on the go' (some people prefer to use literal input, and this ideally needs to be supported too).
  • Formatting of numbers, for example dividing up digits into groups.
  • Correctly presenting awkward symbols such as the micro symbol.
  • Setting the font: many guidelines call for units to be in upright roman font with no bold or italic variation.
  • Keeping numbers and units together (no space breaking)

Many packages have been written to address one or other aspect of this question. For example, SIunits is good at providing semantic input, whereas SIstyle focusses on correct typesetting but leaves the input to the user. On the other hand, unitsdef sticks to doing only units and does not worry about other aspects.

The aim of the siunitx package is to cover all of the requirements above, and to provide a way that package behaviour can be altered. Thus it uses a series of key-value options that will change how the output is formatted. The options can be applied to the entire document or to an individual piece of input. It also is designed to work in either math or text mode equally well. I have also been very careful to provide up to date advice about the internationally-agreed units in the documentation of siunitx.

As a demo, using the latest release of siunitx the following all show off the package:

\documentclass{article}
\usepackage{siunitx}
\begin{document}

\begin{itemize} \item \qty{100}{\degreeCelsius} \item \qty{3e5}{\km\per\s} or \qty[per-mode = symbol]{3e5}{\km\per\s} \item \unit{\newton\metre\squared\per\kilogram\squared} or \unit[per-mode = symbol]{\newton\metre\squared\per\kilogram\squared} \item ( \qty{10}{\kilo\hertz} = \qty{1}{\per\second\tothe{4}} ) \item \qty[parse-numbers = false]{\sin(x)}{\metre} \end{itemize}

\end{document}

Example

There are a couple of notes to bear in mind if using siunitx. First, it requires e-TeX, which can be an issue with some publishers (even over 10 years after it was finalised!). Secondly, the formatting does take up some time. There are settings to turn things off but it's always the case that working by hand will ultimately be faster. However, the upside of clearer and more flexible input is in my opinion worth it.

One other point is that siunitx is under development, with bug fixes and new features (there is a list for v3.1). In contrast, both SIunits and SIstyle are depreciated: bug fixes only. The units and unitsdef packages have not been updated for many years.

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
  • Great answer! I gotta look at the code sample later, with more time. You forgot to cite cjwunits and hepunits. ;-) – Denilson Sá Maia Aug 24 '10 at 20:26
  • hepunits is an extension of SIunits. I'm not familiar with cjwunits, but a quick read through the code suggests is a simple approach to providing something like unitsdef-style units. – Joseph Wright Aug 24 '10 at 20:43
  • Does siunitx have any conflict inside align* environment? I get ! Package siunitx Error: Invalid token '\protect ' in numerical input. – Kedar Mhaswade Nov 05 '20 at 00:40
  • Is this advice still current (2021)? In particular, the code example seems different from what is supported by current siunitx. I've always used unitsdef and I was going to update to siunitx since it's actively maintained, but the two packages are incompatible, so this prevents a smooth transition, forcing me to change every unitsdef usage in a document at once, which could be a bit disruptive. – LorenzoDonati4Ukraine-OnStrike Dec 21 '21 at 15:12
  • @LorenzoDonati--Codidact.com The code example was updated recently to match the v3 change. As you say, siunitx is incompatible with unitsdef: that's a consequence of using the same document command names. – Joseph Wright Dec 21 '21 at 18:57
  • Thanks for the prompt reply. I needed a confirmation before committing to learning a new package and to a large change to my documents. BTW, the command \qty in the example doesn't seem to be defined (I'm skimming over the manual of v2.8b in the latest TeXlive distro). It seems it was replaced by the \SI command. – LorenzoDonati4Ukraine-OnStrike Dec 21 '21 at 19:45
  • @LorenzoDonati--Codidact.com \SI was the standard v2 syntax, for v3 I have moved to using \qty. I suspect you are using a Linux distro TeX live rather than the vanilla one from TUG: siunitx in TeX Live 2021 is currently v3.0.37. – Joseph Wright Dec 22 '21 at 09:03
  • I downloaded TeXlive 2021 for Windows just a couple of weeks ago (the big ISO image), so I guess that distro was a bit outdated. I really don't like web installers. I like to be able to get my system to its original state if something bad happens. Not having an original installation packet around in my backup set is a big no-no for me. Anyway, thanks for the clarification. May I suggest to add the information about the supported version to your answer. Perhaps something like As a demo, using the latest release (v.3.0.37-released on 2021-MM-DD.)... – LorenzoDonati4Ukraine-OnStrike Dec 22 '21 at 10:53
8

The siunitx package discusses each of the others you've listed, noting that it can emulate all of them. I haven't used it extensively, but in the experience I do have, it seems to work very well, and be very comprehensive. A quick scan through that manual should let you find examples matching each of the ones you've listed.

Thus I think that the short answer is: use siunitx.

Norman Gray
  • 7,497
  • 2
  • 25
  • 35
  • Actually, I tried using scientific notation with siunitx, and I got an error. Since I was in a hurry, I decided to stick with unitsdef. I gotta try that extensively later (unless someone does that before me). – Denilson Sá Maia Aug 24 '10 at 12:34
  • 3
    Some detail of what you tried would be nice :-) Something like \SI{1e4}{\metre} should work fine with siunitx. – Joseph Wright Aug 24 '10 at 12:38
  • Nice! Since I was in a hurry, I didn't have enough time to read the siunitx documentation. I had tried something similar to this: \SI{$2.1 \times 10^{2}$}{\meter}, and I guess it failed because of math code inside this command. – Denilson Sá Maia Aug 24 '10 at 20:22
  • 1
    You'd want \sisetup{parse-numbers = false} for that. – Joseph Wright Aug 25 '10 at 05:45
5

I'd also recommend siunitx. As you know its author is very active in the TeX community and provides excellent support.

Leo Liu
  • 5,445
3

I find the packages for units cumbersome. Instead consider a simple solution that covers most if not all canonical use cases.

\newcommand{\unit}[1]{\,\mathrm{#1}}
\newcommand{\degC}{^\circ{\mathrm C}}
\newcommand{\tothe}[1]{\times 10^{#1}}

Putting these commands in a preamble is admittedly not as clean as a \usepackage command, but the economy and readability of the text is far greater in my opinion. Here's the MWE.

\documentclass{article}

\newcommand{\unit}[1]{,\mathrm{#1}} \newcommand{\degC}{^\circ{\mathrm C}} \newcommand{\tothe}[1]{\times 10^{#1}}

\begin{document}

\begin{itemize} \item $100\degC$ \item $3\tothe{5}\unit{km/s}$ or $3\tothe{5}\unit{km,s^{-1}}$ \item $6\unit{N m^2 kg^{-2}}$ or $6\unit{N m^2/kg^2}$ \item $10\unit{kHz} = 1\unit{s^{-4}}$ \item $\sin(x)\unit{m}$ \item $16\unit{\mu W/m,K}$ is different than $16\unit{\mu W/mK}$ \end{itemize}

\end{document}

This approach has obvious drawbacks. (1) It's not semantic. But I don't need this in my own documents. I know what I'm trying to say and can do it more economically than a package. (See the last example in the MWE. A semantic approach would handle this transparently.) (2) It doesn't cover all use cases. But I can't think of an edge case, and I can format these locally if need be or edit the command; I don't need a monolithic package that covers everything at the expense of simplicity. (3) It doesn't handle naked units elegantly (because of the thin space, even if you include \ensuremath in the command). But I would argue naked units are not needed in scientific writing (other than in plot labels, which are normally generated outside the LaTeX document anyway).

I know this is not for everyone, but having written lots of scientific articles and used several of the unit packages, this is the solution that I keep coming back to. It's easier than trying to recall the syntax and key/value pairs for the myriad of options, is more readable, and I have more control over the output.