You are here


Submitted by h2b on 12. March 2017 - 19:48

SI -- A Scala Library of Units of Measurement

This is a Scala library of units of measurement featuring the International System of Units (SI).


In most cases, to use this package you will import all of this:

import de.h2b.scala.lib.phys.units.Quantity
import de.h2b.scala.lib.phys.units.Quantity._
import de.h2b.scala.lib.phys.units.base._
import de.h2b.scala.lib.phys.units.derived._


A quantity is composed of a magnitude and a unit.

val m = Quantity(10, kilogram) //> m  : Quantity[MassUnit] = 10.0 kg
val l = Quantity(0.981, metre) //> l  : Quantity[LengthUnit] = 0.981 m
val t = Quantity(1, second)    //> t  : Quantity[TimeUnit] = 1.0 s

You can add or subtract quantities of the same unit and multiply or divide quantities of arbitrary units. Also, you can scale a quantity by a factor.

val m2 = m + Quantity(20, kilogram) //> m2  : Quantity[MassUnit] = 30.0 kg
val m3 = 2 * Quantity(1, meter)     //> m3  : Quantity[LengthUnit] = 2.0 m

Multiplication and division of two quantities need an implicit unit operation that guarantees that the result becomes a quantity of proper unit. The other operations simply yield a quantity of the same unit as the operator.

val f = m * ((l / t) / t) //> f  : Quantity[ForceUnit] = 9.81 kg*m/s/s

The system is smart enough to derive that a quantity of units kilogram * ((metre / second) / second) is a quantity of ForceUnit. (Actually however, for now it is not smart enough if the order of operands is changed: ((l / t) / t) * m would not work -- in doubt try it out and inspect the unit objects mentioned below.)

The quantity class extends the Equals trait and there is also a ~= operator that compares quantities within an implicitly specified tolerance to compensate rounding errors.

The companion object provides implicit Double operations so that you can write, e.g., 10.m instead of Quantity(10, metre).

Quantity(10, metre) == 10.m //> Boolean = true


Units are based on the Système international d’unités (SI -- which gave this package its name), i.e., each unit [Q] can mathematically be expressed in terms of the base units metre, kilogram, second, ampere, kelvin, mol and candela by the equation

[Q] = ξ·10n·mα·kgβ·sγ·Aδ·Kε·molζ·cdη

For ξ=1 we have a (potentially derived) SI unit; for ξ=1 and n=0 we have a coherent SI unit.

The base package provides classes for the seven base units (plus a NeutralUnit) with implicit multiplication and division operations (as mentioned above) and associated objects of common names like metre, kilogram, second and so on.

The derived package provides the same for a (of course not complete) bunch of derived SI units like squareMetre, newton, pascal, joule, watt or volt.

The Prefix class has case objects providing the usual SI prefixes like kilo or milli along with a multiplication operation for units.

You can implement other units by providing the same components for the new unit as the base or derived packages do. For details see there.


See Scaladoc.

Maven Coordinates

See The Central Repository. Choose the version you want (of course, the latest one is recommended) and look under "Dependency Information".


SI - A Scala Library of Units of Measurement

Copyright 2016-2017 Hans-Hermann Bode

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.