Units
A run-time C++ library for working with units of measurement and conversions between them and with string representations of units and measurements
Install / Use
/learn @llnl/UnitsREADME
Units
The Units library provides a means of working with units of measurement at runtime, including conversion to and from strings. It provides a small number of types for working with units and measurements and operations necessary for user input and output with units.
This software was developed for use in LLNL/GridDyn, and HELICS and is currently a work in progress (though it's getting close). Namespaces, function names, and code organization are subject to change, though they are fairly stable at this point. Feedback is welcome. A set of documentation is available. A Python wrapper is also available through Pypi that wraps a limited subset of the library for most common purposes.
Table of contents
- Purpose
- Limitations
- Alternatives
- C++ Types
- Unit Representation
- Building The Library
- Try it out
- Usage
- Contributions
- Users
- Release
Purpose
A units library was needed to represent units from a wide range of disciplines and be able to separate them from the numerical values for use in calculations when needed. The main drivers are
- converting units, often represented by strings, to a standardized unit set when dealing with user input and output.
- Being able to use the unit as a single type that could contain any unit, and not introduce a huge number of types to represent all possible units.
- Being able to associate a completely arbitrary unit given by users with a generic interface and support conversions between those user defined units and other units.
- The library has its origins in power systems so support for per-unit operations was also lacking in the alternatives.
- Capturing uncertainty and uncertainty calculations directly with a measurement
It was desired that the unit representation be a compact type (<=8 bytes) that is typically passed by value, that can represent a wide assortment of units and arbitrary combinations of units. The primary use of the conversions is at run-time to convert user input/output to/from internal units, it is not to provide strict type safety or dimensional analysis, though it can provide some of that. This library does NOT provide compile time checking of units. The units library supports units and operations on units where many of the units in use are unknown at compile time and conversions and definitions are dealt with at run time, and may be of a wide variety of units.
This library is an engineering library, created to represent a huge variety of units and measurements in a simple data type instead of a proliferation of templates. It supports conversion of units to and from strings. It supports mathematical operations on units and measurements which are constexpr where possible. It supports units used in a wide variety of scientific and non-scientific contexts. Supports conversions between different units of the same type as well as some typical assumptions for supporting conversions of a few dissimilar types. In some cases it also has some notion of commodities, and support for existing unit standards for strings and naming.
Basic use case
The primary use case for the library is string operations and conversion. For example if you have a library that does some computations with physical units. In the library code itself the units are standardized and well defined. For example take a velocity, internally everything is in meters per second, but there is a configuration file that takes in the initial data and you would like to broadly support different units on the input
#include <units/units.hpp>
double GetInputValueAs(const std::string &input, precise_units out)
{
auto meas=measurement_from_string(input);
return meas.value_as(out);
}
The return value can be checked for validity as an invalid conversion would result in constants::invalid_conversion or NaN so can be checked by std::isnan
or
if (!meas.units().is_convertible(out))
{
throw(std::invalid_argument);
}
Limitations
- The powers represented by units by default are limited. See Unit representation and only normal physical units or common operations are supported, this can be modified at compile time to support a much broader range at the expense of size and computation.
- The library uses floating point and double precision for the multipliers which is generally good enough for most engineering contexts, but does come with the limits and associated loss of precision for long series of calculations on floating point numbers.
- Currency is supported as a unit but it is not recommended to use this for anything beyond basic financial calculations. So, if you are doing a lot of financial calculations or accounting, use something more specific for currency manipulations. It also does not maintain any notion of currency conversions since those fluctuate in value. It may at some point recognize different currency names though commodities.
- Fractional unit powers are not supported in general. While some mathematical operations on units are supported any root operations
sqrtorcbrtwill only produce valid results if the result is integral powers of the base units. One exception is limited support for √Hz operations in measurements of Amplitude spectral density. A specific definition of a unit representing square root of Hz is available and will work in combination with other units. - While conversions of various temperature definitions are supported, there is no generalized support for datums and bias shifts. It may be possible to add some specific cases in the future for common uses cases but the space requirement limits such use. Some of the other libraries have general support for this.
- A few equation-like units are supported these include logarithms, nepers, and some things like Saffir-Simpson, Beaufort, and Fujita scales for wind, and Richter scales for earthquakes. There is capacity within the framework to add a few more equation like units if a need arises.
- There are several units where the specific definition differs when used in different domains. The unit
radin the nature of radiation absorbed dose is one such unit as it would conflicts withradin terms of radians. Soradmeans radians by default since that is the more common use in electrical engineering. The use of domains in the conversion operations can control this to some extent. For example the 'Nuclear' domain specifies thatradrefers to radiation absorbed dose instead of the angle.
Alternatives
If you are looking for compile-time and prevention of unit errors in equations for dimensional analysis one of these libraries might work for you.
- boost units -Zero-overhead dimensional analysis and unit/quantity manipulation and conversion in C++
- Units -A compile-time, header-only, dimensional analysis library built on
C++14with no dependencies. - Units -Another compile time library
- PhysUnits-CT A C++ library for compile-time dimensional analysis and unit/quantity manipulation and conversion.
- PhysUnits-RT -A C++ library for run-time dimensional analysis and unit/quantity manipulation and conversion.
- Libunits -The ultimate shared library to do calculations(!) and conversions with any units! Includes all SI and pseudo SI units and thousands of US, Imperial and other units.
- unitscpp -A lightweight C++ library for physical calculation with units.
- mpusz/units -A compile-time enabled Modern C++ library that provides compile-time dimensional analysis and unit/quantity manipulation. This library is in process for standardization in C++23/26.
- bernedom/SI -A header only C++ library that provides type safety and user defined literals for handling physical values defined in the International System of Units
These libraries will work well if the number of units being dealt with is known at compile time. Many also produce zero-overhead operations and checking
Related Skills
node-connect
333.7kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
82.0kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
333.7kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
82.0kCommit, push, and open a PR
