exact_units¶
Units of measure fixed at compile time, exact.
A number carries its unit, its scale and its storage in its type. The compiler checks them. At run time it is just the integer.
use exact_units::{Fixed, Micros, prefix::Milli};
let t: Micros<u32> = Fixed::new(1500); // 1500 µs, stored as a u32
assert_eq!(t.to_string(), "1500 µs");
assert_eq!(t.to::<Milli, u16>(), None); // not a whole number of ms: refused
assert_eq!(size_of::<Micros<u32>>(), 4); // the same bytes as the u32
What it is for¶
- Firmware and device APIs that keep numbers as integers: µs timers, mV readings, Q15 samples, binary angles.
- Conversions that are exact or refused, never rounded through a float.
- The cases other unit crates leave out: temperatures as points, angles that wrap, levels in dB, counted things.
How to read this book¶
The book goes from easy to deep. Each page has a badge with its reading level.
- Why: what goes wrong with a plain
u32, and what the type fixes. - First steps:
Fixed, units, prefixes, printing, literals. - Doing maths: arithmetic, conversions, bounds, rounding, overflow.
- Fixed point: Q15, Q31 and binary angles for DSP and motor control.
- Points: temperatures, angles that wrap, sensor register formulas, indices.
- Levels: dB and neper, thresholds as integer compares.
- Complex: impedances, IQ samples, CORDIC.
- Your units: customary units, and units of your own.
- The wire: the same bytes on the wire, the unit in the API.
- Nomicon: exact magnitudes, how conversions are chosen, how the crate is tested.
The recipes are short answers to common tasks.
Add it¶
A firmware picks only what it uses: see On a microcontroller.