SI_Units Checked and Unchecked
June 18, 2026 · View on GitHub
Ada packages for handling SI units of measure:
Physical items have a private type; a subtype is defined for any dimension that has a unique SI unit like Newton and a lot more like speed.
Units (meter "m", second "s", Newton "N", etc. together wirh optional prefixes) are given as strings because they are case sensitive.
V: Speed := 5.0*"km/h"; -- unit indication is ...
T: Time := 30.0*"s"; -- ... case sensitive: "S" is Siemens
D: Length := V * T; -- dimension "m"
Put (D, Dim => "dam"); -- output with any prefix, here decameter: 4.2*dam (no string quotes)
Put (D, Dim => "Km"); -- raises Illegal_Unit, wrong case 'K'
Put (V, Dim => "dam"); -- raises Unit_Error, not dimension Speed
The method comes in two variants, checked and unchecked, selected with a generic parameter:
- Checked: Physical items carry with them their current dimension, so that all assignments and expressions are checked with respect to correct dimensions.
- Unchecked: This variant has the exact same specification, but physical items only carry their numerical values, dimensions are stripped.
License GPL 3 with GNAT modification.
For a more detailed introduction, see file SI.html. There is a complete user interface documentation included in a separate directory about which units are supported, what is the unit string syntax etc.
[Also see the author's Ada Magica and Ada introductory course at Ada Deutschland.]
This is an interim update; June 18, 2026
- The previous
SI.Text_IO.Getoperation with parameterWidth/= 0was not very plausible.Ada.Text_IO.GetwithWidth/= 0is most probably meant for reading data tables, so data to be read is right-aligned and trailing characters withinWidthrange lead toData_Error.
1815
1983
1995
Tables with dimensioned data generally split the numeric value and the unit in separate columns, so they cannot sensibly be read without additional parameters.
15.0 km
60 km/h
This change does not affect legacy code since the new parameters have default values. Only calls ofGetwithWidth/=0will no longer work, but those will be rare if not nonexistent (because of unusability). Of course the corresponding Put operation has also new defaulted parameters. - Plugged a hole in type checking:
Put (X, Dim => ""); -- outputs the default unit, no checks
Put (X, Dim => "mm"); -- checks whether X has dimension Length
Put (X, Dim => " "); -- new, note the space: checks whether X has dimension One - Fixed a bug in Get for Width > 0.
- Tests have been updated. The Tables example shows the new functionality.
- Added pitfall examples for fractional powers in documentation.
(8.0*"m**3")**(1/3) = 2.0*"m" -- an item (a value times a unit) to the power of x
8.0**(1/3)*"m**(3/3)" = 1.0*"m" -- a value to the power of x times a unit
8.0**(1/3)*"m**3"**(1/3) -- illegal: ditto times a unit to the power of x
This is release 2.0.0; Apr 7, 2026.
Incompatible User Interface change: Ada 2022 defines the 'Image attribute for any type and allows its redefinition –
since its default is impractical, the 'Image attribute has been redefined to deliver the same result as its previous homonymous
replacement function, which does no longer exist; its partner, the Value function, has been moved to the base package where
'Image is now defined.
Some improvements of documentation and tests.
Tested with GNAT CE 2021.
Use of GNAT 15.2.1 is not recommended because of Bugzilla 122574.
Release 1.0.1; Sep 9, 2025
Evaluation of unit strings has been reimplemented, tests adapted accordingly (no effect on execution time).
There is no change in the user interface.
Only behaviour in case of wrong unit strings is different.
There is a bug fix in the unit string syntax.
Tested with GNAT CE 2021.
Release 1.0.0; Jul 14, 2025
First GitHub release.
Updated edition of 5 Aug 2020 published at http://archive.adaic.com/tools/CKWG/Dimension/SI.html.
The source at this URL is no longer updated.
Uses Predicates and (new) pragma Assertion_Policy.
Code: Celsius temperature scale added; instantiation of Text_IO package changed.
Test: Improved IO tests.
Since a physical item is of a private type, the attributes 'Image and 'Value do not exist.
Two homonymous functions are used as a replacement.