Units

A unit is a particular physical quantity, defined and adopted by convention, with which other particular quantities of the same kind are compared to express their value. The library has two classes of units: basic units and derived units. Basic units measure some arbitrary amount of a specific quantity while derived units are created by multiplying, scaling, and translating powers of other units (basic and/or derived). All units are associated with a specific quantity of the database either explicitly or implicitly. Implicit association is allowed if the appropriate quantity is not ambiguous. The library is able to convert an array of measurements from one unit to another if the source and destination unit measure the same specific quantity.

The definition of a basic unit is a two step process. First an empty definition is created with saf_declare_unit, then the unit is associated with a quantity with saf_quantify_unit. Example: define meters as a basic unit of length. That is, meters measures some arbitrary amount of length and will be the basis for deriving all compatible units.

1
2
3
 SAF_Unit *m = saf_declare_unit(SAF_ALL,db,"meter","m",NULL);
 saf_quantify_unit(SAF_ALL,m,SAF_QLENGTH,1);
 saf_commit(m,SAF_ALL,database);

The definition of derived units is similar when the new unit measures the same quantity. Example: define kilometers as 1000 meters (km and m both measure the same quantity).

1
2
 SAF_Unit *km = saf_declare_unit(SAF_ALL,db,"kilometer","km",NULL);
 saf_multiply_unit(SAF_ALL,km,1000,m,1);

Another way to define a unit is to multiply other units together. When this happens the new unit measures a different quantity than its unit divisors. In most cases the library can figure out what specific quantity to use for the unit, but this is not possible when the library contains multiple quantity definitions for similar quantities (e.g., `molecular amount’ and `monetary amount’ are both amount-of-a-substance quantities, but the library has two separate quantity definitions because it should should not be possible to convert between moles and dollars). Example: define coulomb as an ampere second instead of some arbitrary amount of charge:

1
2
3
4
5
 SAF_Unit *C = saf_declare_unit(SAF_ALL,db,"coulomb","C",NULL);
 saf_multiply_unit(SAF_ALL,C,1,A,1); // ampere
 saf_multiply_unit(SAF_ALL,C,1,s,1); // second
 SAF_Quantity *charge = saf_find_one_quantity(db,"electric charge",NULL);
 saf_quantify_unit(SAF_ALL,C,charge,1);

In the previous example the saf_quantify_unit could have been omitted since the library only defines one electric charge quantity and there is no ambiguity.

Two notable units are thermodynamic temperature measured in absolute Celsius and Fahrenheit. Both of these are the same amount as a degree Kelvin or a degree Rankine, but are offset by some amount. These units can be declared with saf_offset_unit:

1
2
3
 SAF_Unit *absC = saf_declare_unit(SAF_ALL,db,"absolute Celceus","absC",NULL);
 saf_multiply_unit(SAF_ALL,absC,1,k,1); // degree Kelvin
 saf_offset_unit(SAF_ALL,absC,273.5);   // 0 deg C is 273.15 k

Another special type of unit is one which uses a logarithmic scale instead of a linear scale. For example, a decibel is a dimensionless measure of the ratio of two powers, equal to ten times the logarithm to the base ten of the ratio of two powers. In acoustics the decibel is 20 times the common log of the ratio of sound pressures, with the denominator usually being 2e-5 pascal. The saf_log_unit can be used to define such a unit:

1
2
3
4
 SAF_Unit *dB = saf_declare_unit(SAF_ALL,db,"decibel","dB",NULL);
 SAF_Quantity *spr = saf_find_one_quantity(db,"sound pressure ratio",NULL);
 saf_quantify_unit(SAF_ALL,dB,spr,1);
 saf_log_unit(SAF_ALL,dB,10,20);

The saf_offset_unit and saf_log_unit can only be applied to a unit after all multiplications have been performed, and such a unit cannot be used to derive other units.