use malachite_base::num::arithmetic::traits::{ModPowerOf2, ModPowerOf2IsReduced};
use malachite_base::num::basic::signeds::PrimitiveSigned;
use malachite_base::num::basic::traits::Zero;
use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom};
use malachite_base::test_util::generators::{
signed_gen, signed_unsigned_pair_gen_var_1, signed_unsigned_pair_gen_var_10,
signed_unsigned_pair_gen_var_11, signed_unsigned_pair_gen_var_4, unsigned_gen,
unsigned_pair_gen_var_2, unsigned_pair_gen_var_20, unsigned_triple_gen_var_13,
unsigned_triple_gen_var_4,
};
use std::cmp::min;
use std::fmt::Debug;
use std::panic::catch_unwind;
#[test]
fn test_mod_power_of_2_and_rem_power_of_2_unsigned() {
fn test<T: PrimitiveUnsigned>(x: T, pow: u64, out: T) {
assert_eq!(x.mod_power_of_2(pow), out);
let mut mut_x = x;
mut_x.mod_power_of_2_assign(pow);
assert_eq!(mut_x, out);
assert_eq!(x.rem_power_of_2(pow), out);
let mut mut_x = x;
mut_x.rem_power_of_2_assign(pow);
assert_eq!(mut_x, out);
}
test::<u8>(0, 0, 0);
test::<u16>(260, 8, 4);
test::<u32>(1611, 4, 11);
test::<u8>(123, 100, 123);
test::<u64>(1000000000000, 0, 0);
test::<u64>(1000000000000, 12, 0);
test::<u64>(1000000000001, 12, 1);
test::<u64>(999999999999, 12, 4095);
test::<u64>(1000000000000, 15, 4096);
test::<u64>(1000000000000, 100, 1000000000000);
test::<u128>(1000000000000000000000000, 40, 1020608380928);
test::<u128>(1000000000000000000000000, 64, 2003764205206896640);
test::<u32>(u32::MAX, 31, 0x7fffffff);
test::<u32>(u32::MAX, 32, u32::MAX);
test::<usize>(0xffffffff, 33, 0xffffffff);
test::<u64>(0x100000000, 31, 0);
test::<u64>(0x100000000, 32, 0);
test::<u64>(0x100000000, 33, 0x100000000);
test::<u64>(0x100000001, 31, 1);
test::<u64>(0x100000001, 32, 1);
test::<u64>(0x100000001, 33, 0x100000001);
}
#[test]
fn test_mod_power_of_2_signed() {
fn test<U: Copy + Debug + Eq, S: ModPowerOf2<Output = U> + PrimitiveSigned>(
x: S,
pow: u64,
out: U,
) {
assert_eq!(x.mod_power_of_2(pow), out);
}
test::<_, i8>(0, 0, 0);
test::<_, i16>(2, 1, 0);
test::<_, i32>(260, 8, 4);
test::<_, i16>(1611, 4, 11);
test::<_, i8>(123, 100, 123);
test::<_, i64>(1000000000000, 0, 0);
test::<_, i64>(1000000000000, 12, 0);
test::<_, i64>(1000000000001, 12, 1);
test::<_, i64>(999999999999, 12, 4095);
test::<_, i64>(1000000000000, 15, 4096);
test::<_, i64>(1000000000000, 100, 1000000000000);
test::<_, i128>(1000000000000000000000000, 40, 1020608380928);
test::<_, i128>(1000000000000000000000000, 64, 2003764205206896640);
test::<_, i32>(0x7fffffff, 30, 0x3fffffff);
test::<_, i32>(0x7fffffff, 31, 0x7fffffff);
test::<_, isize>(0x7fffffff, 32, 0x7fffffff);
test::<_, i64>(0x80000000, 30, 0);
test::<_, i64>(0x80000000, 31, 0);
test::<_, i64>(0x80000000, 32, 0x80000000);
test::<_, i64>(0x80000001, 30, 1);
test::<_, i64>(0x80000001, 31, 1);
test::<_, i64>(0x80000001, 32, 0x80000001);
test::<_, i64>(0xffffffff, 31, 0x7fffffff);
test::<_, i64>(0xffffffff, 32, 0xffffffff);
test::<_, i64>(0xffffffff, 33, 0xffffffff);
test::<_, i64>(0x100000000, 31, 0);
test::<_, i64>(0x100000000, 32, 0);
test::<_, i64>(0x100000000, 33, 0x100000000);
test::<_, i64>(0x100000001, 31, 1);
test::<_, i64>(0x100000001, 32, 1);
test::<_, i64>(0x100000001, 33, 0x100000001);
test::<_, i8>(-2, 1, 0);
test::<_, i16>(-260, 8, 252);
test::<_, i32>(-1611, 4, 5);
test::<_, i128>(-123, 100, 1267650600228229401496703205253);
test::<_, i64>(-1000000000000, 0, 0);
test::<_, i64>(-1000000000000, 12, 0);
test::<_, i64>(-1000000000001, 12, 4095);
test::<_, i64>(-999999999999, 12, 1);
test::<_, i64>(-1000000000000, 15, 0x7000);
test::<_, i128>(-1000000000000, 100, 1267650600228229400496703205376);
test::<_, i128>(-1000000000000000000000000, 40, 78903246848);
test::<_, i128>(-1000000000000000000000000, 64, 16442979868502654976);
test::<_, i32>(-0x7fffffff, 30, 1);
test::<_, i32>(-0x7fffffff, 31, 1);
test::<_, i32>(-0x7fffffff, 32, 0x80000001);
test::<_, isize>(-0x80000000, 30, 0);
test::<_, isize>(-0x80000000, 31, 0);
test::<_, isize>(-0x80000000, 32, 0x80000000);
test::<_, i64>(-0x80000001, 30, 0x3fffffff);
test::<_, i64>(-0x80000001, 31, 0x7fffffff);
test::<_, i64>(-0x80000001, 32, 0x7fffffff);
test::<_, i64>(-0xffffffff, 31, 1);
test::<_, i64>(-0xffffffff, 32, 1);
test::<_, i64>(-0xffffffff, 33, 0x100000001);
test::<_, i64>(-0x100000000, 31, 0);
test::<_, i64>(-0x100000000, 32, 0);
test::<_, i64>(-0x100000000, 33, 0x100000000);
test::<_, i64>(-0x100000001, 31, 0x7fffffff);
test::<_, i64>(-0x100000001, 32, 0xffffffff);
test::<_, i64>(-0x100000001, 33, 0xffffffff);
}
fn mod_power_of_2_signed_fail_helper<T: PrimitiveSigned>() {
assert_panic!(T::NEGATIVE_ONE.mod_power_of_2(200));
}
#[test]
fn mod_power_of_2_signed_fail() {
apply_fn_to_signeds!(mod_power_of_2_signed_fail_helper);
}
#[test]
fn test_mod_power_of_2_assign_signed() {
fn test<T: PrimitiveSigned>(x: T, pow: u64, out: T) {
let mut mut_x = x;
mut_x.mod_power_of_2_assign(pow);
assert_eq!(mut_x, out);
}
test::<i8>(0, 0, 0);
test::<i16>(2, 1, 0);
test::<i32>(260, 8, 4);
test::<i16>(1611, 4, 11);
test::<i8>(123, 100, 123);
test::<i64>(1000000000000, 0, 0);
test::<i64>(1000000000000, 12, 0);
test::<i64>(1000000000001, 12, 1);
test::<i64>(999999999999, 12, 4095);
test::<i64>(1000000000000, 15, 4096);
test::<i64>(1000000000000, 100, 1000000000000);
test::<i128>(1000000000000000000000000, 40, 1020608380928);
test::<i128>(1000000000000000000000000, 64, 2003764205206896640);
test::<i32>(0x7fffffff, 30, 0x3fffffff);
test::<i32>(0x7fffffff, 31, 0x7fffffff);
test::<isize>(0x7fffffff, 32, 0x7fffffff);
test::<i64>(0x80000000, 30, 0);
test::<i64>(0x80000000, 31, 0);
test::<i64>(0x80000000, 32, 0x80000000);
test::<i64>(0x80000001, 30, 1);
test::<i64>(0x80000001, 31, 1);
test::<i64>(0x80000001, 32, 0x80000001);
test::<i64>(0xffffffff, 31, 0x7fffffff);
test::<i64>(0xffffffff, 32, 0xffffffff);
test::<i64>(0xffffffff, 33, 0xffffffff);
test::<i64>(0x100000000, 31, 0);
test::<i64>(0x100000000, 32, 0);
test::<i64>(0x100000000, 33, 0x100000000);
test::<i64>(0x100000001, 31, 1);
test::<i64>(0x100000001, 32, 1);
test::<i64>(0x100000001, 33, 0x100000001);
test::<i8>(-2, 1, 0);
test::<i16>(-260, 8, 252);
test::<i32>(-1611, 4, 5);
test::<i128>(-123, 100, 1267650600228229401496703205253);
test::<i64>(-1000000000000, 0, 0);
test::<i64>(-1000000000000, 12, 0);
test::<i64>(-1000000000001, 12, 4095);
test::<i64>(-999999999999, 12, 1);
test::<i64>(-1000000000000, 15, 0x7000);
test::<i128>(-1000000000000, 100, 1267650600228229400496703205376);
test::<i128>(-1000000000000000000000000, 40, 78903246848);
test::<i128>(-1000000000000000000000000, 64, 16442979868502654976);
test::<i32>(-0x7fffffff, 30, 1);
test::<i32>(-0x7fffffff, 31, 1);
test::<i64>(-0x7fffffff, 32, 0x80000001);
test::<isize>(-0x80000000, 30, 0);
test::<isize>(-0x80000000, 31, 0);
test::<i64>(-0x80000000, 32, 0x80000000);
test::<i64>(-0x80000001, 30, 0x3fffffff);
test::<i64>(-0x80000001, 31, 0x7fffffff);
test::<i64>(-0x80000001, 32, 0x7fffffff);
test::<i64>(-0xffffffff, 31, 1);
test::<i64>(-0xffffffff, 32, 1);
test::<i64>(-0xffffffff, 33, 0x100000001);
test::<i64>(-0x100000000, 31, 0);
test::<i64>(-0x100000000, 32, 0);
test::<i64>(-0x100000000, 33, 0x100000000);
test::<i64>(-0x100000001, 31, 0x7fffffff);
test::<i64>(-0x100000001, 32, 0xffffffff);
test::<i64>(-0x100000001, 33, 0xffffffff);
}
fn mod_power_of_2_assign_signed_fail_helper<T: PrimitiveSigned>() {
assert_panic!({
let mut x = T::NEGATIVE_ONE;
x.mod_power_of_2_assign(200)
});
assert_panic!({
let mut x = T::MIN;
x.mod_power_of_2_assign(T::WIDTH)
});
}
#[test]
fn mod_power_of_2_assign_signed_fail() {
apply_fn_to_signeds!(mod_power_of_2_assign_signed_fail_helper);
}
#[test]
fn test_rem_power_of_2_signed() {
fn test<T: PrimitiveSigned>(x: T, pow: u64, out: T) {
assert_eq!(x.rem_power_of_2(pow), out);
let mut mut_x = x;
mut_x.rem_power_of_2_assign(pow);
assert_eq!(mut_x, out);
}
test::<i8>(0, 0, 0);
test::<i16>(2, 1, 0);
test::<i32>(260, 8, 4);
test::<i64>(1611, 4, 11);
test::<i8>(123, 100, 123);
test::<i64>(1000000000000, 0, 0);
test::<i64>(1000000000000, 12, 0);
test::<i64>(1000000000001, 12, 1);
test::<i64>(999999999999, 12, 4095);
test::<i64>(1000000000000, 15, 4096);
test::<i64>(1000000000000, 100, 1000000000000);
test::<i128>(1000000000000000000000000, 40, 1020608380928);
test::<i128>(1000000000000000000000000, 64, 2003764205206896640);
test::<i32>(0x7fffffff, 30, 0x3fffffff);
test::<i32>(0x7fffffff, 31, 0x7fffffff);
test::<isize>(0x7fffffff, 32, 0x7fffffff);
test::<i64>(0x80000000, 30, 0);
test::<i64>(0x80000000, 31, 0);
test::<i64>(0x80000000, 32, 0x80000000);
test::<i64>(0x80000001, 30, 1);
test::<i64>(0x80000001, 31, 1);
test::<i64>(0x80000001, 32, 0x80000001);
test::<i64>(0xffffffff, 31, 0x7fffffff);
test::<i64>(0xffffffff, 32, 0xffffffff);
test::<i64>(0xffffffff, 33, 0xffffffff);
test::<i64>(0x100000000, 31, 0);
test::<i64>(0x100000000, 32, 0);
test::<i64>(0x100000000, 33, 0x100000000);
test::<i64>(0x100000001, 31, 1);
test::<i64>(0x100000001, 32, 1);
test::<i64>(0x100000001, 33, 0x100000001);
test::<i8>(-2, 1, 0);
test::<i16>(-260, 8, -4);
test::<i32>(-1611, 4, -11);
test::<i64>(-123, 100, -123);
test::<i64>(-1000000000000, 0, 0);
test::<i64>(-1000000000000, 12, 0);
test::<i64>(-1000000000001, 12, -1);
test::<i64>(-999999999999, 12, -4095);
test::<i64>(-1000000000000, 15, -4096);
test::<i64>(-1000000000000, 100, -1000000000000);
test::<i128>(-1000000000000000000000000, 40, -1020608380928);
test::<i128>(-1000000000000000000000000, 64, -2003764205206896640);
test::<i32>(-0x7fffffff, 30, -0x3fffffff);
test::<i32>(-0x7fffffff, 31, -0x7fffffff);
test::<isize>(-0x7fffffff, 32, -0x7fffffff);
test::<i64>(-0x80000000, 30, 0);
test::<i64>(-0x80000000, 31, 0);
test::<i64>(-0x80000000, 32, -0x80000000);
test::<i64>(-0x80000001, 30, -1);
test::<i64>(-0x80000001, 31, -1);
test::<i64>(-0x80000001, 32, -0x80000001);
test::<i64>(-0xffffffff, 31, -0x7fffffff);
test::<i64>(-0xffffffff, 32, -0xffffffff);
test::<i64>(-0xffffffff, 33, -0xffffffff);
test::<i64>(-0x100000000, 31, 0);
test::<i64>(-0x100000000, 32, 0);
test::<i64>(-0x100000000, 33, -0x100000000);
test::<i64>(-0x100000001, 31, -1);
test::<i64>(-0x100000001, 32, -1);
test::<i64>(-0x100000001, 33, -0x100000001);
}
#[test]
fn test_neg_mod_power_of_2_unsigned() {
fn test<T: PrimitiveUnsigned>(x: T, pow: u64, out: T) {
assert_eq!(x.neg_mod_power_of_2(pow), out);
let mut mut_x = x;
mut_x.neg_mod_power_of_2_assign(pow);
assert_eq!(mut_x, out);
}
test::<u8>(0, 0, 0);
test::<u16>(260, 8, 252);
test::<u32>(1611, 4, 5);
test::<u32>(1, 32, u32::MAX);
test::<u128>(123, 100, 1267650600228229401496703205253);
test::<u64>(1000000000000, 0, 0);
test::<u64>(1000000000000, 12, 0);
test::<u64>(1000000000001, 12, 4095);
test::<u64>(999999999999, 12, 1);
test::<u64>(1000000000000, 15, 0x7000);
test::<u128>(1000000000000, 100, 1267650600228229400496703205376);
test::<u128>(1000000000000000000000000, 40, 78903246848);
test::<u128>(1000000000000000000000000, 64, 16442979868502654976);
test::<u32>(u32::MAX, 31, 1);
test::<usize>(0xffffffff, 32, 1);
test::<u64>(0xffffffff, 33, 0x100000001);
test::<u64>(0x100000000, 31, 0);
test::<u64>(0x100000000, 32, 0);
test::<u64>(0x100000000, 33, 0x100000000);
test::<u64>(0x100000001, 31, 0x7fffffff);
test::<u64>(0x100000001, 32, 0xffffffff);
test::<u64>(0x100000001, 33, 0xffffffff);
}
fn neg_mod_power_of_2_fail_helper<T: PrimitiveUnsigned>() {
assert_panic!(T::ONE.neg_mod_power_of_2(200));
assert_panic!(T::MAX.neg_mod_power_of_2(T::WIDTH + 1));
assert_panic!({
let mut x = T::ONE;
x.neg_mod_power_of_2_assign(200)
});
assert_panic!({
let mut x = T::MAX;
x.neg_mod_power_of_2_assign(T::WIDTH + 1)
});
}
#[test]
fn neg_mod_power_of_2_fail() {
apply_fn_to_unsigneds!(neg_mod_power_of_2_fail_helper);
}
#[test]
fn test_ceiling_mod_power_of_2_signed() {
fn test<T: PrimitiveSigned>(x: T, pow: u64, out: T) {
assert_eq!(x.ceiling_mod_power_of_2(pow), out);
let mut mut_x = x;
mut_x.ceiling_mod_power_of_2_assign(pow);
assert_eq!(mut_x, out);
}
test::<i8>(0, 0, 0);
test::<i16>(2, 1, 0);
test::<i32>(260, 8, -252);
test::<i64>(1611, 4, -5);
test::<i128>(123, 100, -1267650600228229401496703205253);
test::<i64>(1000000000000, 0, 0);
test::<i64>(1000000000000, 12, 0);
test::<i64>(1000000000001, 12, -4095);
test::<i64>(999999999999, 12, -1);
test::<i64>(1000000000000, 15, -0x7000);
test::<i128>(1000000000000, 100, -1267650600228229400496703205376);
test::<i128>(1000000000000000000000000, 40, -78903246848);
test::<i128>(1000000000000000000000000, 64, -16442979868502654976);
test::<i32>(0x7fffffff, 30, -1);
test::<isize>(0x7fffffff, 31, -1);
test::<i64>(0x7fffffff, 32, -0x80000001);
test::<i64>(0x80000000, 30, 0);
test::<i64>(0x80000000, 31, 0);
test::<i64>(0x80000000, 32, -0x80000000);
test::<i64>(0x80000001, 30, -0x3fffffff);
test::<i64>(0x80000001, 31, -0x7fffffff);
test::<i64>(0x80000001, 32, -0x7fffffff);
test::<i64>(0xffffffff, 31, -1);
test::<i64>(0xffffffff, 32, -1);
test::<i64>(0xffffffff, 33, -0x100000001);
test::<i64>(0x100000000, 31, 0);
test::<i64>(0x100000000, 32, 0);
test::<i64>(0x100000000, 33, -0x100000000);
test::<i64>(0x100000001, 31, -0x7fffffff);
test::<i64>(0x100000001, 32, -0xffffffff);
test::<i64>(0x100000001, 33, -0xffffffff);
test::<i8>(-2, 1, 0);
test::<i16>(-260, 8, -4);
test::<i32>(-1611, 4, -11);
test::<i64>(-123, 100, -123);
test::<i64>(-1000000000000, 0, 0);
test::<i64>(-1000000000000, 12, 0);
test::<i64>(-1000000000001, 12, -1);
test::<i64>(-999999999999, 12, -4095);
test::<i64>(-1000000000000, 15, -4096);
test::<i64>(-1000000000000, 100, -1000000000000);
test::<i128>(-1000000000000000000000000, 40, -1020608380928);
test::<i128>(-1000000000000000000000000, 64, -2003764205206896640);
test::<i32>(-0x7fffffff, 30, -0x3fffffff);
test::<i32>(-0x7fffffff, 31, -0x7fffffff);
test::<i32>(-0x7fffffff, 32, -0x7fffffff);
test::<i32>(-0x80000000, 31, 0);
test::<isize>(-0x80000000, 30, 0);
test::<isize>(-0x80000000, 31, 0);
test::<isize>(-0x80000000, 32, -0x80000000);
test::<i64>(-0x80000001, 30, -1);
test::<i64>(-0x80000001, 31, -1);
test::<i64>(-0x80000001, 32, -0x80000001);
test::<i64>(-0xffffffff, 31, -0x7fffffff);
test::<i64>(-0xffffffff, 32, -0xffffffff);
test::<i64>(-0xffffffff, 33, -0xffffffff);
test::<i64>(-0x100000000, 31, 0);
test::<i64>(-0x100000000, 32, 0);
test::<i64>(-0x100000000, 33, -0x100000000);
test::<i64>(-0x100000001, 31, -1);
test::<i64>(-0x100000001, 32, -1);
test::<i64>(-0x100000001, 33, -0x100000001);
}
fn ceiling_mod_power_of_2_fail_helper<T: PrimitiveSigned>() {
assert_panic!(T::ONE.ceiling_mod_power_of_2(T::WIDTH));
assert_panic!(T::MIN.ceiling_mod_power_of_2(T::WIDTH));
assert_panic!({
let mut x = T::ONE;
x.ceiling_mod_power_of_2_assign(T::WIDTH)
});
assert_panic!({
let mut x = T::MIN;
x.ceiling_mod_power_of_2_assign(T::WIDTH)
});
}
#[test]
fn ceiling_mod_power_of_2_fail() {
apply_fn_to_signeds!(ceiling_mod_power_of_2_fail_helper);
}
fn mod_power_of_2_properties_helper_unsigned<T: PrimitiveUnsigned>() {
unsigned_pair_gen_var_2::<T, u64>().test_properties(|(n, pow)| {
let mut mut_n = n;
mut_n.mod_power_of_2_assign(pow);
let result = mut_n;
assert!(result.mod_power_of_2_is_reduced(pow));
assert_eq!(n.mod_power_of_2(pow), result);
let mut mut_n = n;
mut_n.rem_power_of_2_assign(pow);
assert_eq!(mut_n, result);
assert_eq!(n.rem_power_of_2(pow), result);
assert!(result <= n);
assert_eq!(result == T::ZERO, n.divisible_by_power_of_2(pow));
assert_eq!(result.mod_power_of_2(pow), result);
});
unsigned_triple_gen_var_4::<T, u64>().test_properties(|(x, y, pow)| {
assert_eq!(
x.wrapping_add(y).mod_power_of_2(pow),
x.mod_power_of_2(pow)
.wrapping_add(y.mod_power_of_2(pow))
.mod_power_of_2(pow)
);
assert_eq!(
x.wrapping_mul(y).mod_power_of_2(pow),
x.mod_power_of_2(pow)
.wrapping_mul(y.mod_power_of_2(pow))
.mod_power_of_2(pow)
);
});
unsigned_triple_gen_var_13::<T, u64>().test_properties(|(n, u, v)| {
assert_eq!(
n.mod_power_of_2(u).mod_power_of_2(v),
n.mod_power_of_2(min(u, v))
);
});
unsigned_gen::<T>().test_properties(|n| {
assert_eq!(n.mod_power_of_2(0), T::ZERO);
});
unsigned_gen().test_properties(|pow| {
assert_eq!(T::ZERO.mod_power_of_2(pow), T::ZERO);
});
}
fn mod_power_of_2_properties_helper_signed<T: PrimitiveSigned>()
where
<T as ModPowerOf2>::Output: ExactFrom<T> + PrimitiveUnsigned,
{
signed_unsigned_pair_gen_var_10::<T>().test_properties(|(n, pow)| {
let result = n.mod_power_of_2(pow);
assert!(result.mod_power_of_2_is_reduced(pow));
assert_eq!(
result == <T as ModPowerOf2>::Output::ZERO,
n.divisible_by_power_of_2(pow)
);
assert_eq!(result.mod_power_of_2(pow), result);
});
signed_unsigned_pair_gen_var_4::<T>().test_properties(|(n, pow)| {
let mut mut_n = n;
mut_n.mod_power_of_2_assign(pow);
let result = mut_n;
assert_eq!(
n.mod_power_of_2(pow),
<T as ModPowerOf2>::Output::exact_from(result)
);
assert!(result >= T::ZERO);
assert_eq!(result == T::ZERO, n.divisible_by_power_of_2(pow));
assert_eq!(
result.mod_power_of_2(pow),
<T as ModPowerOf2>::Output::exact_from(result)
);
});
signed_gen::<T>().test_properties(|n| {
assert_eq!(n.mod_power_of_2(0), <T as ModPowerOf2>::Output::ZERO);
});
unsigned_gen().test_properties(|pow| {
assert_eq!(
T::ZERO.mod_power_of_2(pow),
<T as ModPowerOf2>::Output::ZERO
);
});
}
#[test]
fn mod_power_of_2_properties() {
apply_fn_to_unsigneds!(mod_power_of_2_properties_helper_unsigned);
apply_fn_to_signeds!(mod_power_of_2_properties_helper_signed);
}
fn rem_power_of_2_properties_helper<T: PrimitiveSigned>() {
signed_unsigned_pair_gen_var_1::<T, u64>().test_properties(|(n, pow)| {
let mut mut_n = n;
mut_n.rem_power_of_2_assign(pow);
let result = mut_n;
assert_eq!(n.rem_power_of_2(pow), result);
if n != T::MIN {
assert_eq!((-n).rem_power_of_2(pow), -result);
}
assert!(result.le_abs(&n));
assert_eq!(result == T::ZERO, n.divisible_by_power_of_2(pow));
assert_eq!(result.rem_power_of_2(pow), result);
assert!(result == T::ZERO || (result > T::ZERO) == (n > T::ZERO));
});
signed_gen::<T>().test_properties(|n| {
assert_eq!(n.rem_power_of_2(0), T::ZERO);
});
unsigned_gen().test_properties(|pow| {
assert_eq!(T::ZERO.rem_power_of_2(pow), T::ZERO);
});
}
#[test]
fn rem_power_of_2_properties() {
apply_fn_to_signeds!(rem_power_of_2_properties_helper);
}
fn neg_mod_power_of_2_properties_helper<T: PrimitiveUnsigned>() {
unsigned_pair_gen_var_20::<T>().test_properties(|(n, pow)| {
let mut mut_n = n;
mut_n.neg_mod_power_of_2_assign(pow);
let result = mut_n;
assert!(result.mod_power_of_2_is_reduced(pow));
assert_eq!(n.neg_mod_power_of_2(pow), result);
assert_eq!(result == T::ZERO, n.divisible_by_power_of_2(pow));
assert!(result
.wrapping_add(n.mod_power_of_2(pow))
.divisible_by_power_of_2(pow));
assert_eq!(result.neg_mod_power_of_2(pow), n.mod_power_of_2(pow));
});
unsigned_gen::<T>().test_properties(|n| {
assert_eq!(n.neg_mod_power_of_2(0), T::ZERO);
});
unsigned_gen().test_properties(|pow| {
assert_eq!(T::ZERO.neg_mod_power_of_2(pow), T::ZERO);
});
}
#[test]
fn neg_mod_power_of_2_properties() {
apply_fn_to_unsigneds!(neg_mod_power_of_2_properties_helper);
}
fn ceiling_mod_power_of_2_properties_helper<
U: PrimitiveUnsigned + WrappingFrom<S>,
S: PrimitiveSigned + WrappingFrom<U>,
>() {
signed_unsigned_pair_gen_var_11::<U, S>().test_properties(|(n, pow)| {
let mut mut_n = n;
mut_n.ceiling_mod_power_of_2_assign(pow);
let result = mut_n;
assert_eq!(n.ceiling_mod_power_of_2(pow), result);
assert!(result <= S::ZERO);
assert_eq!(result == S::ZERO, n.divisible_by_power_of_2(pow));
});
signed_gen::<S>().test_properties(|n| {
assert_eq!(n.ceiling_mod_power_of_2(0), S::ZERO);
});
unsigned_gen().test_properties(|pow| {
assert_eq!(S::ZERO.ceiling_mod_power_of_2(pow), S::ZERO);
});
}
#[test]
fn ceiling_mod_power_of_2_properties() {
apply_fn_to_unsigned_signed_pairs!(ceiling_mod_power_of_2_properties_helper);
}