dsp-fixedpoint
no_std fixed-point arithmetic with explicit storage, accumulator, and
quantization boundaries.
Type shape
Q<T, A, F> stores raw T bits scaled by 2^-F; products accumulate in A.
T: stored and signal valueA: wide accumulatorF: fractional bits
Aliases include Q32<F> = Q<i32, i64, F> and wrapping/unsigned variants.
Wide MAC, late quantization
Put the coefficient on the left and the raw signal on the right:
use Q32;
type C = ;
let a = ;
let x = ;
let mut acc = a * x; // Q<i64, i32, 28>
acc += a * x; // still wide
let y = acc.quantize; // one shift and narrowing conversion
assert_eq!;
The shape is Q<T, A, F> * T -> Q<A, T, F>. Accumulate products of that type,
then call quantize() once. Reversing the operands, T * Q -> T, quantizes each
product immediately.
Construction
from_int and from_f32/from_f64 construct scaled values; from_bits
preserves raw bits. FromRatio constructs a coefficient from two raw values:
use ;
let gain = Q32::from_ratio;
assert!;
For positive F, FromRatio widens the numerator before scaling and division.
The denominator must be nonzero and the result must fit T.
Operators
| Operation | Result | Quantization |
|---|---|---|
Q * T |
Q<A, T, F> |
none; wide product |
T * Q |
T |
immediate |
Q * Q, Q / Q |
Q<T, A, F> |
immediate |
Q + Q, Q - Q |
Q<T, A, F> |
none; equal F required |
T / Q |
T |
immediate |
mul_wide() and apply() spell Q * T and T * Q explicitly.
Scale and conversion
Use .scale::<F1>() when changing fractional bits. Numeric traits convert the
represented value; from_bits/into_bits access the representation.
Q::<_, _, -128>::DELTA is invalid. One is available only when 1 is exactly
representable by T and F.
Optional integrations
serde: transparent raw representation;serde::as_f32/as_f64for scaled values.defmt: compact decimal logging throughf32.bytemuck:Pod,Zeroable, andTransparentWrapperwhen the component types permit them.
Display is decimal. Binary, octal, and hexadecimal formatting place the radix
point according to F.