Java corner - Unit conversion

Author : François Ochsenbein - Read before any use of available Java classes

Download corner

Class able to deal with scientific units and make the appropriate conversions. This class is an application of the "Adopted Standards for Astronomical Catalogues" ( It is tightly related to the class Converter which can define non-standard conversions.

Basically, a unit consists in a value associated to a unit symbol which is itself related to the SI (Système International). Most of the unit symbols in use in astronomy are included, but it is possible to add the definition of new units with their equivalence via the addSymbol(java.lang.String, java.lang.String, java.lang.String) method.

The class can also deal with units expressed in log scale like [km/s] equivalent to log(km/s), or in mag scale which is defined as -2.5log. Values may be transformed between the linear and log scales with the log, mag and dexp methods; conversions may also be performed via the convert methods.

The operations on units include the basic operations plus, minus, mult, div and power and the square root sqrt. Addition or multiplications on physical values would however better use the sum or prod methods, which take care of converting the log scales. To illustrate the differences, assuming that u1 and u2 have the same content of 5mag, the operation u1.add(u2) gives the result 10mag, while u1.sum(u2) gives a value around 4.25mag corresponding to the brightness of a source merging the two brightnesses.

For repetitive operations, like working on values from a table, it is suggested to use the setValue method which assigns the value but keeps the unit symbol and definition.

The numbers with their associated unit are edited as a single word (without embedded blanks); the SI equivalent may be edited with the toStringInSI method. The numbers in their edited form use an exponential notation mx10+n; the classical form mE+n is also correctly interpreted. Values in sexagesimal notation are also interpreted correctly in setValue provided their associated unit is "h:m:s" (time) or "d:m:s" (angle) --- note that the quotes " around the unit symbol are required!

An example of a program reading data all with the same km/s unit could be:

 Unit aUnit = new Unit("km/s") ; 
while (true) {
aUnit.setValue(stdin.readLine()) ;
System.out.println("Complete Value: " + aUnit);
System.out.println(" SI Equivalent: " + aUnit.toStringInSI());
System.out.println(" Unit Meaning: " + aUnit.explainUnit());

The recursive (BNF) definition of a Unit is as follows:

 Full_Unit = factor Complex_unit
Complex_Unit = single_Unit
| single_Unit OP single_Unit
| "log[" single_Unit OP single_Unit "]"
| "mag[" single_Unit OP single_Unit "]"
single_Unit = extended_UnitSymbol
| extended_UnitSymbol power
extended_UnitSymbol = UnitSymbol
| Magnitude_Prefix UnitSymbol
| "(" Full_Unit ")"
power = Number
| +Number
| -Number
OP = . | /
©ULP/CNRS - CDS, 11 rue de l'Université, 67000 Strasbourg, France Question@simbad