Class able to deal with scientific units and make the appropriate
conversions.
This class is an application of the
"Adopted Standards for Astronomical Catalogues"
(http://vizier.u-strasbg.fr/doc/catstd.htx).
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
*m*`x10+`*n*; the classical form
*m*`E+`*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 |