// 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_4, unsigned_gen, unsigned_gen_var_1, unsigned_pair_gen_var_12, }; use std::panic::catch_unwind; #[test] fn test_div_mod_and_div_rem_unsigned() { fn test(n: T, d: T, q: T, r: T) { assert_eq!(n.div_mod(d), (q, r)); let mut mut_n = n; assert_eq!(mut_n.div_assign_mod(d), r); assert_eq!(mut_n, q); assert_eq!(n.div_rem(d), (q, r)); let mut mut_n = n; assert_eq!(mut_n.div_assign_rem(d), r); assert_eq!(mut_n, q); } test::(0, 1, 0, 0); test::(0, 123, 0, 0); test::(1, 1, 1, 0); test::(123, 1, 123, 0); test::(123, 123, 1, 0); test::(123, 456, 0, 123); test::(456, 123, 3, 87); test::(u32::MAX, 1, u32::MAX, 0); test::(0xffffffff, 0xffffffff, 1, 0); test::(1000000000000, 1, 1000000000000, 0); test::(1000000000000, 3, 333333333333, 1); test::(1000000000000, 123, 8130081300, 100); test::(1000000000000, 0xffffffff, 232, 3567587560); test::(1000000000000000000000000, 1, 1000000000000000000000000, 0); test::(1000000000000000000000000, 3, 333333333333333333333333, 1); test::(1000000000000000000000000, 123, 8130081300813008130081, 37); test::( 1000000000000000000000000, 0xffffffff, 232830643708079, 3167723695, ); test::( 1000000000000000000000000, 1234567890987, 810000006723, 530068894399, ); test::( 253640751230376270397812803167, 2669936877441, 94998781946290113, 1520301762334, ); test::(3768477692975601, 11447376614057827956, 0, 3768477692975601); test::(3356605361737854, 3081095617839357, 1, 275509743898497); test::( 1098730198198174614195, 953382298040157850476, 1, 145347900158016763719, ); test::( 69738658860594537152875081748, 69738658860594537152875081748, 1, 0, ); test::(1000000000000000000000000, 1000000000000000000000000, 1, 0); test::(0, 1000000000000000000000000, 0, 0); test::(123, 1000000000000000000000000, 0, 123); } fn div_mod_and_div_rem_properties_helper_unsigned() { unsigned_pair_gen_var_12::().test_properties(|(x, y)| { let mut mut_x = x; let r = mut_x.div_assign_mod(y); let q = mut_x; assert_eq!(x.div_mod(y), (q, r)); let mut mut_x = x; let r_alt = mut_x.div_assign_rem(y); let q_alt = mut_x; assert_eq!((q_alt, r_alt), (q, r)); assert_eq!(x.div_rem(y), (q, r)); assert_eq!((x / y, x % y), (q, r)); assert!(r < y); assert_eq!(q * y + r, x); }); unsigned_gen::().test_properties(|x| { assert_eq!(x.div_mod(T::ONE), (x, T::ZERO)); assert_panic!(x.div_mod(T::ZERO)); assert_panic!({ let mut y = x; y.div_assign_mod(T::ZERO) }); }); unsigned_gen_var_1::().test_properties(|x| { assert_eq!(x.div_mod(x), (T::ONE, T::ZERO)); assert_eq!(T::ZERO.div_mod(x), (T::ZERO, T::ZERO)); if x > T::ONE { assert_eq!(T::ONE.div_mod(x), (T::ZERO, T::ONE)); } }); } #[test] fn test_div_mod_signed() { fn test(n: T, d: T, q: T, r: T) { assert_eq!(n.div_mod(d), (q, r)); let mut mut_n = n; assert_eq!(mut_n.div_assign_mod(d), r); assert_eq!(mut_n, q); } test::(0, 1, 0, 0); test::(0, 123, 0, 0); test::(1, 1, 1, 0); test::(123, 1, 123, 0); test::(123, 123, 1, 0); test::(123, 456, 0, 123); test::(456, 123, 3, 87); test::(0xffffffff, 1, 0xffffffff, 0); test::(0xffffffff, 0xffffffff, 1, 0); test::(1000000000000, 1, 1000000000000, 0); test::(1000000000000, 3, 333333333333, 1); test::(1000000000000, 123, 8130081300, 100); test::(1000000000000, 0xffffffff, 232, 3567587560); test::(1000000000000000000000000, 1, 1000000000000000000000000, 0); test::(1000000000000000000000000, 3, 333333333333333333333333, 1); test::(1000000000000000000000000, 123, 8130081300813008130081, 37); test::( 1000000000000000000000000, 0xffffffff, 232830643708079, 3167723695, ); test::( 1000000000000000000000000, 1234567890987, 810000006723, 530068894399, ); test::( 253640751230376270397812803167, 2669936877441, 94998781946290113, 1520301762334, ); test::(3768477692975601, 11447376614057827956, 0, 3768477692975601); test::(3356605361737854, 3081095617839357, 1, 275509743898497); test::( 1098730198198174614195, 953382298040157850476, 1, 145347900158016763719, ); test::( 69738658860594537152875081748, 69738658860594537152875081748, 1, 0, ); test::(1000000000000000000000000, 1000000000000000000000000, 1, 0); test::(0, 1000000000000000000000000, 0, 0); test::(123, 1000000000000000000000000, 0, 123); test::(0, -1, 0, 0); test::(0, -123, 0, 0); test::(1, -1, -1, 0); test::(123, -1, -123, 0); test::(123, -123, -1, 0); test::(123, -456, -1, -333); test::(456, -123, -4, -36); test::(0xffffffff, -1, -0xffffffff, 0); test::(0xffffffff, -0xffffffff, -1, 0); test::(1000000000000, -1, -1000000000000, 0); test::(1000000000000, -3, -333333333334, -2); test::(1000000000000, -123, -8130081301, -23); test::(1000000000000, -0xffffffff, -233, -727379735); test::(1000000000000000000000000, -1, -1000000000000000000000000, 0); test::(1000000000000000000000000, -3, -333333333333333333333334, -2); test::( 1000000000000000000000000, -123, -8130081300813008130082, -86, ); test::( 1000000000000000000000000, -0xffffffff, -232830643708080, -1127243600, ); test::( 1000000000000000000000000, -1234567890987, -810000006724, -704498996588, ); test::( 253640751230376270397812803167, -2669936877441, -94998781946290114, -1149635115107, ); test::( 3768477692975601, -11447376614057827956, -1, -11443608136364852355, ); test::(3356605361737854, -3081095617839357, -2, -2805585873940860); test::( 1098730198198174614195, -953382298040157850476, -2, -808034397882141086757, ); test::( 69738658860594537152875081748, -69738658860594537152875081748, -1, 0, ); test::(1000000000000000000000000, -1000000000000000000000000, -1, 0); test::(0, -1000000000000000000000000, 0, 0); test::( 123, -1000000000000000000000000, -1, -999999999999999999999877, ); test::(-1, 1, -1, 0); test::(-123, 1, -123, 0); test::(-123, 123, -1, 0); test::(-123, 456, -1, 333); test::(-456, 123, -4, 36); test::(-0xffffffff, -1, 0xffffffff, 0); test::(-0xffffffff, 0xffffffff, -1, 0); test::(-1000000000000, 1, -1000000000000, 0); test::(-1000000000000, 3, -333333333334, 2); test::(-1000000000000, 123, -8130081301, 23); test::(-1000000000000, 0xffffffff, -233, 727379735); test::(-1000000000000000000000000, 1, -1000000000000000000000000, 0); test::(-1000000000000000000000000, 3, -333333333333333333333334, 2); test::(-1000000000000000000000000, 123, -8130081300813008130082, 86); test::( -1000000000000000000000000, 0xffffffff, -232830643708080, 1127243600, ); test::( -1000000000000000000000000, 1234567890987, -810000006724, 704498996588, ); test::( -253640751230376270397812803167, 2669936877441, -94998781946290114, 1149635115107, ); test::( -3768477692975601, 11447376614057827956, -1, 11443608136364852355, ); test::(-3356605361737854, 3081095617839357, -2, 2805585873940860); test::( -1098730198198174614195, 953382298040157850476, -2, 808034397882141086757, ); test::( -69738658860594537152875081748, 69738658860594537152875081748, -1, 0, ); test::(-1000000000000000000000000, 1000000000000000000000000, -1, 0); test::( -123, 1000000000000000000000000, -1, 999999999999999999999877, ); test::(-1, -1, 1, 0); test::(-123, -1, 123, 0); test::(-123, -123, 1, 0); test::(-123, -456, 0, -123); test::(-456, -123, 3, -87); test::(-0xffffffff, -1, 0xffffffff, 0); test::(-0xffffffff, -0xffffffff, 1, 0); test::(-1000000000000, -1, 1000000000000, 0); test::(-1000000000000, -3, 333333333333, -1); test::(-1000000000000, -123, 8130081300, -100); test::(-1000000000000, -0xffffffff, 232, -3567587560); test::(-1000000000000000000000000, -1, 1000000000000000000000000, 0); test::(-1000000000000000000000000, -3, 333333333333333333333333, -1); test::( -1000000000000000000000000, -123, 8130081300813008130081, -37, ); test::( -1000000000000000000000000, -0xffffffff, 232830643708079, -3167723695, ); test::( -1000000000000000000000000, -1234567890987, 810000006723, -530068894399, ); test::( -253640751230376270397812803167, -2669936877441, 94998781946290113, -1520301762334, ); test::( -3768477692975601, -11447376614057827956, 0, -3768477692975601, ); test::(-3356605361737854, -3081095617839357, 1, -275509743898497); test::( -1098730198198174614195, -953382298040157850476, 1, -145347900158016763719, ); test::( -69738658860594537152875081748, -69738658860594537152875081748, 1, 0, ); test::(-1000000000000000000000000, -1000000000000000000000000, 1, 0); test::(-123, -1000000000000000000000000, 0, -123); } fn div_mod_fail_helper() { assert_panic!(T::ONE.div_mod(T::ZERO)); assert_panic!({ let mut n = T::ONE; n.div_assign_mod(T::ZERO); }); } fn div_mod_signed_fail_helper() { assert_panic!(T::MIN.div_mod(T::NEGATIVE_ONE)); assert_panic!({ let mut n = T::MIN; n.div_assign_mod(T::NEGATIVE_ONE); }); } #[test] pub fn div_mod_fail() { apply_fn_to_primitive_ints!(div_mod_fail_helper); apply_fn_to_signeds!(div_mod_signed_fail_helper); } fn div_mod_properties_helper_signed() { signed_pair_gen_var_4::().test_properties(|(x, y)| { let mut mut_x = x; let r = mut_x.div_assign_mod(y); let q = mut_x; assert_eq!(x.div_mod(y), (q, r)); let (q_alt, r_alt) = (x.div_round(y, Floor).0, x.mod_op(y)); assert_eq!(q_alt, q); assert_eq!(r_alt, r); assert!(r.lt_abs(&y)); assert!(r == T::ZERO || (r > T::ZERO) == (y > T::ZERO)); if let Some(product) = q.checked_mul(y) { assert_eq!(product + r, x); } else if q > T::ZERO { assert_eq!((q - T::ONE) * y + r + y, x); } else { assert_eq!((q + T::ONE) * y + r - y, x); } if x != T::MIN { let (neg_q, neg_r) = (-x).div_mod(y); assert_eq!(x.ceiling_div_mod(y), (-neg_q, -neg_r)); } if y != T::MIN && (x != T::MIN || y != T::ONE) { let (neg_q, r) = x.div_mod(-y); assert_eq!(x.ceiling_div_mod(y), (-neg_q, r)); } }); signed_gen::().test_properties(|x| { let (q, r) = x.div_mod(T::ONE); assert_eq!(q, x); assert_eq!(r, T::ZERO); if x != T::MIN { let (q, r) = x.div_mod(T::NEGATIVE_ONE); assert_eq!(q, -x); assert_eq!(r, T::ZERO); } assert_panic!(x.div_mod(T::ZERO)); assert_panic!({ let mut y = x; y.div_assign_mod(T::ZERO) }); }); signed_gen_var_6::().test_properties(|x| { assert_eq!(x.div_mod(T::ONE), (x, T::ZERO)); assert_eq!(x.div_mod(x), (T::ONE, T::ZERO)); assert_eq!(T::ZERO.div_mod(x), (T::ZERO, T::ZERO)); if x != T::MIN { assert_eq!(x.div_mod(T::NEGATIVE_ONE), (-x, T::ZERO)); assert_eq!(x.div_mod(-x), (T::NEGATIVE_ONE, T::ZERO)); } if x > T::ONE { assert_eq!(T::ONE.div_mod(x), (T::ZERO, T::ONE)); assert_eq!(T::NEGATIVE_ONE.div_mod(x), (T::NEGATIVE_ONE, x - T::ONE)); } }); } #[test] fn div_mod_properties() { apply_fn_to_unsigneds!(div_mod_and_div_rem_properties_helper_unsigned); apply_fn_to_signeds!(div_mod_properties_helper_signed); } #[test] fn test_div_rem_signed() { fn test(n: T, d: T, q: T, r: T) { assert_eq!(n.div_rem(d), (q, r)); let mut mut_n = n; assert_eq!(mut_n.div_assign_rem(d), r); assert_eq!(mut_n, q); } test::(0, 1, 0, 0); test::(0, 123, 0, 0); test::(1, 1, 1, 0); test::(123, 1, 123, 0); test::(123, 123, 1, 0); test::(123, 456, 0, 123); test::(456, 123, 3, 87); test::(0xffffffff, 1, 0xffffffff, 0); test::(0xffffffff, 0xffffffff, 1, 0); test::(1000000000000, 1, 1000000000000, 0); test::(1000000000000, 3, 333333333333, 1); test::(1000000000000, 123, 8130081300, 100); test::(1000000000000, 0xffffffff, 232, 3567587560); test::(1000000000000000000000000, 1, 1000000000000000000000000, 0); test::(1000000000000000000000000, 3, 333333333333333333333333, 1); test::(1000000000000000000000000, 123, 8130081300813008130081, 37); test::( 1000000000000000000000000, 0xffffffff, 232830643708079, 3167723695, ); test::( 1000000000000000000000000, 1234567890987, 810000006723, 530068894399, ); test::( 253640751230376270397812803167, 2669936877441, 94998781946290113, 1520301762334, ); test::(3768477692975601, 11447376614057827956, 0, 3768477692975601); test::(3356605361737854, 3081095617839357, 1, 275509743898497); test::( 1098730198198174614195, 953382298040157850476, 1, 145347900158016763719, ); test::( 69738658860594537152875081748, 69738658860594537152875081748, 1, 0, ); test::(1000000000000000000000000, 1000000000000000000000000, 1, 0); test::(0, 1000000000000000000000000, 0, 0); test::(123, 1000000000000000000000000, 0, 123); test::(0, -1, 0, 0); test::(0, -123, 0, 0); test::(1, -1, -1, 0); test::(123, -1, -123, 0); test::(123, -123, -1, 0); test::(123, -456, 0, 123); test::(456, -123, -3, 87); test::(0xffffffff, -1, -0xffffffff, 0); test::(0xffffffff, -0xffffffff, -1, 0); test::(1000000000000, -1, -1000000000000, 0); test::(1000000000000, -3, -333333333333, 1); test::(1000000000000, -123, -8130081300, 100); test::(1000000000000, -0xffffffff, -232, 3567587560); test::(1000000000000000000000000, -1, -1000000000000000000000000, 0); test::(1000000000000000000000000, -3, -333333333333333333333333, 1); test::(1000000000000000000000000, -123, -8130081300813008130081, 37); test::( 1000000000000000000000000, -0xffffffff, -232830643708079, 3167723695, ); test::( 1000000000000000000000000, -1234567890987, -810000006723, 530068894399, ); test::( 253640751230376270397812803167, -2669936877441, -94998781946290113, 1520301762334, ); test::(3768477692975601, -11447376614057827956, 0, 3768477692975601); test::(3356605361737854, -3081095617839357, -1, 275509743898497); test::( 1098730198198174614195, -953382298040157850476, -1, 145347900158016763719, ); test::( 69738658860594537152875081748, -69738658860594537152875081748, -1, 0, ); test::(1000000000000000000000000, -1000000000000000000000000, -1, 0); test::(0, -1000000000000000000000000, 0, 0); test::(123, -1000000000000000000000000, 0, 123); test::(-1, 1, -1, 0); test::(-123, 1, -123, 0); test::(-123, 123, -1, 0); test::(-123, 456, 0, -123); test::(-456, 123, -3, -87); test::(-0xffffffff, 1, -0xffffffff, 0); test::(-0xffffffff, 0xffffffff, -1, 0); test::(-1000000000000, 1, -1000000000000, 0); test::(-1000000000000, 3, -333333333333, -1); test::(-1000000000000, 123, -8130081300, -100); test::(-1000000000000, 0xffffffff, -232, -3567587560); test::(-1000000000000000000000000, 1, -1000000000000000000000000, 0); test::(-1000000000000000000000000, 3, -333333333333333333333333, -1); test::( -1000000000000000000000000, 123, -8130081300813008130081, -37, ); test::( -1000000000000000000000000, 0xffffffff, -232830643708079, -3167723695, ); test::( -1000000000000000000000000, 1234567890987, -810000006723, -530068894399, ); test::( -253640751230376270397812803167, 2669936877441, -94998781946290113, -1520301762334, ); test::( -3768477692975601, 11447376614057827956, 0, -3768477692975601, ); test::(-3356605361737854, 3081095617839357, -1, -275509743898497); test::( -1098730198198174614195, 953382298040157850476, -1, -145347900158016763719, ); test::( -69738658860594537152875081748, 69738658860594537152875081748, -1, 0, ); test::(-1000000000000000000000000, 1000000000000000000000000, -1, 0); test::(-123, 1000000000000000000000000, 0, -123); test::(-1, -1, 1, 0); test::(-123, -1, 123, 0); test::(-123, -123, 1, 0); test::(-123, -456, 0, -123); test::(-456, -123, 3, -87); test::(-0xffffffff, -1, 0xffffffff, 0); test::(-0xffffffff, -0xffffffff, 1, 0); test::(-1000000000000, -1, 1000000000000, 0); test::(-1000000000000, -3, 333333333333, -1); test::(-1000000000000, -123, 8130081300, -100); test::(-1000000000000, -0xffffffff, 232, -3567587560); test::(-1000000000000000000000000, -1, 1000000000000000000000000, 0); test::(-1000000000000000000000000, -3, 333333333333333333333333, -1); test::( -1000000000000000000000000, -123, 8130081300813008130081, -37, ); test::( -1000000000000000000000000, -0xffffffff, 232830643708079, -3167723695, ); test::( -1000000000000000000000000, -1234567890987, 810000006723, -530068894399, ); test::( -253640751230376270397812803167, -2669936877441, 94998781946290113, -1520301762334, ); test::( -3768477692975601, -11447376614057827956, 0, -3768477692975601, ); test::(-3356605361737854, -3081095617839357, 1, -275509743898497); test::( -1098730198198174614195, -953382298040157850476, 1, -145347900158016763719, ); test::( -69738658860594537152875081748, -69738658860594537152875081748, 1, 0, ); test::(-1000000000000000000000000, -1000000000000000000000000, 1, 0); test::(-123, -1000000000000000000000000, 0, -123); } fn div_rem_fail_helper() { assert_panic!(T::ONE.div_rem(T::ZERO)); assert_panic!({ let mut n = T::ONE; n.div_assign_rem(T::ZERO); }); } fn div_rem_signed_fail_helper() { assert_panic!(T::MIN.div_rem(T::NEGATIVE_ONE)); assert_panic!({ let mut n = T::MIN; n.div_assign_rem(T::NEGATIVE_ONE); }); } #[test] pub fn div_rem_fail() { apply_fn_to_primitive_ints!(div_rem_fail_helper); apply_fn_to_signeds!(div_rem_signed_fail_helper); } fn div_rem_properties_helper_signed() { signed_pair_gen_var_4::().test_properties(|(x, y)| { let mut mut_x = x; let r = mut_x.div_assign_rem(y); let q = mut_x; assert_eq!(x.div_rem(y), (q, r)); assert_eq!((x / y, x % y), (q, r)); assert!(r.lt_abs(&y)); assert!(r == T::ZERO || (r > T::ZERO) == (x > T::ZERO)); assert_eq!(q * y + r, x); if x != T::MIN { assert_eq!((-x).div_rem(y), (-q, -r)); } if y != T::MIN && (x != T::MIN || y != T::ONE) { assert_eq!(x.div_rem(-y), (-q, r)); } }); signed_gen::().test_properties(|x| { let (q, r) = x.div_rem(T::ONE); assert_eq!(q, x); assert_eq!(r, T::ZERO); if x != T::MIN { let (q, r) = x.div_rem(T::NEGATIVE_ONE); assert_eq!(q, -x); assert_eq!(r, T::ZERO); } assert_panic!(x.div_rem(T::ZERO)); assert_panic!({ let mut y = x; y.div_assign_rem(T::ZERO) }); }); signed_gen_var_6::().test_properties(|x| { assert_eq!(x.div_rem(T::ONE), (x, T::ZERO)); assert_eq!(x.div_rem(x), (T::ONE, T::ZERO)); assert_eq!(T::ZERO.div_rem(x), (T::ZERO, T::ZERO)); if x != T::MIN { assert_eq!(x.div_rem(T::NEGATIVE_ONE), (-x, T::ZERO)); assert_eq!(x.div_rem(-x), (T::NEGATIVE_ONE, T::ZERO)); } if x > T::ONE { assert_eq!(T::ONE.div_rem(x), (T::ZERO, T::ONE)); assert_eq!(T::NEGATIVE_ONE.div_rem(x), (T::ZERO, T::NEGATIVE_ONE)); } }); } #[test] fn div_rem_properties() { apply_fn_to_signeds!(div_rem_properties_helper_signed); } #[test] fn test_ceiling_div_neg_mod() { fn test(n: T, d: T, q: T, r: T) { assert_eq!(n.ceiling_div_neg_mod(d), (q, r)); let mut mut_n = n; assert_eq!(mut_n.ceiling_div_assign_neg_mod(d), r); assert_eq!(mut_n, q); } test::(0, 1, 0, 0); test::(0, 123, 0, 0); test::(1, 1, 1, 0); test::(123, 1, 123, 0); test::(123, 123, 1, 0); test::(123, 456, 1, 333); test::(456, 123, 4, 36); test::(0xffffffff, 1, 0xffffffff, 0); test::(0xffffffff, 0xffffffff, 1, 0); test::(1000000000000, 1, 1000000000000, 0); test::(1000000000000, 3, 333333333334, 2); test::(1000000000000, 123, 8130081301, 23); test::(1000000000000, 0xffffffff, 233, 727379735); test::(1000000000000000000000000, 1, 1000000000000000000000000, 0); test::(1000000000000000000000000, 3, 333333333333333333333334, 2); test::(1000000000000000000000000, 123, 8130081300813008130082, 86); test::( 1000000000000000000000000, 0xffffffff, 232830643708080, 1127243600, ); test::( 1000000000000000000000000, 1234567890987, 810000006724, 704498996588, ); test::( 253640751230376270397812803167, 2669936877441, 94998781946290114, 1149635115107, ); test::( 3768477692975601, 11447376614057827956, 1, 11443608136364852355, ); test::(3356605361737854, 3081095617839357, 2, 2805585873940860); test::( 1098730198198174614195, 953382298040157850476, 2, 808034397882141086757, ); test::( 69738658860594537152875081748, 69738658860594537152875081748, 1, 0, ); test::(1000000000000000000000000, 1000000000000000000000000, 1, 0); test::(0, 1000000000000000000000000, 0, 0); test::(123, 1000000000000000000000000, 1, 999999999999999999999877); } fn ceiling_div_neg_mod_fail_helper() { assert_panic!(T::ONE.ceiling_div_neg_mod(T::ZERO)); assert_panic!({ let mut n = T::ONE; n.ceiling_div_assign_neg_mod(T::ZERO); }); } #[test] pub fn ceiling_div_neg_mod_fail() { apply_fn_to_unsigneds!(ceiling_div_neg_mod_fail_helper); } fn ceiling_div_neg_mod_properties_helper() { unsigned_pair_gen_var_12::().test_properties(|(x, y)| { let mut mut_x = x; let r = mut_x.ceiling_div_assign_neg_mod(y); let q = mut_x; assert_eq!(x.ceiling_div_neg_mod(y), (q, r)); let (q_alt, r_alt) = (x.div_round(y, Ceiling).0, x.neg_mod(y)); assert_eq!(q_alt, q); assert_eq!(r_alt, r); assert!(r < y); if let Some(product) = q.checked_mul(y) { assert_eq!(product - r, x); } else { assert_eq!((q - T::ONE) * y - r + y, x); } }); unsigned_gen::().test_properties(|x| { assert_eq!(x.ceiling_div_neg_mod(T::ONE), (x, T::ZERO)); assert_panic!(x.ceiling_div_neg_mod(T::ZERO)); assert_panic!({ let mut y = x; y.ceiling_div_assign_neg_mod(T::ZERO) }); }); unsigned_gen_var_1::().test_properties(|x| { assert_eq!(x.ceiling_div_neg_mod(x), (T::ONE, T::ZERO)); assert_eq!(T::ZERO.ceiling_div_neg_mod(x), (T::ZERO, T::ZERO)); if x > T::ONE { assert_eq!(T::ONE.ceiling_div_neg_mod(x), (T::ONE, x - T::ONE)); } }); } #[test] fn ceiling_div_neg_mod_properties() { apply_fn_to_unsigneds!(ceiling_div_neg_mod_properties_helper); } #[test] fn test_ceiling_div_mod() { fn test(n: T, d: T, q: T, r: T) { assert_eq!(n.ceiling_div_mod(d), (q, r)); let mut mut_n = n; assert_eq!(mut_n.ceiling_div_assign_mod(d), r); assert_eq!(mut_n, q); } test::(0, 1, 0, 0); test::(0, 123, 0, 0); test::(1, 1, 1, 0); test::(123, 1, 123, 0); test::(123, 123, 1, 0); test::(123, 456, 1, -333); test::(456, 123, 4, -36); test::(0xffffffff, 1, 0xffffffff, 0); test::(0xffffffff, 0xffffffff, 1, 0); test::(1000000000000, 1, 1000000000000, 0); test::(1000000000000, 3, 333333333334, -2); test::(1000000000000, 123, 8130081301, -23); test::(1000000000000, 0xffffffff, 233, -727379735); test::(1000000000000000000000000, 1, 1000000000000000000000000, 0); test::(1000000000000000000000000, 3, 333333333333333333333334, -2); test::(1000000000000000000000000, 123, 8130081300813008130082, -86); test::( 1000000000000000000000000, 0xffffffff, 232830643708080, -1127243600, ); test::( 1000000000000000000000000, 1234567890987, 810000006724, -704498996588, ); test::( 253640751230376270397812803167, 2669936877441, 94998781946290114, -1149635115107, ); test::( 3768477692975601, 11447376614057827956, 1, -11443608136364852355, ); test::(3356605361737854, 3081095617839357, 2, -2805585873940860); test::( 1098730198198174614195, 953382298040157850476, 2, -808034397882141086757, ); test::( 69738658860594537152875081748, 69738658860594537152875081748, 1, 0, ); test::(1000000000000000000000000, 1000000000000000000000000, 1, 0); test::(0, 1000000000000000000000000, 0, 0); test::(123, 1000000000000000000000000, 1, -999999999999999999999877); test::(0, -1, 0, 0); test::(0, -123, 0, 0); test::(1, -1, -1, 0); test::(123, -1, -123, 0); test::(123, -123, -1, 0); test::(123, -456, 0, 123); test::(456, -123, -3, 87); test::(0xffffffff, -1, -0xffffffff, 0); test::(0xffffffff, -0xffffffff, -1, 0); test::(1000000000000, -1, -1000000000000, 0); test::(1000000000000, -3, -333333333333, 1); test::(1000000000000, -123, -8130081300, 100); test::(1000000000000, -0xffffffff, -232, 3567587560); test::(1000000000000000000000000, -1, -1000000000000000000000000, 0); test::(1000000000000000000000000, -3, -333333333333333333333333, 1); test::(1000000000000000000000000, -123, -8130081300813008130081, 37); test::( 1000000000000000000000000, -0xffffffff, -232830643708079, 3167723695, ); test::( 1000000000000000000000000, -1234567890987, -810000006723, 530068894399, ); test::( 253640751230376270397812803167, -2669936877441, -94998781946290113, 1520301762334, ); test::(3768477692975601, -11447376614057827956, 0, 3768477692975601); test::(3356605361737854, -3081095617839357, -1, 275509743898497); test::( 1098730198198174614195, -953382298040157850476, -1, 145347900158016763719, ); test::( 69738658860594537152875081748, -69738658860594537152875081748, -1, 0, ); test::(1000000000000000000000000, -1000000000000000000000000, -1, 0); test::(0, -1000000000000000000000000, 0, 0); test::(123, -1000000000000000000000000, 0, 123); test::(-1, 1, -1, 0); test::(-123, 1, -123, 0); test::(-123, 123, -1, 0); test::(-123, 456, 0, -123); test::(-456, 123, -3, -87); test::(-0xffffffff, 1, -0xffffffff, 0); test::(-0xffffffff, 0xffffffff, -1, 0); test::(-1000000000000, 1, -1000000000000, 0); test::(-1000000000000, 3, -333333333333, -1); test::(-1000000000000, 123, -8130081300, -100); test::(-1000000000000, 0xffffffff, -232, -3567587560); test::(-1000000000000000000000000, 1, -1000000000000000000000000, 0); test::(-1000000000000000000000000, 3, -333333333333333333333333, -1); test::( -1000000000000000000000000, 123, -8130081300813008130081, -37, ); test::( -1000000000000000000000000, 0xffffffff, -232830643708079, -3167723695, ); test::( -1000000000000000000000000, 1234567890987, -810000006723, -530068894399, ); test::( -253640751230376270397812803167, 2669936877441, -94998781946290113, -1520301762334, ); test::( -3768477692975601, 11447376614057827956, 0, -3768477692975601, ); test::(-3356605361737854, 3081095617839357, -1, -275509743898497); test::( -1098730198198174614195, 953382298040157850476, -1, -145347900158016763719, ); test::( -69738658860594537152875081748, 69738658860594537152875081748, -1, 0, ); test::(-1000000000000000000000000, 1000000000000000000000000, -1, 0); test::(0, 1000000000000000000000000, 0, 0); test::(-123, 1000000000000000000000000, 0, -123); test::(-1, -1, 1, 0); test::(-123, -1, 123, 0); test::(-123, -123, 1, 0); test::(-123, -456, 1, 333); test::(-456, -123, 4, 36); test::(-0xffffffff, -1, 0xffffffff, 0); test::(-0xffffffff, -0xffffffff, 1, 0); test::(-1000000000000, -1, 1000000000000, 0); test::(-1000000000000, -3, 333333333334, 2); test::(-1000000000000, -123, 8130081301, 23); test::(-1000000000000, -0xffffffff, 233, 727379735); test::(-1000000000000000000000000, -1, 1000000000000000000000000, 0); test::(-1000000000000000000000000, -3, 333333333333333333333334, 2); test::(-1000000000000000000000000, -123, 8130081300813008130082, 86); test::( -1000000000000000000000000, -0xffffffff, 232830643708080, 1127243600, ); test::( -1000000000000000000000000, -1234567890987, 810000006724, 704498996588, ); test::( -253640751230376270397812803167, -2669936877441, 94998781946290114, 1149635115107, ); test::( -3768477692975601, -11447376614057827956, 1, 11443608136364852355, ); test::(-3356605361737854, -3081095617839357, 2, 2805585873940860); test::( -1098730198198174614195, -953382298040157850476, 2, 808034397882141086757, ); test::( -69738658860594537152875081748, -69738658860594537152875081748, 1, 0, ); test::(-1000000000000000000000000, -1000000000000000000000000, 1, 0); test::(0, -1000000000000000000000000, 0, 0); test::( -123, -1000000000000000000000000, 1, 999999999999999999999877, ); } fn ceiling_div_mod_fail_helper() { assert_panic!(T::ONE.ceiling_div_mod(T::ZERO)); assert_panic!({ let mut n = T::ONE; n.ceiling_div_assign_mod(T::ZERO); }); assert_panic!(T::MIN.ceiling_div_mod(T::NEGATIVE_ONE)); assert_panic!({ let mut n = T::MIN; n.ceiling_div_assign_mod(T::NEGATIVE_ONE); }); } #[test] pub fn ceiling_div_mod_fail() { apply_fn_to_signeds!(ceiling_div_mod_fail_helper); } fn ceiling_div_mod_properties_helper() { signed_pair_gen_var_4::().test_properties(|(x, y)| { let mut mut_x = x; let r = mut_x.ceiling_div_assign_mod(y); let q = mut_x; assert_eq!(x.ceiling_div_mod(y), (q, r)); let (q_alt, r_alt) = (x.div_round(y, Ceiling).0, x.ceiling_mod(y)); assert_eq!(q_alt, q); assert_eq!(r_alt, r); assert!(r.lt_abs(&y)); assert!(r == T::ZERO || (r > T::ZERO) != (y > T::ZERO)); if let Some(product) = q.checked_mul(y) { assert_eq!(product + r, x); } else if q > T::ZERO { assert_eq!((q - T::ONE) * y + r + y, x); } else { assert_eq!((q + T::ONE) * y + r - y, x); } if x != T::MIN { let (neg_q, neg_r) = (-x).ceiling_div_mod(y); assert_eq!(x.div_mod(y), (-neg_q, -neg_r)); } if y != T::MIN && (x != T::MIN || y != T::ONE) { let (neg_q, r) = x.ceiling_div_mod(-y); assert_eq!(x.div_mod(y), (-neg_q, r)); } }); signed_gen::().test_properties(|x| { let (q, r) = x.ceiling_div_mod(T::ONE); assert_eq!(q, x); assert_eq!(r, T::ZERO); if x != T::MIN { let (q, r) = x.ceiling_div_mod(T::NEGATIVE_ONE); assert_eq!(q, -x); assert_eq!(r, T::ZERO); } assert_panic!(x.ceiling_div_mod(T::ZERO)); assert_panic!({ let mut y = x; y.ceiling_div_assign_mod(T::ZERO) }); }); signed_gen_var_6::().test_properties(|x| { assert_eq!(x.ceiling_div_mod(T::ONE), (x, T::ZERO)); if x != T::MIN { assert_eq!(x.ceiling_div_mod(T::NEGATIVE_ONE), (-x, T::ZERO)); } assert_eq!(x.ceiling_div_mod(x), (T::ONE, T::ZERO)); if x != T::MIN { assert_eq!(x.ceiling_div_mod(-x), (T::NEGATIVE_ONE, T::ZERO)); } assert_eq!(T::ZERO.ceiling_div_mod(x), (T::ZERO, T::ZERO)); }); } #[test] fn ceiling_div_mod_properties() { apply_fn_to_signeds!(ceiling_div_mod_properties_helper); }