malachite-nz 0.3.2

The bignum types Natural and Integer, with efficient algorithms partially derived from GMP and FLINT
Documentation
use malachite_base::num::arithmetic::traits::{Mod, ModAdd, ModIsReduced, ModNeg, ModNegAssign};
use malachite_base::num::basic::traits::Zero;
use malachite_base::test_util::generators::unsigned_pair_gen_var_16;
use malachite_nz::integer::Integer;
use malachite_nz::natural::Natural;
use malachite_nz::platform::Limb;
use malachite_nz::test_util::generators::natural_pair_gen_var_8;
use std::str::FromStr;

#[test]
fn test_mod_neg() {
    let test = |s, t, out| {
        let u = Natural::from_str(s).unwrap();
        let v = Natural::from_str(t).unwrap();

        assert!(u.mod_is_reduced(&v));
        let n = u.clone().mod_neg(v.clone());
        assert!(n.is_valid());
        assert!(n.mod_is_reduced(&v));
        assert_eq!(n.to_string(), out);

        let n = u.clone().mod_neg(&v);
        assert_eq!(n.to_string(), out);
        assert!(n.is_valid());

        let n = (&u).mod_neg(v.clone());
        assert_eq!(n.to_string(), out);
        assert!(n.is_valid());

        let n = (&u).mod_neg(&v);
        assert_eq!(n.to_string(), out);
        assert!(n.is_valid());

        let mut n = u.clone();
        n.mod_neg_assign(v.clone());
        assert!(n.is_valid());
        assert_eq!(n.to_string(), out);

        let mut n = u;
        n.mod_neg_assign(&v);
        assert!(n.is_valid());
        assert_eq!(n.to_string(), out);
    };
    test("0", "5", "0");
    test("7", "10", "3");
    test("100", "101", "1");
    test("4294967294", "4294967295", "1");
    test("1", "4294967295", "4294967294");
    test("7", "1000000000000", "999999999993");
    test("999999999993", "1000000000000", "7");
}

#[test]
fn mod_neg_properties() {
    natural_pair_gen_var_8().test_properties(|(n, m)| {
        assert!(n.mod_is_reduced(&m));
        let neg = (&n).mod_neg(&m);
        assert!(neg.is_valid());
        assert!(neg.mod_is_reduced(&m));

        let neg_alt = (&n).mod_neg(m.clone());
        assert!(neg_alt.is_valid());
        assert_eq!(neg_alt, neg);

        let neg_alt = n.clone().mod_neg(&m);
        assert!(neg_alt.is_valid());
        assert_eq!(neg_alt, neg);

        let neg_alt = n.clone().mod_neg(m.clone());
        assert!(neg_alt.is_valid());
        assert_eq!(neg_alt, neg);

        let mut n_alt = n.clone();
        n_alt.mod_neg_assign(&m);
        assert!(neg_alt.is_valid());
        assert_eq!(neg_alt, neg);

        let mut n_alt = n.clone();
        n_alt.mod_neg_assign(m.clone());
        assert!(neg_alt.is_valid());
        assert_eq!(neg_alt, neg);

        assert_eq!(neg, (-&n).mod_op(Integer::from(&m)));
        assert_eq!((&neg).mod_neg(&m), n);
        assert_eq!((&n).mod_add(&neg, &m), 0);
        assert_eq!(n == neg, n == Natural::ZERO || n << 1 == m);
    });

    unsigned_pair_gen_var_16::<Limb>().test_properties(|(n, m)| {
        assert_eq!(n.mod_neg(m), Natural::from(n).mod_neg(Natural::from(m)));
    });
}