Introduction
ddust is a Rust crate of fixed-point decimals. Its Decimal, a Decimal<I, S>, is a whole number of steps of , held in one of Rust’s ten
integers, at a scale the compiler knows or one carried at run time. It is for
code in which a lost digit is a bug: prices, quantities, balances, fees and
rates, and the messages and files that carry them as text.
A binary float cannot hold 0.1. A sum of prices in f64 drifts, and writing one
back as text means guessing which decimal it was. A decimal holds 0.1 exactly,
and ddust’s keeps three promises:
- Nothing loses a digit unless a rounding mode says so.
a * bis exact, its scale the sum of the factors’;a / btruncates toward zero, as the integer’s does; and every other operation that can lose a digit takes a rounding mode as its last argument. - Scales never mix by accident. Two static scales are two types, so a
D64<2>plus aD64<4>does not compile. Two scales known only at run time line up exactly at the finer one, as SQL’sDECIMALdoes. - Every operator behaves as the integer’s. A
D64<2>is ani64and adds as one. Overflow panics with overflow checks on and wraps otherwise, and each operator has the integer’schecked_*,saturating_*,wrapping_*andoverflowing_*methods.
What It Holds
- The decimal,
Decimal, with an alias for each integer at a static scale:D8toD128andUD8toUD128.dec!writes a literal that is checked when the constant is evaluated. - Scales:
Fixed<D>, known to the compiler and zero-sized, andDynamic, carried at run time. - Rounding: nine modes in
round, each a zero-sized type, andRounding, a mode chosen at run time.Divisorprepares one divisor for many divisions. - Text: reading that is exact or refused, from a slice or in place inside a
message, and writing through
Displayor into a byte buffer, with no formatter. - Floats: the nearest
f64, correctly rounded, and a double to a decimal by a rounding mode. - Integrations, each behind a feature: serde, num-traits, bytemuck, zerocopy, rand, proptest, arbitrary and defmt.
The crate is #![no_std], allocates nothing, and has no dependencies unless a
feature asks for one.
What It Leaves Out
- Arbitrary precision. A decimal holds at most 38 decimals and its integer’s
range: about ±9.2 × 10¹⁶ at two decimals in an
i64, and about ±1.7 × 10²⁰ at eighteen in ani128. - A scale that each operation chooses. rust_decimal’s values carry their own scale, up to 28 decimals, and a quotient takes as many decimals as fit. In ddust a scale is chosen by the caller; a quotient is at the dividend’s scale, or at one its rounding names.
- NaN, the infinities and negative zero, which a float has and a decimal does not need.
- Square roots, logarithms, powers and trigonometry.
- Stable Rust. ddust builds on nightly, from
nightly-2026-09-28: its arithmetic, rounding and literals areconst fnthrough const traits, which are not stable yet.
Compared with Others says when another crate is the better choice.
This Book
The guide comes first: Getting Started, then a chapter for each idea in the order a program meets it, from Decimals and Scales to Serialization, and Choosing a Decimal. The reference follows: what each operation costs, the platforms and features, the crates ddust works with, testing code that uses it, and how it compares with the other decimal crates.