尚未收集仓库信息。
尚未检测到更新。GitHub 发布版本后会显示在这里。
Units of measure checked at compile time: exact scales, no_std, no alloc, the same bytes as the plain integer
翻译准备中
正在加载完整 README。
查看完整 README ↗Units of measure checked at compile time, with exact scales and the cases other unit crates leave out: a number with its unit, scale and storage in the type, the same bytes as the plain integer,
no_stdand no alloc.
What exact means here: no hidden gotchas. Every scale is an exact fraction times exact symbols (π, ln 2, ln 10), never a float. A conversion gives the exact value or refuses it, at compile time where it can. Anything that loses information (rounding, saturating, wrapping, going to a float) is a call or a type that names its policy. A measured constant of nature stays a symbol, and a number for it appears only where you ask for one, with its source. Conventions (which gallon, which ADC step) are names you pick, never defaults. The safe way is the short way, and each of these claims is checked by properties, proofs and tests. The book's What exact means page has an example per rule, and lists where the crate falls short today.
use exact_units::{Fixed, Micros, Point, origins::{Celsius, Fahrenheit}};
use exact_units::prefix::{Centi, Kibi, Milli, One, Rational};
use exact_units::units::{Byte, Kelvin};
// exact or refused, never rounded through a float
let t: Micros<u32> = Fixed::new(1500);
assert_eq!(t.to::<Milli, u16>(), None); // 1500 µs is not a whole number of ms
assert_eq!(Fixed::<Byte, Kibi, u16>::new(4).to::<One, u32>(), Some(Fixed::new(4096)));
// a temperature is a point against an origin, not an amount of kelvin
type DegF = Point<Fahrenheit, Fixed<Kelvin, Rational<5, 9>, i16>>;
type DegC = Point<Celsius, Fixed<Kelvin, Centi, i16>>;
assert_eq!(DegF::from_raw(212).to::<Celsius, Centi, i16>(), Some(DegC::from_raw(10000)));
assert_eq!(DegC::from_raw(2500).to_string(), "25 °C");
// zero cost: the type is the integer
assert_eq!(size_of::<Micros<u32>>(), size_of::<u32>());
And what doesn't compile:
use exact_units::{Fixed, prefix::One, units::{Joule, Torque}};
// angle is a dimension: a torque is N·m per radian, not an energy
let _ = Fixed::<Torque, One, i32>::new(5).convert::<Joule, One, i32>();
use exact_units::{Fixed, prefix::One, units::{AngularVelocity, Hertz}};
// 50 Hz is not 50 rad/s
let _ = Fixed::<Hertz, One, u32>::new(50).convert::<AngularVelocity, One, u32>();
use exact_units::{Index, units::Sample};
// two positions don't add up; a position and an amount do
let _ = Index::<Sample, u32>::new(1) + Index::<Sample, u32>::new(2);
exact.vhrd.tech is the guide, from first steps to the internals: units and scales, conversions and rounding, Q15 and binary angles, temperatures and other points, levels in dB, complex numbers and CORDIC, custom units, the wire format, and how the crate is tested. Every example in it runs as a doctest. Build it locally with just docs (needs uv).
The API reference is on docs.rs.
None or doesn't compile.Fixed is #[repr(transparent)] over its integer: the same bytes, and on Cortex-M the same instructions.Exact<Hertz> of 80/3 MHz, worked out on a host, printed 26.[6] MHz, read back from a config, compared with any Fixed exactly.Uncertain<U> holds a value and its standard uncertainty exactly as CODATA, AME and NUBASE print them (6.674 30(15)e-11, a value and a ± column), and refuses estimated values (#), limits and asymmetric uncertainties by name.fixed!(0.1) and db!(-3) as compile-time constants.no_std, no alloc, no dependencies without features (q!, on by default, is a proc-macro crate of this repository, itself without dependencies); WireWeaver's wire format with shrink_wrap.以上为 README 的开头部分。其余内容请阅读原文。 查看完整 README ↗