Unit Lists (Units: A Unit Conversion Program and Scientific Calculator)

## 7 Unit Lists: Conversion to Sums of Units ¶

Outside of the SI, it is sometimes desirable to convert a single unit to a sum of units—for example, feet to feet plus inches. The conversion from sums of units was described in Sums and Differences of Units, and is a simple matter of adding the units with the ‘`+`’ sign:

    You have: 12 ft + 3 in + 3|8 in
    You want: ft
            * 12.28125
            / 0.081424936

Although you can similarly write a sum of units to convert to, the result will not be the conversion to the units in the sum, but rather the conversion to the particular sum that you have entered:

    You have: 12.28125 ft
    You want: ft + in + 1|8 in
            * 11.228571
            / 0.089058524

The unit expression given at the ‘`You want:`’ prompt is equivalent to asking for conversion to multiples of ‘`1 ft + 1 in + 1|8 in`’, which is 1.09375 ft, so the conversion in the previous example is equivalent to

    You have: 12.28125 ft
    You want: 1.09375 ft
            * 11.228571
            / 0.089058524

In converting to a sum of units like miles, feet and inches, you typically want the largest integral value for the first unit, followed by the largest integral value for the next, and the remainder converted to the last unit. You can do this conversion easily with `units` using a special syntax for lists of units. You must list the desired units in order from largest to smallest, separated by the semicolon (‘`;`’) character:

    You have: 12.28125 ft
    You want: ft;in;1|8 in
            12 ft + 3 in + 3|8 in

The conversion always gives integer coefficients on the units in the list, except possibly the last unit when the conversion is not exact:

    You have: 12.28126 ft
    You want: ft;in;1|8 in
            12 ft + 3 in + 3.00096 * 1|8 in

The order in which you list the units is important:

    You have: 3 kg
    You want: oz;lb
            105 oz + 0.051367866 lb

    You have: 3 kg
    You want: lb;oz
            6 lb + 9.8218858 oz

Listing ounces before pounds produces a technically correct result, but not a very useful one. You must list the units in descending order of size in order to get the most useful result.

Ending a unit list with the separator ‘`;`’ has the same effect as repeating the last unit on the list, so ‘`ft;in;1|8 in;`’ is equivalent to ‘`ft;in;1|8 in;1|8 in`’. With the example above, this gives

    You have: 12.28126 ft
    You want: ft;in;1|8 in;
            12 ft + 3 in + 3|8 in + 0.00096 * 1|8 in

in effect separating the integer and fractional parts of the coefficient for the last unit. If you instead prefer to round the last coefficient to an integer you can do this with the `--round` (`-r`) option. With the previous example, the result is

    You have: 12.28126 ft
    You want: ft;in;1|8 in
            12 ft + 3 in + 3|8 in (rounded down to nearest 1|8 in)

When you use the `-r` option, repeating the last unit on the list has no effect (e.g., ‘`ft;in;1|8 in;1|8 in`’ is equivalent to ‘`ft;in;1|8 in`’), and hence neither does ending a list with a ‘`;`’. With a single unit and the `-r` option, a terminal ‘`;`’ does have an effect: it causes `units` to treat the single unit as a list and produce a rounded value for the single unit. Without the extra ‘`;`’, the `-r` option has no effect on single unit conversions. This example shows the output using the `-r` option:

    You have: 12.28126 ft
    You want: in
            * 147.37512
            / 0.0067854058

    You have: 12.28126 ft
    You want: in;
            147 in (rounded down to nearest in)

Each unit that appears in the list must be conformable with the first unit on the list, and of course the listed units must also be conformable with the unit that you enter at the ‘`You have:`’ prompt.

    You have: meter
    You want: ft;kg
                 ^
    conformability error
            ft = 0.3048 m
            kg = 1 kg

    You have: meter
    You want: lb;oz
    conformability error
            1 m
            0.45359237 kg

In the first case, `units` reports the disagreement between units appearing on the list. In the second case, `units` reports disagreement between the unit you entered and the desired conversion. This conformability error is based on the first unit on the unit list.

Other common candidates for conversion to sums of units are angles and time:

    You have: 23.437754 deg
    You want: deg;arcmin;arcsec
        23 deg + 26 arcmin + 15.9144 arcsec

    You have: 7.2319 hr
    You want: hr;min;sec
        7 hr + 13 min + 54.84 sec

Some applications for unit lists may be less obvious. Suppose that you have a postal scale and wish to ensure that it’s accurate at 1 oz, but have only metric calibration weights. You might try

    You have: 1 oz
    You want: 100 g;50 g; 20 g;10 g;5 g;2 g;1 g;
            20 g + 5 g + 2 g + 1 g + 0.34952312 * 1 g

You might then place one each of the 20 g, 5 g, 2 g, and 1 g weights on the scale and hope that it indicates close to

    You have: 20 g + 5 g + 2 g + 1 g
    You want: oz;
            0.98767093 oz

