dashu
A library set of arbitrary precision numbers (aka. big numbers) for mathematics and numerics, implemented in Rust. It's a Rust native alternative to GNU GMP + MPFR + MPC. It features:
- Pure rust, full
no_stdsupport. - Focus on ergonomics & readability, and then efficiency.
- Optimized speed and memory usage.
- Current MSRV is 1.68. The MSRV covers the default build (no optional features); optional
features may require a newer Rust version (e.g.
rkyv_v08needs Rust ≥ 1.81).
Sub-crates
dashu-base: Common trait definitionsdashu-int: Arbitrary precision integersdashu-float: Arbitrary precision floating point numbersdashu-ratio: Arbitrary precision rational numbersdashu-cmplx: Arbitrary precision complex numbersdashu-macros: Macros for creating big numbers
dashu is a meta crate that re-exports all the types from these sub-crates. Please see the README.md in each subdirectory for crate-specific introduction.
Examples
Construction & literal macros
Construct numbers with the compile-time literal macros (no precision loss, any size) and the meta-crate type aliases — readable names for every number domain:
use ;
use ;
// Compile-time literals — zero precision loss, any size
let n: Natural = ubig!;
let e: Real = fbig!;
let pi: Decimal = dbig!;
let r: Rational = rbig!;
let z: Complex = cbig!; // complex, decimal by default
// Meta-crate type aliases cover every number domain
let _neg: Integer = ibig!;
let _prod = &n * &_neg; // Natural × Integer → Integer
// Explicit radix and base prefixes work too
let _hex = ubig!;
let _bin = ibig!;
// Associated constants are available on every type
let _one: Natural = ONE;
let _unit = I; // the imaginary unit
String conversion
Parse from strings in any base, then format back with the full std::fmt mini-language —
hexadecimal, scientific, positional expansion, and more:
use ;
use FromStr;
// Parse from strings — any base, scientific notation, rational form
let a = from_str_radix.unwrap;
let b: Decimal = "3.1415926535897932384626".parse.unwrap;
let c: Rational = "22/7".parse.unwrap;
// Full std::fmt mini-language for every type
assert_eq!;
assert_eq!;
assert_eq!;
// in_radix formats in any base; {:.N} rounds the fractional digits
assert_eq!;
assert_eq!;
// Debug prints a compact head‥tail form for large values
assert_eq!;
Serialization
Enable the serde feature for compact binary encoding (e.g. postcard) and
human-readable JSON round-trips with precision preserved:
// requires: features = ["serde"]
use ;
// Binary format: compact little-endian byte encoding
let a = from;
let bytes = to_stdvec.unwrap;
let b: Integer = from_bytes.unwrap;
assert_eq!;
// Human-readable: precision-preserving string format
let r = from_parts;
let json = to_string.unwrap;
assert_eq!;
// JSON round-trips preserve the value exactly
let rt: Rational = from_str.unwrap;
assert_eq!;
// Floats serialize losslessly too, with precision preserved
let x: Real = "0x1.8p0".parse.unwrap; // 1.5
let json2 = to_string.unwrap;
let _rt: Real = from_str.unwrap;
Random numbers
Enable the rand feature for uniform sampling — integers of a given bit-length,
floats in [0, 1) at a chosen precision, and more:
// requires: features = ["rand"]
use ;
use BitTest;
use UniformBits;
use Uniform01;
use RngExt;
let mut rng = rng;
// Uniform random integers with a bit-length limit
let a: Natural = rng.sample;
let b: Integer = rng.sample;
assert!;
// Uniform floats in [0, 1) at chosen precisions
let x: Real = rng.sample; // binary64
let _y: Real = rng.sample; // higher precision
assert!;
// sample_iter streams an unbounded sequence
let _stream: = rng.sample_iter.take.collect;
Type conversion
Convert freely between number domains — binary to decimal floats, floats to rationals (recovering the human-intended fraction), floats to integers with a rounding direction:
use Zero;
use ;
// Base conversion: binary (Real) ↔ decimal (Decimal)
let x: Decimal = "3.141592653589793".parse.unwrap;
let y = x.to_binary.value; // Decimal → binary float
let _back = y.to_decimal.value; // and back
// Float → rational: recover the fraction the programmer meant
let r = simplest_from_f64.unwrap;
assert_eq!;
// Float → integer with a rounding direction
let floor: Integer = y.to_int.value; // truncates toward zero
assert_eq!;
// Exact rational → float at a chosen precision
let third = from_parts;
let _f = third..value; // 1/3 in base 2
Python package
dashu-python is a user-friendly test field for the core dashu
functionalities: through the dashu-rs
package on PyPI, users can try dashu's arbitrary-precision integers, rationals,
floats, and complex numbers from Python to get an idea of what dashu is capable
of — no Rust toolchain needed. Beyond exploring dashu, it also stands on its own
as a standalone arbitrary-precision number package for the Python ecosystem.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.