// Copyright © 2024 Mikhail Hogrefe
//
// This file is part of Malachite.
//
// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
// 3 of the License, or (at your option) any later version. See .
use malachite_base::num::basic::integers::PrimitiveInt;
use malachite_base::num::basic::signeds::PrimitiveSigned;
use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
use malachite_base::rounding_modes::RoundingMode::*;
use malachite_base::test_util::generators::{
signed_gen, signed_gen_var_6, signed_pair_gen_var_3, unsigned_gen, unsigned_gen_var_1,
unsigned_pair_gen_var_11,
};
use std::panic::catch_unwind;
#[test]
fn test_div_exact() {
fn test(x: T, y: T, out: T) {
assert_eq!(x.div_exact(y), out);
let mut x = x;
x.div_exact_assign(y);
assert_eq!(x, out);
}
test::(0, 123, 0);
test::(123, 1, 123);
test::(123, 123, 1);
test::(56088, 123, 456);
test::(0, 1000000000000, 0);
test::(1000000000000, 1, 1000000000000);
test::(1000000000000, 1000000000000, 1);
test::(123000000000000, 1000000000000, 123);
test::(123000000000000, 123, 1000000000000);
test::(121932631112635269000000, 123456789000, 987654321000);
test::(0x1fffffffe, 0xffffffff, 2);
test::(18446744065119617025, 0xffffffff, 0xffffffff);
test::(0, -123, 0);
test::(123, -1, -123);
test::(123, -123, -1);
test::(56088, -123, -456);
test::(0, -1000000000000, 0);
test::(1000000000000, -1, -1000000000000);
test::(1000000000000, -1000000000000, -1);
test::(123000000000000, -1000000000000, -123);
test::(123000000000000, -123, -1000000000000);
test::(121932631112635269000000, -123456789000, -987654321000);
test::(0x1fffffffe, -0xffffffff, -2);
test::(18446744065119617025, -0xffffffff, -0xffffffff);
test::(-123, 1, -123);
test::(-123, 123, -1);
test::(-56088, 123, -456);
test::(-1000000000000, 1, -1000000000000);
test::(-1000000000000, 1000000000000, -1);
test::(-123000000000000, 1000000000000, -123);
test::(-123000000000000, 123, -1000000000000);
test::(-121932631112635269000000, 123456789000, -987654321000);
test::(-0x1fffffffe, 0xffffffff, -2);
test::(-18446744065119617025, 0xffffffff, -0xffffffff);
test::(-123, -1, 123);
test::(-123, -123, 1);
test::(-56088, -123, 456);
test::(-1000000000000, -1, 1000000000000);
test::(-1000000000000, -1000000000000, 1);
test::(-123000000000000, -1000000000000, 123);
test::(-123000000000000, -123, 1000000000000);
test::(-121932631112635269000000, -123456789000, 987654321000);
test::(-0x1fffffffe, -0xffffffff, 2);
test::(-18446744065119617025, -0xffffffff, 0xffffffff);
}
fn div_exact_fail_helper() {
assert_panic!(T::ONE.div_exact(T::ZERO));
assert_panic!({
let mut n = T::ONE;
n.div_exact_assign(T::ZERO);
});
}
#[test]
pub fn div_exact_fail() {
apply_fn_to_primitive_ints!(div_exact_fail_helper);
}
fn div_exact_properties_helper_unsigned() {
unsigned_pair_gen_var_11::().test_properties(|(x, y)| {
let mut mut_x = x;
mut_x.div_exact_assign(y);
let q = mut_x;
assert_eq!(x.div_exact(y), q);
assert_eq!(x.div_round(y, Exact).0, q);
assert_eq!(q * y, x);
});
unsigned_gen::().test_properties(|x| {
assert_eq!(x.div_exact(T::ONE), x);
assert_panic!(x.div_exact(T::ZERO));
assert_panic!({
let mut y = x;
y.div_exact_assign(T::ZERO);
});
});
unsigned_gen_var_1::().test_properties(|x| {
assert_eq!(T::ZERO.div_exact(x), T::ZERO);
assert_eq!(x.div_exact(x), T::ONE);
});
}
fn div_exact_properties_helper_signed() {
signed_pair_gen_var_3::().test_properties(|(x, y)| {
let mut mut_x = x;
mut_x.div_exact_assign(y);
let q = mut_x;
assert_eq!(x.div_exact(y), q);
assert_eq!(x.div_round(y, Exact).0, q);
assert_eq!(q * y, x);
if x != T::MIN {
assert_eq!((-x).div_exact(y), -q);
}
if y != T::MIN && q != T::MIN {
assert_eq!(x.div_exact(-y), -q);
}
});
signed_gen::().test_properties(|x| {
assert_eq!(x.div_exact(T::ONE), x);
assert_panic!(x.div_exact(T::ZERO));
assert_panic!({
let mut y = x;
y.div_exact_assign(T::ZERO);
});
});
signed_gen_var_6::().test_properties(|x| {
assert_eq!(T::ZERO.div_exact(x), T::ZERO);
assert_eq!(x.div_exact(x), T::ONE);
});
}
#[test]
fn div_exact_properties() {
apply_fn_to_unsigneds!(div_exact_properties_helper_unsigned);
apply_fn_to_signeds!(div_exact_properties_helper_signed);
}