SI Library(ID:3696/sil006)

The SI Library of Unit-Based Computation

Walter E. Brown, Fermi National Accelerator Laboratory, 1998

Extension to C++ to enable rigorous scientific computing (includes dimensions, units, intervals etc)

  • Walter E. Brown "The SI Library of Unit-Based Computation" Fermi National Accelerator Laboratory Batavia, IL 60510-0500, USA view details Abstract: We describe the general requirements, design, and usage of a C++ library based on the recognized international standard (SI) for describing measurable quantities and their units.

    In their introductory text, Halliday and Resnick teach physicists to "... check the dimensions of all the equations you use." However, inspection of code samples reveals that scientific programmers typically make heavy use of a programming language's native numeric data types, thus obscuring the diverse intentions (e.g., distances, masses, energies, momenta, etc.) that any such purely numeric value could represent.

    While limitations in programming language expressiveness and compiler technology have historically made such efforts difficult, the present project provides, in a modern programming language, a convenient means of expressing, computing with, and displaying numeric values with attached units. The fundamental requirements, (1) to apply compile-time type-checking while (2) avoiding time and space overhead at run-time, have been met. Thus, the Library enables automated (compile-time) checking of the dimensions of the numeric values within a computer program, and so provides the well-known benefits of type-safety to a new category of computing contexts.

    In particular, this SI Library provides data types corresponding to all the base dimensions specified by SI. It also provides a mechanism to generate additional data types to describe and represent all derived dimensions in accordance with SI's provisions. Thus, for example, an object resulting from the product of two Length objects is automatically of type Area.

    All the base and composite units specified by SI are provided as well, as are forms of the mandated prefixes for describing multiples and sub-multiples of the units. A significant number of additional standard values (any of which may be used as units), are also furnished within the Library. As additional features, the Library permits user'specification, at compile time, of data representation, calibration, and models.

    The following two lines of code suffice to access the Library's full capabilities:

        #include "SIunits/stdModel.h"
        using namespace si;    // optional

    The Library itself is built from a relatively small amount of source code. This has been accomplished via extensive use of contemporary C++ technology, including namespaces and templates. Moreover, the byte-size of any object created via this Library is identical to the byte-size of an object of the native type having the identical data representation. Extract: Example
    // -------------------------------------------------------
        // Example 1: fundamentals of instantiation/initialization
        // -------------------------------------------------------

        #include "SIunits/stdModel.h"
        using namespace si;       // make most si:: symbols available
        using namespace si::abbreviations;

        int main()  {

          // Successful instantiations:
          Length d;               // initialized to 0 meters by default
          Length d2( 2.5 );       // 2.5 meters; same as 2.5 * m
          Length d3( 1.2 * cm );  // 1.2 centimeters; recorded as .012 * m
          Length d4( 5 * d3 );    // equivalent to 6.0 centimeters
          Length d5( 1.23 * pico_ * meter ); // 1.23e-12 * m
          Length d6( d2 + d3 );   // all dimensions match

          // Bad instantiation attempts; all detected at compile-time:
          Length d7( d2 * d3 );   // oops: an Area can't initialize a Length
          Length d8 = 3.5;        // oops: 3.5 is not a Length
          Length d9;              // so far so good, ...
            d9 = 3.5;             // ... oops: 3.5 is still not a Length

          return 0;

        }  // main()