View on GitHub

malachite

An arbitrary-precision arithmetic library for Rust.

Logo

Malachite is an arbitrary-precision arithmetic library for Rust. It achieves high performance in part by using algorithms derived from GMP, FLINT, and MPFR.

The documentation for Malachite is here, and its crate is here.

Coming from another arithmetic library? The mapping pages list each library’s functions next to their Malachite counterparts, section by section, and mark the ones Malachite does not have yet: GMP’s integers and rationals, FLINT’s integers, integers mod n, and rationals, MPFR’s floats, and num’s integers, rationals, and traits are covered today, with more FLINT pages to follow.

use malachite::base::num::arithmetic::traits::Factorial;
use malachite::Natural;

fn main() {
    println!("{}", Natural::factorial(100));
}

The code above outputs the following:

93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

You have to scroll to see the entire output.

Here is Ramanujan’s constant, \(e^{\pi \sqrt{163}}\), which is famously, and not by coincidence, within a trillionth of an integer. Computing it takes real arbitrary-precision machinery: a transcendental constant, a square root, and an exponential, each correctly rounded to 200 bits. Only the starting values name a precision; every operation after that inherits the precision of its input, or the larger precision of its two inputs. The default rounding mode is round-to-nearest, but every function that rounds also has a variant that lets you specify one of six rounding modes.

Float support is enabled by the floats feature.

use malachite::base::num::arithmetic::traits::{Exp, Sqrt};
use malachite::base::num::conversion::string::options::ToSciOptions;
use malachite::base::num::conversion::traits::ToSci;
use malachite::Float;

fn main() {
    let prec = 200;
    let pi = Float::pi_prec(prec).0;
    let sqrt_163 = Float::from_unsigned_prec(163u32, prec).0.sqrt();
    let almost_integer = (pi * sqrt_163).exp();
    let mut options = ToSciOptions::default();
    options.set_precision(45);
    println!("{}", almost_integer.to_sci_with_options(options));
}

The output is this, with twelve nines after the decimal point:

262537412640768743.999999999999250072597198186

Every digit is correct, except that in the least-significant place, a 5 has been rounded up to a 6. Each operation returns its result along with an Ordering reporting whether that result is below, equal to, or above the exact value; the example discards them with .0, but they are how you track exactness through a computation.

Exactness is sometimes the whole story. The polynomial below is from Rump’s example, evaluated at \(x = 77617\) and \(y = 33096\).

use malachite::base::num::arithmetic::traits::Square;
use malachite::base::num::basic::traits::Two;
use malachite::base::num::conversion::string::options::ToSciOptions;
use malachite::base::num::conversion::traits::ToSci;
use malachite::Rational;

fn main() {
    let (x, y) = (Rational::from(77617), Rational::from(33096));
    let x2 = (&x).square();
    let y2 = (&y).square();
    let y4 = (&y2).square();
    let y6 = &y4 * &y2;
    let y8 = (&y4).square();
    let inner =
        Rational::from(11) * &x2 * y2 - &y6 - Rational::from(121) * y4 - Rational::TWO;
    let exact = Rational::from_signeds(1335, 4) * y6
        + x2 * inner
        + Rational::from_signeds(11, 2) * y8
        + x / (Rational::TWO * y);
    let mut options = ToSciOptions::default();
    options.set_precision(20);
    println!("{} ≈ {}", exact, exact.to_sci_with_options(options));
}

The output is this:

-54767/66192 ≈ -0.82739605994682136814

The same formula evaluated in f64 arithmetic gives roughly \(-1.18 \times 10^{21}\): off by twenty-one orders of magnitude. In Rump’s original 1988 paper, an IBM mainframe was wrong more subtly: single, double, and extended precision all agreed on \(+1.172603\ldots\).

Malachite is designed to work with very large numbers efficiently. See here for a performance comparison against other libraries.

Malachite uses no_std, unless the random, test_build, or bin_build features are enabled.

To use Malachite, add the following to your project’s Cargo.toml file:

[dependencies.malachite]
version = "0.10.0"

By default, Malachite includes Natural, Integer, and Rational. Float support is opt-in:

[dependencies.malachite]
version = "0.10.0"
features = [ "floats" ]

You can also opt out of the types you don’t need. For example, if you want to use Natural and Integer but not Rational, you can use

[dependencies.malachite]
version = "0.10.0"
default-features = false
features = [ "naturals_and_integers" ]

The malachite crate re-exports four sub-crates.

Malachite is under active development, with many more types and features planned for the future. Nonetheless, it is extensively tested and documented, and ready for use today. Just be aware that its API is not stable yet, and that Malachite is licensed under LGPL 3.0.

Malachite is developed by Mikhail Hogrefe. malachite-bigint, a drop-in num-bigint replacement based on Malachite, was created by Steve Shi and is now maintained by Mikhail Hogrefe. Thanks to 43615, b4D8, Romain Billot, Maxim Biryukov, coolreader18, Dasaav-dsv, Duncan Freeman, florian1345, konstin, Rowan Hart, YunWon Jeong, Park Joon-Kyu, Antonio Mamić, OliverNChalk, Kevin Phoenix, probablykasper, shekohex, skycloudd, John Vandenberg, Brandon Weeks, and Will Youmans for additional contributions.

FAQ

How is “Malachite” pronounced, and what does it mean? “Malachite” is pronounced MA-luh-kite, or /ˈmæl.əˌkaɪt/. It is the name of a green gemstone. Unfortunately, malachite does not contain iron, which would have made it a particularly good namesake for a Rust library.

Malachite’s logo is an image of a snub cube.

When does Malachite allocate memory? Any Natural less than \(2^{64}\) is represented inline, without allocating memory. Any Integer whose absolute value is less than \(2^{64}\) doesn’t allocate either, and neither does any Rational whose absolute numerator and denominator are both less than \(2^{64}\). If you’re using a build with --features 32_bit_limbs, then the threshold is \(2^{32}\) instead.

Can I build Malachite for WebAssembly? Yes. If, in the future, Malachite includes code incompatible with Wasm (for example, code that uses rayon), it will be possible to disable that code with cargo flags.

Blog Posts

Copyright © 2026 Mikhail Hogrefe