# Help me get my feet back on the ground

units is a Unix command line program that just doesn’t translate well to a graphical user interface.

You have: 105 m/s^2
You want: g
* 10.70702
/ 0.093396667
You have: 240 cc
You want: floz
* 8.1153654
/ 0.12322304
You have: 16 m/s
You want: mph
* 35.790981
/ 0.02794
You have: 2.7 ft water
You want: lbf/ft^2
* 168.55549
/ 0.0059327642
You have: 2.7 ft water
You want: kpascal
* 8.0704807
/ 0.12390836
You have: .6 watt/m degC
You want: btu/hr ft degF
* 0.34667223
/ 2.8845691


This is an interactive session with units. The strengths of the program are:

• It thinks the way you do, using common abbreviations and common prefixes for powers of ten. It’s much easier to just type kpascal than to go through a menu or tabbed interface to find the “pascal” entry among the various pressure terms—and then divide the answer by 1000 to convert from pascals to kilopascals. (Of course, you can’t have everything. g is commonly used for both grams and the acceleration of gravity, but units isn’t smart enough to use context to distinguish between the two. It has to choose one or the other, and it chose g to mean gravitational acceleration. Grams are gm and gram.)
• It has a huge library of units. The water unit is the weight density of water; multiplying it by a length gives you the pressure at the bottom of a column of water of that height. The designer of a GUI unit converter would think long and hard before adding a unit like water, because every additional unit takes up space in a window or a menu and makes finding the other units a little bit harder. No such problem with a command line program.
• It allows you to combine units through multiplication and division, which effectively expands the library to a nearly infinite variety. units doesn’t need to have a special set of entries for thermal conductivity; it constructs the watt/m degC and btu/hr ft degF units on the fly because it knows all the individual components.

By the way, if you’re wondering why every conversion has a / line, it’s because the fundamental behavior of units—which I seldom use—is to provide the conversion factors to go back and forth between two sets of units. In this fundamental mode, you would have a session like this:

You have: m/s
You want: mph
* 2.2369363
/ 0.44704
You have: ft water
You want: kpascal
* 2.9890669
/ 0.33455256


So, for example, to go from m/s to mph, you multiply by 2.237 or divide by 0.447. It just so happens that if you put a pure number in front of the “have” units, the * line gives you the converted value in the “want” units. You can put numbers in front of the “want” units, too, but the interpretation of the result may involve more thinking than you want to do.

You have: 2.7 ft water
You want: 10 lbf/ft^2
* 16.855549
/ 0.059327642


2.7 in feet of water is equivalent to 16.86 in tens of pounds per square foot. The / line in conversions like this has an even weirder interpretation: if you have a pressure in tens of pounds per square foot, you divide it by 0.0593 to get it in “2.7s” of feet of water. It’s probably best not to think that way.

The units program itself is just a conversion engine—by itself, it doesn’t know any units at all. It learns the units at startup by reading a data file. By default, this data file is /usr/share/misc/units.lib on a Mac or /usr/share/lib/unittab or /usr/share/units.dat on other Unix platforms. You can tell units to read another data file by invoking it with the -f option:

    units -f /path/to/data/file


The data file is just a text file, with each line defining a new unit (or another name for a previously defined unit). On my computer, I have a units.lib file in my home directory that is a copy of the standard file with these additions at the end:

/ Local additions
Pa      pascal
W       watt
ksi     1000 psi
pcf     lbf/ft3
psf     lbf/ft2
ksf     kip/ft2
tsf     ton/ft2


The Pa and W lines are just synonyms so I don’t have to type out pascal and watt. The others are pressure, stress, and density units common in civil and mechanical engineering.

I have an alias in my .bashrc file,

    alias units='units -f ~/units.lib'


so that I can simply type units at the command line to get my augmented units instead of just the standard ones.

One deficiency in units is that it doesn’t allow fractional exponents1. I can think of only one use for fractional exponents, but it’s one that comes up commonly in the work I do: the fracture toughness of materials is expressed in units like $$\textrm{ksi} \sqrt{\textrm{in}}$$ or $$\textrm{MPa} \sqrt{\textrm{m}}$$. Because I can’t express values like this in units, I still have to convert these by hand.

The GNU version of units differs from the standard BSD/Mac version in that it allows addition and subtraction in the conversions (standard units allows only multiplication and division), and it uses the Readline library in interactive mode. The manual says it can do fractional exponents, but all the examples involve roots of units that are already raised to a power—there’s nothing like $$\sqrt{\textrm{in}}$$. Maybe I’ll download it and do some experimenting.

Update (5/27/09)
There’s now a followup post on $$\sqrt{\textrm{in}}$$ and GNU units.

Tags:

1. As far as I know. If you know better, please tell me about it.