Appending ‘`;`’ to ‘`oz`’ forces a one-line display that includes the unit; here the integer part of the result is zero, so it is not displayed.

If a non-empty list item differs vastly in scale from the quantity from which the list is to be converted, you may exceed the available precision of floating point (about 15 digits), in which case you will get a warning, e.g.,

    You have: lightyear
    You want: mile;100 inch;10 inch;mm;micron
            5.8786254e+12 mile + 390 * 100 inch (at 15-digit precision limit)

### 7.1 Cooking Measure ¶

In North America, recipes for cooking typically measure ingredients by volume, and use units that are not always convenient multiples of each other. Suppose that you have a recipe for 6 and you wish to make a portion for 1. If the recipe calls for 2 1/2 cups of an ingredient, you might wish to know the measurements in terms of measuring devices you have available, you could use `units` and enter

    You have: (2+1|2) cup / 6
    You want: cup;1|2 cup;1|3 cup;1|4 cup;tbsp;tsp;1|2 tsp;1|4 tsp
            1|3 cup + 1 tbsp + 1 tsp

By default, if a unit in a list begins with fraction of the form 1|x and its multiplier is an integer, the fraction is given as the product of the multiplier and the numerator; for example,

    You have: 12.28125 ft
    You want: ft;in;1|8 in;
            12 ft + 3 in + 3|8 in

In many cases, such as the example above, this is what is wanted, but sometimes it is not. For example, a cooking recipe for 6 might call for 5 1/4 cup of an ingredient, but you want a portion for 2, and your 1-cup measure is not available; you might try

    You have: (5+1|4) cup / 3
    You want: 1|2 cup;1|3 cup;1|4 cup
            3|2 cup + 1|4 cup

This result might be fine for a baker who has a 1 1/2-cup measure (and recognizes the equivalence), but it may not be as useful to someone with more limited set of measures, who does want to do additional calculations, and only wants to know “How many 1/2-cup measures to I need to add?” After all, that’s what was actually asked. With the `--show-factor` option, the factor will not be combined with a unity numerator, so that you get

    You have: (5+1|4) cup / 3
    You want: 1|2 cup;1|3 cup;1|4 cup
            3 * 1|2 cup + 1|4 cup

A user-specified fractional unit with a numerator other than 1 is never overridden, however—if a unit list specifies ‘`3|4 cup;1|2 cup`’, a result equivalent to 1 1/2 cups will always be shown as ‘`2 * 3|4 cup`’ whether or not the `--show-factor` option is given.

### 7.2 Unit List Aliases ¶

A unit list such as

    cup;1|2 cup;1|3 cup;1|4 cup;tbsp;tsp;1|2 tsp;1|4 tsp

can be tedious to enter. The `units` program provides shorthand names for some common combinations:

    hms         time: hours, minutes, seconds
    dms         angle: degrees, minutes, seconds
    time        time: years, days, hours, minutes and seconds
    usvol       US cooking volume: cups and smaller
    uswt        US weight: pounds and ounces
    ftin        length: feet, inches and 1/8 inches
    ftin2       length: feet, inches and 1/2 inches
    ftin4       length: feet, inches and 1/4 inches
    ftin8       length: feet, inches and 1/8 inches
    ftin16      length: feet, inches and 1/16 inches
    ftin32      length: feet, inches and 1/32 inches
    ftin64      length: feet, inches and 1/64 inches
    inchfine    length: inches subdivided to 1/64 inch

Using these shorthands, or unit list aliases, you can do the following conversions:

    You have: anomalisticyear
    You want: time
            1 year + 25 min + 3.4653216 sec
    You have: 1|6 cup
    You want: usvol
            2 tbsp + 2 tsp

Suppose you want to drill a clearance hole for a #10 screw and have about 1/64 inch clearance; you could try

    You have: screwgauge(10) + 1|64 in
    You want: ftin64
            13.16 * 1|64 in
    You have: _
    You want: ftin32
            6.58 * 1|32 in

If a slightly tight fit is acceptable, a 13/64-inch drill would do the job; if not, a 7/32-inch drill would work with a slightly looser fit.

You can define your own unit list aliases; see Defining Unit List Aliases.

You cannot combine a unit list alias with other units: it must appear alone at the ‘`You want:`’ prompt.

You can display the definition of a unit list alias by entering it at the ‘`You have:`’ prompt:

    You have: dms
            Definition: unit list, deg;arcmin;arcsec

When you specify compact output with `--compact`, `--terse` or `-t` and perform conversion to a unit list, `units` lists the conversion factors for each unit in the list, separated by semicolons.

    You have: year
    You want: day;min;sec
    365;348;45.974678

Unlike the case of regular output, zeros are included in this output list:

    You have: liter
    You want: cup;1|2 cup;1|4 cup;tbsp
    4;0;0;3.6280454