Expand description
§Fixed point primitives
dsp-fixedpoint provides small no_std fixed-point primitives with explicit
integer storage and widening accumulators.
§Model
Q<T, A, F> stores a raw integer T and interprets it as scaled by 2^F.
Tis the storage type.Ais the widened accumulator type used for intermediate results.Fis the number of fractional bits.
Type aliases cover the common signed, unsigned, and wrapping pairs:
Q8/Q16/Q32/Q64, P8/P16/P32/P64, W8/W16/W32/W64, and V8/V16/V32/V64.
§Construction
There are two construction modes:
from_int,from_f32, andfrom_f64scale into the fixed-point domain.from_bitsis the raw-representation constructor.
use dsp_fixedpoint::Q8;
let scaled = Q8::<4>::from_int(3);
let raw = Q8::<4>::from_bits(3 << 4);
assert_eq!(scaled, raw);
assert_eq!(raw.into_bits(), 48);§Operator semantics
The crate keeps addition-like operators conservative and multiplication-like
operators efficient. Q means Q<T, A, F> unless shown otherwise.
| Operation | Result | Notes |
|---|---|---|
Q<F> + Q<F>, Q<F> - Q<F>, Q<F> % Q<F> | Q<T, A, F> | Requires the same F; use .scale::<F1>() explicitly when scales differ. |
Q * Q, Q / Q | Q<T, A, F> | Preserves the left-hand scale and quantizes the fixed-point result. |
Q * T | Q<A, T, F> | Widened raw-integer multiplication; same as q.mul_wide(t). |
T * Q | T | Applies Q as a gain to T and quantizes; same as q.apply(t). |
Q / T | Q<T, A, F> | Raw integer division of the stored representation. |
T / Q | T | Divides by Q as a fixed-point gain and quantizes. |
Q *= Q, Q /= Q | Q<T, A, F> | Assignment forms follow the left-hand scale. |
Q *= T, Q /= T | Q<T, A, F> | Assignment forms operate on the raw stored representation. |
The mixed multiplication and division asymmetry is intentional: operand order
chooses whether the result remains wide or is quantized immediately. Use
mul_wide() and apply() when spelling that choice explicitly is clearer than
relying on operand order.
§Scale restrictions
F is an i8, but not every i8 value is meaningful everywhere.
Q::<_, _, -128>::DELTAis rejected at compile time.Q::<_, _, F>::one()andQ::<_, _, F>::ONEare rejected at compile time when the mathematical value1is not exactly representable by the storage type and scale.
use dsp_fixedpoint::Q8;
use num_traits::One;
let _ = Q8::<7>::one();§Serialization
With feature = "serde", Q serializes transparently as its raw representation.
For lossy scaled values, use dsp_fixedpoint::serde::as_f32 or
dsp_fixedpoint::serde::as_f64.
use dsp_fixedpoint::Q32;
#[derive(Deserialize, Serialize)]
struct Config {
#[serde(with = "dsp_fixedpoint::serde::as_f64")]
gain: Q32<3>,
}§Ecosystem Traits
Q implements a small set of generic numeric traits where the semantics stay
clear:
Boundedforwards to the raw storage bounds.ToPrimitive,FromPrimitive, andNumCastconvert numeric values rather than raw bits.Signedis implemented for signedQ/Wfamilies.Hashfollows the raw representation.
Signed inherits One, so the existing representability restriction still
applies: operations that need an exact 1, such as signum(), are only usable
when F >= 0.
§Formatting
Display shows decimal notation. Binary/Octal/UpperHex/LowerHex show dot
notation.
use dsp_fixedpoint::Q8;
assert_eq!(
format!("{:#b}", Q8::<3>::from_bits(0b01101001)),
"0b1101.001"
);
assert_eq!(format!("{:x}", Q8::<4>::from_bits(-0x14)), "-1.4");§defmt
With feature = "defmt", Q implements defmt::Format and logs as a decimal
value using f32. This keeps the target-side implementation compact for
embedded use. Exact radix-dot formatting remains available through the standard
Binary, Octal, and hex format traits.
§bytemuck
With feature = "bytemuck", Q derives Pod, Zeroable, and
TransparentWrapper. That makes zero-copy buffer casts and wrapper conversions
available when the underlying storage and accumulator types also satisfy the
corresponding bytemuck bounds.
Modules§
- serde
- Serde adapters for fixed-point wire formats.
Structs§
- Q
- Fixed point integer
Traits§
Type Aliases§
- P8
- Fixed point
u8withu16accumulator - P16
- Fixed point
u16withu32accumulator - P32
- Fixed point
u32withu64accumulator - P64
- Fixed point
u64withu128accumulator - Q8
- Fixed point
i8withi16accumulator - Q16
- Fixed point
i16withi32accumulator - Q32
- Fixed point
i32withi64accumulator - Q64
- Fixed point
i64withi128accumulator - V8
- Fixed point
Wrapping< u8 >withWrapping< u16 >accumulator - V16
- Fixed point
Wrapping< u16 >withWrapping< u32 >accumulator - V32
- Fixed point
Wrapping< u32 >withWrapping< u64 >accumulator - V64
- Fixed point
Wrapping< u64 >withWrapping< u128 >accumulator - W8
- Fixed point
Wrapping< i8 >withWrapping< i16 >accumulator - W16
- Fixed point
Wrapping< i16 >withWrapping< i32 >accumulator - W32
- Fixed point
Wrapping< i32 >withWrapping< i64 >accumulator - W64
- Fixed point
Wrapping< i64 >withWrapping< i128 >accumulator