|
Unit Conversion and Dimensional Analysis Library 3.6.1
A compile-time, header-only C++23 dimensional-analysis library
|
Call <cmath>-style functions on quantities directly — sqrt(area), hypot(a, b), sin(angle) — and get dimensionally correct results.
The library provides unit-aware overloads of the standard math functions. They preserve or transform dimensions correctly: sqrt of an area is a length, pow<2> of a length is an area, the trigonometric functions take an angle and return a dimensionless ratio. You write them exactly as you would the <cmath> originals — unqualified.
Related how-to guides: defining new units, chrono interop, JSON serialization.
The math wrappers live in namespace units. Because a quantity's type is in namespace units, an unqualified call is found by argument-dependent lookup (ADL): naming sqrt(x) with a units argument selects the unit-aware overload, no qualification required.
Note: the 2.x units::math namespace has been removed. Code that wrote units::math::sqrt(x) or math::fma(...) must drop the math:: and call the function unqualified (ADL) or, if it must qualify, units::sqrt(x). There is no units::math to resolve against.
Every function below is in namespace units (except the four classifiers noted separately) and is found by ADL on a units argument.
| Category | Functions | Dimensional behavior |
|---|---|---|
| Powers and roots | pow<N>, sqrt, cbrt | pow<N> raises the dimension to N; sqrt/cbrt take the root of the dimension |
| Distance / mixing | hypot | operands share a dimension; result is that dimension |
| Rounding | floor, ceil, round, trunc | dimension preserved |
| Sign and difference | abs, fabs, copysign, fdim, fmod | dimension preserved (copysign/fdim/fmod on same-dimension operands) |
| Min / max | min, max, fmin, fmax | dimension preserved; operands share a dimension |
| Fused multiply-add | fma | result dimension is (x·y) combined with z |
| Exponential / logarithmic | exp, exp2, expm1, log, log2, log10, log1p | argument and result are dimensionless |
| Trigonometric | sin, cos, tan | take an angle, return dimensionless |
| Inverse trigonometric | asin, acos, atan, atan2 | take dimensionless, return radians |
| Hyperbolic | sinh, cosh, tanh | take an angle, return dimensionless |
| Inverse hyperbolic | asinh, acosh, atanh | take dimensionless, return radians |
| Decomposition | modf | returns the fractional part; integer part written through the pointer |
| Classification | isnan, isinf, isfinite, isnormal, signbit, isunordered | return bool |
pow<N> is a template on the integer exponent, so the result dimension is known at compile time:
hypot(a, b) computes sqrt(a^2 + b^2) on two same-dimension quantities and returns that dimension:
The forward trig and hyperbolic functions accept an angle unit — a plain double will not bind. They return a dimensionless ratio.
Caveat: passing a raw number to sin/cos/tan selects the <cmath> overload, not this one, and treats the value as already-in-radians. Pass an angle quantity (45.0_deg, 1.0_rad) to get the unit-checked behavior. See the diagnostic in type safety for the error a bare number produces on some call sites.
exp, log, and their relatives operate on and produce dimensionless quantities, matching the mathematics — the logarithm of a length has no meaning:
isnan, isinf, isfinite, and isnormal are in namespace units and are found by ADL:
Caveat: signbit (and the std-side isnan/isinf/isfinite overloads that exist to win against the <cmath> templates) are declared in namespace std, not namespace units. signbit in particular is not found by ADL on a units argument and is not a member of units; call it qualified:
Unqualified ADL is the intended way to call these, and normally there is no ambiguity: std::sqrt and the like do not accept a units argument, so even with using std::sqrt; in scope the units overload is the only viable candidate. If a third-party using-declaration or another library ever brings a competing overload into scope and a call does become ambiguous, qualify explicitly with units:::
This is the same units:: qualification that resolves any ambiguity elsewhere in the library; reach for it only when the compiler reports an ambiguous call.