Numeric conversions for engineering notation and RKM code.
Overview
In engineering applications it is common to express quantities relative to the next-lower power of 1000, described by an SI (metric) prefix.
This is normally done by writing the SI multiplier after the quantity. In the "RKM code" variant, the SI multiplier replaces the decimal point.
For example:
| Number | Engineering | RKM |
|---|---|---|
| 42 | 42 | 42 |
| 999 | 999 | 999 |
| 1000 | 1k | 1k |
| 1500 | 1.5k | 1k5 |
| 42900 | 42.9k | 42k9 |
| 2340000 | 2.34M | 2M34 |
And so on going up the SI prefixes, including the new ones R (1027) and Q (1030) which were added in 2022.
This crate exists to support convenient conversion of numbers to/from engineering and RKM notation. The intended use case is reading user-entered strings from configuration files.
Detail
This crate is centred around the [EngineeringQuantity<T>] type.
- The generic parameter
Tspecifies the storage type to use for the significand. This can be any primitive integer except fori8oru8.- For example,
EngineeringQuantity<u64>.
- For example,
- The exponent is always stored as an
i8.
You can convert an EngineeringQuantity to:
- most primitive integer types (not
i8oru8) - String, directly by [
std::fmt::Display], or via the [DisplayAdapter] type for control over the output. - its component parts, as a tuple
(<StorageT>, i8)(seeto_raw) - another
EngineeringQuantityof a different storage type
You can create an EngineeringQuantity from:
- most primitive integer types (not
i8oru8) &str, byFromStr- this autodetects both standard and RKM code variants
- its component parts
(<StorageT>, i8)(seefrom_raw).
Primitive integers may be converted directly to string via the EngineeringRepr convenience trait.
Or, if you prefer, here are the type relations in diagram form:
╭─────────────────────╮ ╭─────────────────────╮ ╭───────────╮
│ integers │ │ integer types │ │ raw tuple │
│ (i16/u16 or larger) │ │ (where Into<T>) │ │ (T, i8) │
╰─────────────────────╯ ╰─────────────────────╯ ╰───────────╯
╵ ▲ │ ▲
╵ │ TryFrom │ From │ From
╵ │ ▼ ▼
╵ ┌───────────────────────────────────────────────────────────┐
╵ │ EngineeringQuantity<T> │
╵ └───────────────────────────────────────────────────────────┘
╵ │ ▲ │
╵ ┌─────────────────────┐ │ │ │
╵ impl │ EngineeringRepr │ │ (configurable │ FromStr │ Display
└−−−−−▶ │ (convenience trait) │ │ format) │ │
└─────────────────────┘ │ │ │
│ to_eng(), to_rkm() │ │ │
▼ │ │ │
┌─────────────────────┐ │ │ │
│ DisplayAdapter<T> │ ◀──┘ │ │
└─────────────────────┘ │ │
│ Display │ │
▼ │ │
╭─────────────────────╮ │ │
│ String │ ─────────────────────┘ │
╰─────────────────────╯ ◀───────────────────────────────┘
Examples
String to number
use EngineeringQuantity as EQ;
use FromStr as _;
// Standard notation
let eq = EQ::from_str.unwrap;
assert_eq!;
// RKM style notation
let eq2 = EQ::from_str.unwrap;
assert_eq!;
Number to string
use EngineeringQuantity as EQ;
// default precision (3 places)
let ee1 = EQ::from;
assert_eq!;
// explicit precision
let ee2 = EQ::from;
assert_eq!;
// RKM style
assert_eq!;
// Zero precision means "automatic, lossless"
assert_eq!;
assert_eq!;
Convenience trait
use EngineeringRepr as _;
assert_eq!;
assert_eq!; // automatic precision
assert_eq!;
Limitations
- This crate only supports integers at the present time. The smaller multipliers (m, μ, n, p, f, a, z, y, r, q) are not currently supported.
- Multipliers which are not a power of 1000 (da, h, d, c) are not supported.
Alternatives
- human-repr is great for converting numbers to human-friendly representations.
- humanize-rs is great for converting some human-friendly representations to numbers, though engineering-repr offers more flexibility.