# Scales

Scales take care of converting values seen by the user to and from the internal SI values.

• A LinearScale is used for most units. A linear scale is a scale that is both additive and multiplicative. I.e. `toStandardUnit(a * b + c) == a * toStandardUnit(b) + toStandardUnit(c)`.
• The IdentityScale is a special case of a LinearScale where `toStandardUnit(a) == a`.
• The OffsetLinearScale is primarily used for conversion among units which have different zero reference points (e.g., absolute temperatures).
• The GradeScale is used to express grades and angles in percentages. The Scale interface prescribes that a scale shall implement these three methods:

• `double toStandardUnit(double value)` which takes a value in the user's unit and returns the corresponding base (usually SI) value.
• `double fromStandardUnit(double value)` which takes a value in the base (usually SI) unit and returns the corresponding value in the user's unit.
• `boolean isBaseSIScale()` which should return true for scales that need no conversion to the base value, e.g., the `IdentityScale`.

Optional methods to implement are:

• `String toString()`
• `hashCode()`
• `equals(Object object)`

### Example OffsetLinearScale

The scale for conversion from Fahrenheit to Kelvin is an `OffsetLinearScale` with scaleFactor 5.0 / 9.0 and offset 459.67. The code for the toStandardUnit method is effectively:

``````@Override
public final double toStandardUnit(final double value)
{
return (value + 459.67) * (5.0 / 9.0);
}``````

The code for the fromStandardUnit method is effectively:

``````@Override
public final double fromStandardUnit(final double value)
{
return (value / (5.0 / 9.0)) - 459.67;
}``````

And the implementation for isBaseSIScale always returns false because this scale does not not even map 0.0 degrees F to 0.0 K (the reverse - mapping 0.0 to 0.0 - is not sufficient to qualify as a BaseSIScale).

In DJUNITS, the Fahrenheit scale is constructed together with the Fahrenheit absolute temperature unit using the deriveLinearOffset method of the Unit class using this code:

``````public static final AbsoluteTemperatureUnit DEGREE_FAHRENHEIT =
KELVIN.deriveLinearOffset(5.0 / 9.0, 459.67,
TemperatureUnit.DEGREE_FAHRENHEIT,
"dgF", "degree Fahrenheit",
UnitSystem.SI_DERIVED,
"\u00B0F", "degF", new String[] {"F"});``````

The first two arguments specify the scaleFactor and the offset. `TemperatureUnit.DEGREE_FAHRENHEIT` is the corresponding relative unit. (DJUNITS needs this in order to construct the result of a subtraction of two absolute temperatures where the first uses the AbsoluteTemperatureUnit.DEGREE_FAHRENHEIT.) The other arguments specify the abbreviations and full name as well as the unit system.

There is a similar (slightly simpler) costruction for the `DEGREE_CELCIUS` unit. DJUNITS can now convert absolute temperatures from Fahrenheit to Celcius via Kelvin (and back) without any additional code.