#mpfr #gmp #bignum #multiple-precision

sys mpir

partial Rust porting of mpir multiple precision library based on gmp mpfr

4 releases

new 0.4.4 Apr 14, 2025
0.4.3 Apr 11, 2025
0.3.5 Apr 1, 2025
0.3.4 Mar 31, 2025
0.0.2 Mar 8, 2025

#2107 in Math

Download history 141/week @ 2025-03-02 758/week @ 2025-03-09 753/week @ 2025-03-16 615/week @ 2025-03-23 487/week @ 2025-03-30 542/week @ 2025-04-06

2,493 downloads per month
Used in test_gmp_mpir

MIT license

1.5MB
6K SLoC

Contains (Windows DLL, 600KB) mpir/bin/mpir.dll, (Windows DLL, 510KB) mpir/bin/libgmp-10.dll, (static library, 130KB) mpir/lib/libgmp-10.lib, (static library, 125KB) mpir/lib/mpir.lib, (static library, 39KB) mpir/lib/libgmpxx-4.lib, (Windows DLL, 31KB) mpir/bin/libgmpxx-4.dll

mpir

partial Rust porting of mpir multiple precision library based on gmp mpfr

Sample

see also sum_arctan_gregory() source

  mpf_set_default_prec(64); // 64 bits default

  // inv_f
  let a = &mpz_s::from(-3);
  let mut f = a.inv_f();
  assert_eq!(format!("{}", f), "-0.33333333333333333333e+0");
  f *= 3;
  assert_eq!(format!("{}", f), "-0.1e+1");

  // inv_f
  let a = &mpz_s::from(-2);
  let f = a.inv_f();
  assert_eq!(format!("{}", f), "-0.5e+0");

  // inv_q
  let a = &mpz_s::from(-2);
  let q = &mut a.inv_q();
  assert_eq!(format!("{}", q), "1/-2");
  assert_eq!(format!("{}", q.reduce()), "1/-2");
  assert_eq!(format!("{}", q.inv()), "-2");

  // mpf from mpq
  let f = mpf_s::from(q);
  assert_eq!(format!("{}", f), "-0.5e+0");
  assert_eq!(format!("{}", f.inv()), "-0.2e+1");

  // mpq from &str
  let f = &mut mpq_s::from("9/-24");
  assert_eq!(format!("{}", f), "9/-24");
  assert_eq!(format!("{}", f.reduce()), "3/-8");

  // mpf from &str
  let f = mpf_s::from("-5");
  assert_eq!(format!("{}", f), "-0.5e+1");

  // mpz from &str
  let f = mpz_s::from("-5");
  assert_eq!(format!("{}", f), "-5");

  // mpz and mpf check about (default) significant digits
  let a = mpz_s::from("987654321098765432109");
  assert_eq!(format!("{}", a), "987654321098765432109"); // 21 digits
  let mut f = mpf_s::from(a);
  f /= mpf_s::from("1.0e+11"); // drift
  assert_eq!(format!("{}", f),
    "0.98765432109876543211e+10"); // 20 digits by default formatter
  assert_eq!(f.fmtstr(10, 22), // check to 22 digits
    "0.987654321098765432109e+10"); // 21 digits ok

  // mpf
  assert_eq!(format!("{}", 1 / mpf_s::from(3)),
    "0.33333333333333333333e+0"); // 1 / 3
  assert_eq!(format!("{}", mpf_s::from(1) / 3),
    "0.33333333333333333333e+0"); // 1 / 3
  assert_eq!(1 / mpf_s::from(3), mpf_s::from(1) / 3); // 1 / 3
  assert_eq!(format!("{}", 2 / mpf_s::from(3)),
    "0.66666666666666666667e+0"); // 2 / 3
  assert_eq!(format!("{}", mpf_s::from(2) / 3),
    "0.66666666666666666667e+0"); // 2 / 3
  assert_eq!(2 / mpf_s::from(3), mpf_s::from(2) / 3); // 2 / 3

  // mpz fact
  let facts = vec![
    "1", "1", "2", "6", "24", "120", "720", "5040", "40320", "362880", // 0-9
    "3628800", "39916800", "479001600", "6227020800", "87178291200", // 10-14
    "1307674368000", "20922789888000", "355687428096000", // 15-17
    "6402373705728000", "121645100408832000", "2432902008176640000"]; // 18-20
  (0..=20).for_each(|n: usize| {
    let t = &mpz_s::fact(n as ui_t);
    assert_eq!(format!("{}! = {}", n, t), format!("{}! = {}", n, facts[n]));
    let u = &mpz_s::fac_ui(n as ui_t);
    assert_eq!(format!("{}! = {}", n, t), format!("{}! = {}", n, u));
  });

  // mpz fact cached
  let m = &mut HashMap::<ui_t, mpz_s>::new();
  (0..=20).for_each(|n: usize| {
    let t = &mpz_s::fact_cached(n as ui_t, m);
    assert_eq!(format!("{}! = {}", n, t), format!("{}! = {}", n, facts[n]));
  });

  // mpq
  let q = &mpq_s::from((2, 8 as ui_t));
  assert_eq!(format!("{}", q), "2/8");

  // mpf prec
//  assert_eq!(mpf_get_default_prec(), 64); // may be 64
  mpf_set_default_prec(100); // 100 set to 128 bits (step by 2**n)
//  assert_eq!(mpf_get_default_prec(), 128); // may be 128 (about 38 digits)
  let digits = mpf_s::calc_digits_from_bits(128);
  assert_eq!(digits, 38); // may be 38

  // mpf significant digits test loss of digits on display
  let disp_digits = digits + 3; // set disp_digits to over prec
  let f = &mut mpf_s::from("1.0e-19");
  let e = &mpf_s::from("1.0e-50");
  assert_eq!(e.fmtstr(10, disp_digits), "0.1e-49");
  assert_eq!(f.fmtstr(10, disp_digits), "0.1e-18");
  // f.add(e) as 0.99999999999999999999e-19 without mpf_set_default_prec(100)
  assert_eq!(f.add(e).fmtstr(10, disp_digits), // use disp_digits
    "0.1000000000000000000000000000000099999999e-18"); // disp over prec
  assert_eq!(f.fmtstr(10, digits), // use digits
    "0.10000000000000000000000000000001e-18"); // disp as match with prec

  // mpf calc napier
  let digits = 150;
  mpf_set_default_prec(mpf_s::calc_bits_from_digits(digits + 3));
  let e = &util::Sigma::from(digits).calc_napier(&mpf_s::from(1.0));
  assert_eq!(format!("{}", e),
    "0.27182818284590452354e+1");
  assert_eq!(e.fmtstr(10, digits),
    "0.271828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526e+1");
/*
  2.
  7182818284 5904523536 0287471352 6624977572 4709369995
  9574966967 6277240766 3035354759 4571382178 5251664274
  2746639193 2003059921 8174135966 2904357290 0334295260
  ...
*/

Misc

Requirements

License

MIT License

Dependencies

~2–15MB
~134K SLoC