use malachite_base::num::basic::integers::PrimitiveInt;
use malachite_base::num::basic::signeds::PrimitiveSigned;
use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
use malachite_base::test_util::generators::{
signed_gen, signed_gen_var_6, signed_pair_gen_var_4, signed_pair_gen_var_6, unsigned_gen,
unsigned_gen_var_1, unsigned_pair_gen_var_12,
};
use std::panic::catch_unwind;
#[test]
fn test_mod_op_unsigned() {
fn test<T: PrimitiveUnsigned>(n: T, d: T, r: T) {
assert_eq!(n.mod_op(d), r);
let mut mut_n = n;
mut_n.mod_assign(d);
assert_eq!(mut_n, r);
}
test::<u8>(0, 1, 0);
test::<u16>(0, 123, 0);
test::<u32>(1, 1, 0);
test::<u64>(123, 1, 0);
test::<usize>(123, 123, 0);
test::<u128>(123, 456, 123);
test::<u16>(456, 123, 87);
test::<u32>(u32::MAX, 1, 0);
test::<usize>(0xffffffff, 0xffffffff, 0);
test::<u64>(1000000000000, 1, 0);
test::<u64>(1000000000000, 3, 1);
test::<u64>(1000000000000, 123, 100);
test::<u64>(1000000000000, 0xffffffff, 3567587560);
test::<u128>(1000000000000000000000000, 1, 0);
test::<u128>(1000000000000000000000000, 3, 1);
test::<u128>(1000000000000000000000000, 123, 37);
test::<u128>(1000000000000000000000000, 0xffffffff, 3167723695);
test::<u128>(1000000000000000000000000, 1234567890987, 530068894399);
test::<u128>(253640751230376270397812803167, 2669936877441, 1520301762334);
test::<u64>(3768477692975601, 11447376614057827956, 3768477692975601);
test::<u64>(3356605361737854, 3081095617839357, 275509743898497);
test::<u128>(
1098730198198174614195,
953382298040157850476,
145347900158016763719,
);
test::<u128>(
69738658860594537152875081748,
69738658860594537152875081748,
0,
);
test::<u128>(1000000000000000000000000, 1000000000000000000000000, 0);
test::<u128>(0, 1000000000000000000000000, 0);
test::<u128>(123, 1000000000000000000000000, 123);
}
#[test]
fn test_div_mod_signed() {
fn test<T: PrimitiveSigned>(n: T, d: T, r: T) {
assert_eq!(n.mod_op(d), r);
let mut mut_n = n;
mut_n.mod_assign(d);
assert_eq!(mut_n, r);
}
test::<i8>(0, 1, 0);
test::<i16>(0, 123, 0);
test::<i32>(1, 1, 0);
test::<i64>(123, 1, 0);
test::<i128>(123, 123, 0);
test::<isize>(123, 456, 123);
test::<i16>(456, 123, 87);
test::<i64>(0xffffffff, 1, 0);
test::<i64>(0xffffffff, 0xffffffff, 0);
test::<i64>(1000000000000, 1, 0);
test::<i64>(1000000000000, 3, 1);
test::<i64>(1000000000000, 123, 100);
test::<i64>(1000000000000, 0xffffffff, 3567587560);
test::<i128>(1000000000000000000000000, 1, 0);
test::<i128>(1000000000000000000000000, 3, 1);
test::<i128>(1000000000000000000000000, 123, 37);
test::<i128>(1000000000000000000000000, 0xffffffff, 3167723695);
test::<i128>(1000000000000000000000000, 1234567890987, 530068894399);
test::<i128>(253640751230376270397812803167, 2669936877441, 1520301762334);
test::<i128>(3768477692975601, 11447376614057827956, 3768477692975601);
test::<i64>(3356605361737854, 3081095617839357, 275509743898497);
test::<i128>(
1098730198198174614195,
953382298040157850476,
145347900158016763719,
);
test::<i128>(
69738658860594537152875081748,
69738658860594537152875081748,
0,
);
test::<i128>(1000000000000000000000000, 1000000000000000000000000, 0);
test::<i128>(0, 1000000000000000000000000, 0);
test::<i128>(123, 1000000000000000000000000, 123);
test::<i8>(0, -1, 0);
test::<i16>(0, -123, 0);
test::<i32>(1, -1, 0);
test::<i64>(123, -1, 0);
test::<i128>(123, -123, 0);
test::<isize>(123, -456, -333);
test::<i16>(456, -123, -36);
test::<i64>(0xffffffff, -1, 0);
test::<i64>(0xffffffff, -0xffffffff, 0);
test::<i64>(1000000000000, -1, 0);
test::<i64>(1000000000000, -3, -2);
test::<i64>(1000000000000, -123, -23);
test::<i64>(1000000000000, -0xffffffff, -727379735);
test::<i128>(1000000000000000000000000, -1, 0);
test::<i128>(1000000000000000000000000, -3, -2);
test::<i128>(1000000000000000000000000, -123, -86);
test::<i128>(1000000000000000000000000, -0xffffffff, -1127243600);
test::<i128>(1000000000000000000000000, -1234567890987, -704498996588);
test::<i128>(
253640751230376270397812803167,
-2669936877441,
-1149635115107,
);
test::<i128>(
3768477692975601,
-11447376614057827956,
-11443608136364852355,
);
test::<i64>(3356605361737854, -3081095617839357, -2805585873940860);
test::<i128>(
1098730198198174614195,
-953382298040157850476,
-808034397882141086757,
);
test::<i128>(
69738658860594537152875081748,
-69738658860594537152875081748,
0,
);
test::<i128>(1000000000000000000000000, -1000000000000000000000000, 0);
test::<i128>(0, -1000000000000000000000000, 0);
test::<i128>(123, -1000000000000000000000000, -999999999999999999999877);
test::<i8>(-1, 1, 0);
test::<i16>(-123, 1, 0);
test::<i32>(-123, 123, 0);
test::<i64>(-123, 456, 333);
test::<isize>(-456, 123, 36);
test::<i64>(-0xffffffff, -1, 0);
test::<i64>(-0xffffffff, 0xffffffff, 0);
test::<i64>(-1000000000000, 1, 0);
test::<i64>(-1000000000000, 3, 2);
test::<i64>(-1000000000000, 123, 23);
test::<i64>(-1000000000000, 0xffffffff, 727379735);
test::<i128>(-1000000000000000000000000, 1, 0);
test::<i128>(-1000000000000000000000000, 3, 2);
test::<i128>(-1000000000000000000000000, 123, 86);
test::<i128>(-1000000000000000000000000, 0xffffffff, 1127243600);
test::<i128>(-1000000000000000000000000, 1234567890987, 704498996588);
test::<i128>(
-253640751230376270397812803167,
2669936877441,
1149635115107,
);
test::<i128>(
-3768477692975601,
11447376614057827956,
11443608136364852355,
);
test::<i64>(-3356605361737854, 3081095617839357, 2805585873940860);
test::<i128>(
-1098730198198174614195,
953382298040157850476,
808034397882141086757,
);
test::<i128>(
-69738658860594537152875081748,
69738658860594537152875081748,
0,
);
test::<i128>(-1000000000000000000000000, 1000000000000000000000000, 0);
test::<i128>(-123, 1000000000000000000000000, 999999999999999999999877);
test::<i8>(-1, -1, 0);
test::<i16>(-123, -1, 0);
test::<i32>(-123, -123, 0);
test::<i64>(-123, -456, -123);
test::<isize>(-456, -123, -87);
test::<i128>(-0xffffffff, -1, 0);
test::<i64>(-0xffffffff, -0xffffffff, 0);
test::<i64>(-1000000000000, -1, 0);
test::<i64>(-1000000000000, -3, -1);
test::<i64>(-1000000000000, -123, -100);
test::<i64>(-1000000000000, -0xffffffff, -3567587560);
test::<i128>(-1000000000000000000000000, -1, 0);
test::<i128>(-1000000000000000000000000, -3, -1);
test::<i128>(-1000000000000000000000000, -123, -37);
test::<i128>(-1000000000000000000000000, -0xffffffff, -3167723695);
test::<i128>(-1000000000000000000000000, -1234567890987, -530068894399);
test::<i128>(
-253640751230376270397812803167,
-2669936877441,
-1520301762334,
);
test::<i128>(-3768477692975601, -11447376614057827956, -3768477692975601);
test::<i64>(-3356605361737854, -3081095617839357, -275509743898497);
test::<i128>(
-1098730198198174614195,
-953382298040157850476,
-145347900158016763719,
);
test::<i128>(
-69738658860594537152875081748,
-69738658860594537152875081748,
0,
);
test::<i128>(-1000000000000000000000000, -1000000000000000000000000, 0);
test::<i128>(-123, -1000000000000000000000000, -123);
test::<i8>(-128, -1, 0);
}
fn mod_fail_helper<T: PrimitiveInt>() {
assert_panic!(T::ONE.mod_op(T::ZERO));
assert_panic!({
let mut n = T::ONE;
n.mod_assign(T::ZERO);
});
}
#[test]
pub fn mod_fail() {
apply_fn_to_primitive_ints!(mod_fail_helper);
}
#[test]
fn test_neg_mod() {
fn test<T: PrimitiveUnsigned>(n: T, d: T, r: T) {
assert_eq!(n.neg_mod(d), r);
let mut mut_n = n;
mut_n.neg_mod_assign(d);
assert_eq!(mut_n, r);
}
test::<u8>(0, 1, 0);
test::<u16>(0, 123, 0);
test::<u32>(1, 1, 0);
test::<u64>(123, 1, 0);
test::<u128>(123, 123, 0);
test::<usize>(123, 456, 333);
test::<u16>(456, 123, 36);
test::<u64>(0xffffffff, 1, 0);
test::<u64>(0xffffffff, 0xffffffff, 0);
test::<u64>(1000000000000, 1, 0);
test::<u64>(1000000000000, 3, 2);
test::<u64>(1000000000000, 123, 23);
test::<u64>(1000000000000, 0xffffffff, 727379735);
test::<u128>(1000000000000000000000000, 1, 0);
test::<u128>(1000000000000000000000000, 3, 2);
test::<u128>(1000000000000000000000000, 123, 86);
test::<u128>(1000000000000000000000000, 0xffffffff, 1127243600);
test::<u128>(1000000000000000000000000, 1234567890987, 704498996588);
test::<u128>(253640751230376270397812803167, 2669936877441, 1149635115107);
test::<u64>(3768477692975601, 11447376614057827956, 11443608136364852355);
test::<u64>(3356605361737854, 3081095617839357, 2805585873940860);
test::<u128>(
1098730198198174614195,
953382298040157850476,
808034397882141086757,
);
test::<u128>(
69738658860594537152875081748,
69738658860594537152875081748,
0,
);
test::<u128>(1000000000000000000000000, 1000000000000000000000000, 0);
test::<u128>(0, 1000000000000000000000000, 0);
test::<u128>(123, 1000000000000000000000000, 999999999999999999999877);
}
fn neg_mod_fail_helper<T: PrimitiveUnsigned>() {
assert_panic!(T::ONE.neg_mod(T::ZERO));
assert_panic!({
let mut n = T::ONE;
n.neg_mod_assign(T::ZERO);
});
}
#[test]
pub fn neg_mod_fail() {
apply_fn_to_unsigneds!(neg_mod_fail_helper);
}
#[test]
fn test_ceiling_mod() {
fn test<T: PrimitiveSigned>(n: T, d: T, r: T) {
assert_eq!(n.ceiling_mod(d), r);
let mut mut_n = n;
mut_n.ceiling_mod_assign(d);
assert_eq!(mut_n, r);
}
test::<i8>(0, 1, 0);
test::<i16>(0, 123, 0);
test::<i32>(1, 1, 0);
test::<i64>(123, 1, 0);
test::<i128>(123, 123, 0);
test::<isize>(123, 456, -333);
test::<i16>(456, 123, -36);
test::<i64>(0xffffffff, 1, 0);
test::<i64>(0xffffffff, 0xffffffff, 0);
test::<i64>(1000000000000, 1, 0);
test::<i64>(1000000000000, 3, -2);
test::<i64>(1000000000000, 123, -23);
test::<i64>(1000000000000, 0xffffffff, -727379735);
test::<i128>(1000000000000000000000000, 1, 0);
test::<i128>(1000000000000000000000000, 3, -2);
test::<i128>(1000000000000000000000000, 123, -86);
test::<i128>(1000000000000000000000000, 0xffffffff, -1127243600);
test::<i128>(1000000000000000000000000, 1234567890987, -704498996588);
test::<i128>(
253640751230376270397812803167,
2669936877441,
-1149635115107,
);
test::<i128>(
3768477692975601,
11447376614057827956,
-11443608136364852355,
);
test::<i64>(3356605361737854, 3081095617839357, -2805585873940860);
test::<i128>(
1098730198198174614195,
953382298040157850476,
-808034397882141086757,
);
test::<i128>(
69738658860594537152875081748,
69738658860594537152875081748,
0,
);
test::<i128>(1000000000000000000000000, 1000000000000000000000000, 0);
test::<i128>(0, 1000000000000000000000000, 0);
test::<i128>(123, 1000000000000000000000000, -999999999999999999999877);
test::<i8>(0, -1, 0);
test::<i16>(0, -123, 0);
test::<i32>(1, -1, 0);
test::<i64>(123, -1, 0);
test::<i128>(123, -123, 0);
test::<isize>(123, -456, 123);
test::<i16>(456, -123, 87);
test::<i64>(0xffffffff, -1, 0);
test::<i64>(0xffffffff, -0xffffffff, 0);
test::<i64>(1000000000000, -1, 0);
test::<i64>(1000000000000, -3, 1);
test::<i64>(1000000000000, -123, 100);
test::<i64>(1000000000000, -0xffffffff, 3567587560);
test::<i128>(1000000000000000000000000, -1, 0);
test::<i128>(1000000000000000000000000, -3, 1);
test::<i128>(1000000000000000000000000, -123, 37);
test::<i128>(1000000000000000000000000, -0xffffffff, 3167723695);
test::<i128>(1000000000000000000000000, -1234567890987, 530068894399);
test::<i128>(
253640751230376270397812803167,
-2669936877441,
1520301762334,
);
test::<i128>(3768477692975601, -11447376614057827956, 3768477692975601);
test::<i64>(3356605361737854, -3081095617839357, 275509743898497);
test::<i128>(
1098730198198174614195,
-953382298040157850476,
145347900158016763719,
);
test::<i128>(
69738658860594537152875081748,
-69738658860594537152875081748,
0,
);
test::<i128>(1000000000000000000000000, -1000000000000000000000000, 0);
test::<i128>(0, -1000000000000000000000000, 0);
test::<i128>(123, -1000000000000000000000000, 123);
test::<i8>(-1, 1, 0);
test::<i16>(-123, 1, 0);
test::<i32>(-123, 123, 0);
test::<i64>(-123, 456, -123);
test::<i128>(-456, 123, -87);
test::<isize>(-0xffffffff, 1, 0);
test::<i64>(-0xffffffff, 0xffffffff, 0);
test::<i64>(-1000000000000, 1, 0);
test::<i64>(-1000000000000, 3, -1);
test::<i64>(-1000000000000, 123, -100);
test::<i64>(-1000000000000, 0xffffffff, -3567587560);
test::<i128>(-1000000000000000000000000, 1, 0);
test::<i128>(-1000000000000000000000000, 3, -1);
test::<i128>(-1000000000000000000000000, 123, -37);
test::<i128>(-1000000000000000000000000, 0xffffffff, -3167723695);
test::<i128>(-1000000000000000000000000, 1234567890987, -530068894399);
test::<i128>(
-253640751230376270397812803167,
2669936877441,
-1520301762334,
);
test::<i128>(-3768477692975601, 11447376614057827956, -3768477692975601);
test::<i64>(-3356605361737854, 3081095617839357, -275509743898497);
test::<i128>(
-1098730198198174614195,
953382298040157850476,
-145347900158016763719,
);
test::<i128>(
-69738658860594537152875081748,
69738658860594537152875081748,
0,
);
test::<i128>(-1000000000000000000000000, 1000000000000000000000000, 0);
test::<i128>(0, 1000000000000000000000000, 0);
test::<i128>(-123, 1000000000000000000000000, -123);
test::<i8>(-1, -1, 0);
test::<i16>(-123, -1, 0);
test::<i32>(-123, -123, 0);
test::<i64>(-123, -456, 333);
test::<i128>(-456, -123, 36);
test::<isize>(-0xffffffff, -1, 0);
test::<i64>(-0xffffffff, -0xffffffff, 0);
test::<i64>(-1000000000000, -1, 0);
test::<i64>(-1000000000000, -3, 2);
test::<i64>(-1000000000000, -123, 23);
test::<i64>(-1000000000000, -0xffffffff, 727379735);
test::<i128>(-1000000000000000000000000, -1, 0);
test::<i128>(-1000000000000000000000000, -3, 2);
test::<i128>(-1000000000000000000000000, -123, 86);
test::<i128>(-1000000000000000000000000, -0xffffffff, 1127243600);
test::<i128>(-1000000000000000000000000, -1234567890987, 704498996588);
test::<i128>(
-253640751230376270397812803167,
-2669936877441,
1149635115107,
);
test::<i128>(
-3768477692975601,
-11447376614057827956,
11443608136364852355,
);
test::<i64>(-3356605361737854, -3081095617839357, 2805585873940860);
test::<i128>(
-1098730198198174614195,
-953382298040157850476,
808034397882141086757,
);
test::<i128>(
-69738658860594537152875081748,
-69738658860594537152875081748,
0,
);
test::<i128>(-1000000000000000000000000, -1000000000000000000000000, 0);
test::<i128>(0, -1000000000000000000000000, 0);
test::<i128>(-123, -1000000000000000000000000, 999999999999999999999877);
test::<i8>(-128, -1, 0);
}
fn ceiling_mod_fail_helper<T: PrimitiveSigned>() {
assert_panic!(T::ONE.ceiling_mod(T::ZERO));
assert_panic!({
let mut n = T::ONE;
n.ceiling_mod_assign(T::ZERO);
});
}
#[test]
pub fn ceiling_mod_fail() {
apply_fn_to_signeds!(ceiling_mod_fail_helper);
}
fn mod_properties_helper_unsigned<T: PrimitiveUnsigned>() {
unsigned_pair_gen_var_12::<T, T>().test_properties(|(x, y)| {
let mut mut_x = x;
mut_x.mod_assign(y);
let r = mut_x;
assert_eq!(x.mod_op(y), r);
let mut mut_x = x;
mut_x %= y;
assert_eq!(mut_x, r);
assert_eq!(x % y, r);
assert_eq!(x.div_mod(y).1, r);
assert_eq!(x.div_rem(y).1, r);
assert!(r < y);
});
unsigned_gen::<T>().test_properties(|x| {
assert_eq!(x.mod_op(T::ONE), T::ZERO);
});
unsigned_gen_var_1::<T>().test_properties(|x| {
assert_eq!(x.mod_op(x), T::ZERO);
assert_eq!(T::ZERO.mod_op(x), T::ZERO);
if x > T::ONE {
assert_eq!(T::ONE.mod_op(x), T::ONE);
}
});
}
fn mod_properties_helper_signed<T: PrimitiveSigned>() {
signed_pair_gen_var_6::<T>().test_properties(|(x, y)| {
let mut mut_x = x;
mut_x.mod_assign(y);
let r = mut_x;
assert_eq!(x.mod_op(y), r);
assert!(r.lt_abs(&y));
assert!(r == T::ZERO || (r > T::ZERO) == (y > T::ZERO));
if x != T::MIN {
assert_eq!(x.ceiling_mod(y), -(-x).mod_op(y));
}
if y != T::MIN {
assert_eq!(x.ceiling_mod(y), x.mod_op(-y));
}
});
signed_pair_gen_var_4::<T>().test_properties(|(x, y)| {
assert_eq!(x.mod_op(y), x.div_mod(y).1);
});
signed_gen::<T>().test_properties(|x| {
assert_eq!(x.mod_op(T::ONE), T::ZERO);
assert_eq!(x.mod_op(T::NEGATIVE_ONE), T::ZERO);
});
signed_gen_var_6::<T>().test_properties(|x| {
assert_eq!(x.mod_op(T::ONE), T::ZERO);
assert_eq!(x.mod_op(x), T::ZERO);
assert_eq!(T::ZERO.mod_op(x), T::ZERO);
assert_eq!(x.mod_op(T::NEGATIVE_ONE), T::ZERO);
if x != T::MIN {
assert_eq!(x.mod_op(-x), T::ZERO);
}
if x > T::ONE {
assert_eq!(T::ONE.mod_op(x), T::ONE);
assert_eq!(T::NEGATIVE_ONE.mod_op(x), x - T::ONE);
}
});
}
#[test]
fn mod_properties() {
apply_fn_to_unsigneds!(mod_properties_helper_unsigned);
apply_fn_to_signeds!(mod_properties_helper_signed);
}
fn neg_mod_properties_helper<T: PrimitiveUnsigned>() {
unsigned_pair_gen_var_12::<T, T>().test_properties(|(x, y)| {
let mut mut_x = x;
mut_x.neg_mod_assign(y);
let r = mut_x;
assert_eq!(x.neg_mod(y), r);
assert_eq!(x.ceiling_div_neg_mod(y).1, r);
assert!(r < y);
});
unsigned_gen::<T>().test_properties(|x| {
assert_eq!(x.neg_mod(T::ONE), T::ZERO);
});
unsigned_gen_var_1::<T>().test_properties(|x| {
assert_eq!(x.neg_mod(x), T::ZERO);
assert_eq!(T::ZERO.neg_mod(x), T::ZERO);
if x > T::ONE {
assert_eq!(T::ONE.neg_mod(x), x - T::ONE);
}
});
}
#[test]
fn neg_mod_properties() {
apply_fn_to_unsigneds!(neg_mod_properties_helper);
}
fn ceiling_mod_properties_helper<T: PrimitiveSigned>() {
signed_pair_gen_var_6::<T>().test_properties(|(x, y)| {
let mut mut_x = x;
mut_x.ceiling_mod_assign(y);
let r = mut_x;
assert_eq!(x.ceiling_mod(y), r);
assert!(r.lt_abs(&y));
assert!(r == T::ZERO || (r > T::ZERO) != (y > T::ZERO));
if x != T::MIN {
assert_eq!(x.mod_op(y), -(-x).ceiling_mod(y));
}
if y != T::MIN {
assert_eq!(x.mod_op(y), x.ceiling_mod(-y));
}
});
signed_pair_gen_var_4::<T>().test_properties(|(x, y)| {
assert_eq!(x.ceiling_mod(y), x.ceiling_div_mod(y).1);
});
signed_gen::<T>().test_properties(|x| {
assert_eq!(x.ceiling_mod(T::ONE), T::ZERO);
assert_eq!(x.ceiling_mod(T::NEGATIVE_ONE), T::ZERO);
});
signed_gen_var_6::<T>().test_properties(|x| {
assert_eq!(x.ceiling_mod(T::ONE), T::ZERO);
assert_eq!(x.ceiling_mod(T::NEGATIVE_ONE), T::ZERO);
assert_eq!(x.ceiling_mod(x), T::ZERO);
if x != T::MIN {
assert_eq!(x.ceiling_mod(-x), T::ZERO);
}
assert_eq!(T::ZERO.ceiling_mod(x), T::ZERO);
});
}
#[test]
fn ceiling_mod_properties() {
apply_fn_to_signeds!(ceiling_mod_properties_helper);
}