use malachite_base::num::arithmetic::traits::{
CeilingDivAssignMod, CeilingDivMod, CeilingDivNegMod, CeilingMod, DivAssignMod, DivAssignRem,
DivMod, DivRem, DivRound, Mod,
};
use malachite_base::num::basic::integers::PrimitiveInt;
use malachite_base::num::basic::traits::{NegativeOne, One, Zero};
use malachite_base::num::comparison::traits::PartialOrdAbs;
use malachite_base::rounding_modes::RoundingMode::*;
use malachite_base::test_util::generators::common::GenConfig;
use malachite_base::test_util::generators::signed_pair_gen_var_4;
use malachite_nz::integer::Integer;
use malachite_nz::platform::{Limb, SignedLimb};
use malachite_nz::test_util::generators::{
integer_gen, integer_gen_var_8, integer_pair_gen_var_1, integer_pair_gen_var_2,
natural_pair_gen_var_5,
};
use num::{BigInt, Integer as NumInteger};
use std::str::FromStr;
#[test]
fn test_div_mod() {
let test = |s, t, quotient, remainder| {
let u = Integer::from_str(s).unwrap();
let v = Integer::from_str(t).unwrap();
let mut x = u.clone();
let r = x.div_assign_mod(v.clone());
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
assert!(x.is_valid());
assert_eq!(x.to_string(), quotient);
let mut x = u.clone();
let r = x.div_assign_mod(&v);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
assert!(x.is_valid());
assert_eq!(x.to_string(), quotient);
let (q, r) = u.clone().div_mod(v.clone());
assert!(q.is_valid());
assert_eq!(q.to_string(), quotient);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
let (q, r) = u.clone().div_mod(&v);
assert!(q.is_valid());
assert_eq!(q.to_string(), quotient);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
let (q, r) = (&u).div_mod(v.clone());
assert!(q.is_valid());
assert_eq!(q.to_string(), quotient);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
let (q, r) = (&u).div_mod(&v);
assert!(q.is_valid());
assert_eq!(q.to_string(), quotient);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
let (q, r) = BigInt::from_str(s)
.unwrap()
.div_mod_floor(&BigInt::from_str(t).unwrap());
assert_eq!(q.to_string(), quotient);
assert_eq!(r.to_string(), remainder);
let (q, r) = rug::Integer::from_str(s)
.unwrap()
.div_rem_floor(rug::Integer::from_str(t).unwrap());
assert_eq!(q.to_string(), quotient);
assert_eq!(r.to_string(), remainder);
let (q, r) = ((&u).div_round(&v, Floor).0, u.mod_op(v));
assert_eq!(q.to_string(), quotient);
assert_eq!(r.to_string(), remainder);
};
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("4294967295", "1", "4294967295", "0");
test("4294967295", "4294967295", "1", "0");
test("1000000000000", "1", "1000000000000", "0");
test("1000000000000", "3", "333333333333", "1");
test("1000000000000", "123", "8130081300", "100");
test("1000000000000", "4294967295", "232", "3567587560");
test(
"1000000000000000000000000",
"1",
"1000000000000000000000000",
"0",
);
test(
"1000000000000000000000000",
"3",
"333333333333333333333333",
"1",
);
test(
"1000000000000000000000000",
"123",
"8130081300813008130081",
"37",
);
test(
"1000000000000000000000000",
"4294967295",
"232830643708079",
"3167723695",
);
test(
"1000000000000000000000000",
"1234567890987",
"810000006723",
"530068894399",
);
test(
"100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
0",
"1234567890987654321234567890987654321",
"810000006723000055638900467181273922269593923137018654",
"779655053998040854338961591319296066",
);
test(
"100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
0",
"316049380092839506236049380092839506176",
"3164062526261718967339454949926851258865601262253979",
"37816691783627670491375998320948925696",
);
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("4294967295", "-1", "-4294967295", "0");
test("4294967295", "-4294967295", "-1", "0");
test("1000000000000", "-1", "-1000000000000", "0");
test("1000000000000", "-3", "-333333333334", "-2");
test("1000000000000", "-123", "-8130081301", "-23");
test("1000000000000", "-4294967295", "-233", "-727379735");
test(
"1000000000000000000000000",
"-1",
"-1000000000000000000000000",
"0",
);
test(
"1000000000000000000000000",
"-3",
"-333333333333333333333334",
"-2",
);
test(
"1000000000000000000000000",
"-123",
"-8130081300813008130082",
"-86",
);
test(
"1000000000000000000000000",
"-4294967295",
"-232830643708080",
"-1127243600",
);
test(
"1000000000000000000000000",
"-1234567890987",
"-810000006724",
"-704498996588",
);
test(
"100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
0",
"-1234567890987654321234567890987654321",
"-810000006723000055638900467181273922269593923137018655",
"-454912836989613466895606299668358255",
);
test(
"100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
0",
"-316049380092839506236049380092839506176",
"-3164062526261718967339454949926851258865601262253980",
"-278232688309211835744673381771890580480",
);
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("-4294967295", "-1", "4294967295", "0");
test("-4294967295", "4294967295", "-1", "0");
test("-1000000000000", "1", "-1000000000000", "0");
test("-1000000000000", "3", "-333333333334", "2");
test("-1000000000000", "123", "-8130081301", "23");
test("-1000000000000", "4294967295", "-233", "727379735");
test(
"-1000000000000000000000000",
"1",
"-1000000000000000000000000",
"0",
);
test(
"-1000000000000000000000000",
"3",
"-333333333333333333333334",
"2",
);
test(
"-1000000000000000000000000",
"123",
"-8130081300813008130082",
"86",
);
test(
"-1000000000000000000000000",
"4294967295",
"-232830643708080",
"1127243600",
);
test(
"-1000000000000000000000000",
"1234567890987",
"-810000006724",
"704498996588",
);
test(
"-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
00",
"1234567890987654321234567890987654321",
"-810000006723000055638900467181273922269593923137018655",
"454912836989613466895606299668358255",
);
test(
"-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
00",
"316049380092839506236049380092839506176",
"-3164062526261718967339454949926851258865601262253980",
"278232688309211835744673381771890580480",
);
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("-4294967295", "-1", "4294967295", "0");
test("-4294967295", "-4294967295", "1", "0");
test("-1000000000000", "-1", "1000000000000", "0");
test("-1000000000000", "-3", "333333333333", "-1");
test("-1000000000000", "-123", "8130081300", "-100");
test("-1000000000000", "-4294967295", "232", "-3567587560");
test(
"-1000000000000000000000000",
"-1",
"1000000000000000000000000",
"0",
);
test(
"-1000000000000000000000000",
"-3",
"333333333333333333333333",
"-1",
);
test(
"-1000000000000000000000000",
"-123",
"8130081300813008130081",
"-37",
);
test(
"-1000000000000000000000000",
"-4294967295",
"232830643708079",
"-3167723695",
);
test(
"-1000000000000000000000000",
"-1234567890987",
"810000006723",
"-530068894399",
);
test(
"-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
00",
"-1234567890987654321234567890987654321",
"810000006723000055638900467181273922269593923137018654",
"-779655053998040854338961591319296066",
);
test(
"-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
00",
"-316049380092839506236049380092839506176",
"3164062526261718967339454949926851258865601262253979",
"-37816691783627670491375998320948925696",
);
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]
#[should_panic]
fn div_assign_mod_fail() {
Integer::from(10).div_assign_mod(Integer::ZERO);
}
#[test]
#[should_panic]
fn div_assign_mod_ref_fail() {
Integer::from(10).div_assign_mod(&Integer::ZERO);
}
#[test]
#[should_panic]
fn div_mod_fail() {
Integer::from(10).div_mod(Integer::ZERO);
}
#[test]
#[should_panic]
fn div_mod_val_ref_fail() {
Integer::from(10).div_mod(&Integer::ZERO);
}
#[test]
#[should_panic]
fn div_mod_ref_val_fail() {
(&Integer::from(10)).div_mod(Integer::ZERO);
}
#[test]
#[should_panic]
fn div_mod_ref_ref_fail() {
(&Integer::from(10)).div_mod(&Integer::ZERO);
}
#[test]
fn test_div_rem() {
let test = |s, t, quotient, remainder| {
let u = Integer::from_str(s).unwrap();
let v = Integer::from_str(t).unwrap();
let mut x = u.clone();
let r = x.div_assign_rem(v.clone());
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
assert!(x.is_valid());
assert_eq!(x.to_string(), quotient);
let mut x = u.clone();
let r = x.div_assign_rem(&v);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
assert!(x.is_valid());
assert_eq!(x.to_string(), quotient);
let (q, r) = u.clone().div_rem(v.clone());
assert!(q.is_valid());
assert_eq!(q.to_string(), quotient);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
let (q, r) = u.clone().div_rem(&v);
assert!(q.is_valid());
assert_eq!(q.to_string(), quotient);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
let (q, r) = (&u).div_rem(v.clone());
assert!(q.is_valid());
assert_eq!(q.to_string(), quotient);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
let (q, r) = (&u).div_rem(&v);
assert!(q.is_valid());
assert_eq!(q.to_string(), quotient);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
let (q, r) = BigInt::from_str(s)
.unwrap()
.div_rem(&BigInt::from_str(t).unwrap());
assert_eq!(q.to_string(), quotient);
assert_eq!(r.to_string(), remainder);
let (q, r) = rug::Integer::from_str(s)
.unwrap()
.div_rem(rug::Integer::from_str(t).unwrap());
assert_eq!(q.to_string(), quotient);
assert_eq!(r.to_string(), remainder);
let (q, r) = (u.clone() / v.clone(), u % v);
assert_eq!(q.to_string(), quotient);
assert_eq!(r.to_string(), remainder);
};
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("4294967295", "1", "4294967295", "0");
test("4294967295", "4294967295", "1", "0");
test("1000000000000", "1", "1000000000000", "0");
test("1000000000000", "3", "333333333333", "1");
test("1000000000000", "123", "8130081300", "100");
test("1000000000000", "4294967295", "232", "3567587560");
test(
"1000000000000000000000000",
"1",
"1000000000000000000000000",
"0",
);
test(
"1000000000000000000000000",
"3",
"333333333333333333333333",
"1",
);
test(
"1000000000000000000000000",
"123",
"8130081300813008130081",
"37",
);
test(
"1000000000000000000000000",
"4294967295",
"232830643708079",
"3167723695",
);
test(
"1000000000000000000000000",
"1234567890987",
"810000006723",
"530068894399",
);
test(
"100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
0",
"1234567890987654321234567890987654321",
"810000006723000055638900467181273922269593923137018654",
"779655053998040854338961591319296066",
);
test(
"100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
0",
"316049380092839506236049380092839506176",
"3164062526261718967339454949926851258865601262253979",
"37816691783627670491375998320948925696",
);
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("4294967295", "-1", "-4294967295", "0");
test("4294967295", "-4294967295", "-1", "0");
test("1000000000000", "-1", "-1000000000000", "0");
test("1000000000000", "-3", "-333333333333", "1");
test("1000000000000", "-123", "-8130081300", "100");
test("1000000000000", "-4294967295", "-232", "3567587560");
test(
"1000000000000000000000000",
"-1",
"-1000000000000000000000000",
"0",
);
test(
"1000000000000000000000000",
"-3",
"-333333333333333333333333",
"1",
);
test(
"1000000000000000000000000",
"-123",
"-8130081300813008130081",
"37",
);
test(
"1000000000000000000000000",
"-4294967295",
"-232830643708079",
"3167723695",
);
test(
"1000000000000000000000000",
"-1234567890987",
"-810000006723",
"530068894399",
);
test(
"100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
0",
"-1234567890987654321234567890987654321",
"-810000006723000055638900467181273922269593923137018654",
"779655053998040854338961591319296066",
);
test(
"100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
0",
"-316049380092839506236049380092839506176",
"-3164062526261718967339454949926851258865601262253979",
"37816691783627670491375998320948925696",
);
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("-4294967295", "1", "-4294967295", "0");
test("-4294967295", "4294967295", "-1", "0");
test("-1000000000000", "1", "-1000000000000", "0");
test("-1000000000000", "3", "-333333333333", "-1");
test("-1000000000000", "123", "-8130081300", "-100");
test("-1000000000000", "4294967295", "-232", "-3567587560");
test(
"-1000000000000000000000000",
"1",
"-1000000000000000000000000",
"0",
);
test(
"-1000000000000000000000000",
"3",
"-333333333333333333333333",
"-1",
);
test(
"-1000000000000000000000000",
"123",
"-8130081300813008130081",
"-37",
);
test(
"-1000000000000000000000000",
"4294967295",
"-232830643708079",
"-3167723695",
);
test(
"-1000000000000000000000000",
"1234567890987",
"-810000006723",
"-530068894399",
);
test(
"-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
00",
"1234567890987654321234567890987654321",
"-810000006723000055638900467181273922269593923137018654",
"-779655053998040854338961591319296066",
);
test(
"-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
00",
"316049380092839506236049380092839506176",
"-3164062526261718967339454949926851258865601262253979",
"-37816691783627670491375998320948925696",
);
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("-4294967295", "-1", "4294967295", "0");
test("-4294967295", "-4294967295", "1", "0");
test("-1000000000000", "-1", "1000000000000", "0");
test("-1000000000000", "-3", "333333333333", "-1");
test("-1000000000000", "-123", "8130081300", "-100");
test("-1000000000000", "-4294967295", "232", "-3567587560");
test(
"-1000000000000000000000000",
"-1",
"1000000000000000000000000",
"0",
);
test(
"-1000000000000000000000000",
"-3",
"333333333333333333333333",
"-1",
);
test(
"-1000000000000000000000000",
"-123",
"8130081300813008130081",
"-37",
);
test(
"-1000000000000000000000000",
"-4294967295",
"232830643708079",
"-3167723695",
);
test(
"-1000000000000000000000000",
"-1234567890987",
"810000006723",
"-530068894399",
);
test(
"-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
00",
"-1234567890987654321234567890987654321",
"810000006723000055638900467181273922269593923137018654",
"-779655053998040854338961591319296066",
);
test(
"-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
00",
"-316049380092839506236049380092839506176",
"3164062526261718967339454949926851258865601262253979",
"-37816691783627670491375998320948925696",
);
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]
#[should_panic]
fn div_assign_rem_fail() {
Integer::from(10).div_assign_rem(Integer::ZERO);
}
#[test]
#[should_panic]
fn div_assign_rem_ref_fail() {
Integer::from(10).div_assign_rem(&Integer::ZERO);
}
#[test]
#[should_panic]
fn div_rem_fail() {
Integer::from(10).div_rem(Integer::ZERO);
}
#[test]
#[should_panic]
fn div_rem_val_ref_fail() {
Integer::from(10).div_rem(&Integer::ZERO);
}
#[test]
#[should_panic]
fn div_rem_ref_val_fail() {
(&Integer::from(10)).div_rem(Integer::ZERO);
}
#[test]
#[should_panic]
fn div_rem_ref_ref_fail() {
(&Integer::from(10)).div_rem(&Integer::ZERO);
}
#[test]
fn test_ceiling_div_mod() {
let test = |s, t, quotient, remainder| {
let u = Integer::from_str(s).unwrap();
let v = Integer::from_str(t).unwrap();
let mut x = u.clone();
let r = x.ceiling_div_assign_mod(v.clone());
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
assert!(x.is_valid());
assert_eq!(x.to_string(), quotient);
let mut x = u.clone();
let r = x.ceiling_div_assign_mod(&v);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
assert!(x.is_valid());
assert_eq!(x.to_string(), quotient);
let (q, r) = u.clone().ceiling_div_mod(v.clone());
assert!(q.is_valid());
assert_eq!(q.to_string(), quotient);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
let (q, r) = u.clone().ceiling_div_mod(&v);
assert!(q.is_valid());
assert_eq!(q.to_string(), quotient);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
let (q, r) = (&u).ceiling_div_mod(v.clone());
assert!(q.is_valid());
assert_eq!(q.to_string(), quotient);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
let (q, r) = (&u).ceiling_div_mod(&v);
assert!(q.is_valid());
assert_eq!(q.to_string(), quotient);
assert!(r.is_valid());
assert_eq!(r.to_string(), remainder);
let (q, r) = rug::Integer::from_str(s)
.unwrap()
.div_rem_ceil(rug::Integer::from_str(t).unwrap());
assert_eq!(q.to_string(), quotient);
assert_eq!(r.to_string(), remainder);
let (q, r) = (u.clone().div_round(v.clone(), Ceiling).0, u.ceiling_mod(v));
assert_eq!(q.to_string(), quotient);
assert_eq!(r.to_string(), remainder);
};
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("4294967295", "1", "4294967295", "0");
test("4294967295", "4294967295", "1", "0");
test("1000000000000", "1", "1000000000000", "0");
test("1000000000000", "3", "333333333334", "-2");
test("1000000000000", "123", "8130081301", "-23");
test("1000000000000", "4294967295", "233", "-727379735");
test(
"1000000000000000000000000",
"1",
"1000000000000000000000000",
"0",
);
test(
"1000000000000000000000000",
"3",
"333333333333333333333334",
"-2",
);
test(
"1000000000000000000000000",
"123",
"8130081300813008130082",
"-86",
);
test(
"1000000000000000000000000",
"4294967295",
"232830643708080",
"-1127243600",
);
test(
"1000000000000000000000000",
"1234567890987",
"810000006724",
"-704498996588",
);
test(
"10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
00",
"1234567890987654321234567890987654321",
"810000006723000055638900467181273922269593923137018655",
"-454912836989613466895606299668358255",
);
test(
"10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
00",
"316049380092839506236049380092839506176",
"3164062526261718967339454949926851258865601262253980",
"-278232688309211835744673381771890580480",
);
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("4294967295", "-1", "-4294967295", "0");
test("4294967295", "-4294967295", "-1", "0");
test("1000000000000", "-1", "-1000000000000", "0");
test("1000000000000", "-3", "-333333333333", "1");
test("1000000000000", "-123", "-8130081300", "100");
test("1000000000000", "-4294967295", "-232", "3567587560");
test(
"1000000000000000000000000",
"-1",
"-1000000000000000000000000",
"0",
);
test(
"1000000000000000000000000",
"-3",
"-333333333333333333333333",
"1",
);
test(
"1000000000000000000000000",
"-123",
"-8130081300813008130081",
"37",
);
test(
"1000000000000000000000000",
"-4294967295",
"-232830643708079",
"3167723695",
);
test(
"1000000000000000000000000",
"-1234567890987",
"-810000006723",
"530068894399",
);
test(
"100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
0",
"-1234567890987654321234567890987654321",
"-810000006723000055638900467181273922269593923137018654",
"779655053998040854338961591319296066",
);
test(
"100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
0",
"-316049380092839506236049380092839506176",
"-3164062526261718967339454949926851258865601262253979",
"37816691783627670491375998320948925696",
);
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("-4294967295", "1", "-4294967295", "0");
test("-4294967295", "4294967295", "-1", "0");
test("-1000000000000", "1", "-1000000000000", "0");
test("-1000000000000", "3", "-333333333333", "-1");
test("-1000000000000", "123", "-8130081300", "-100");
test("-1000000000000", "4294967295", "-232", "-3567587560");
test(
"-1000000000000000000000000",
"1",
"-1000000000000000000000000",
"0",
);
test(
"-1000000000000000000000000",
"3",
"-333333333333333333333333",
"-1",
);
test(
"-1000000000000000000000000",
"123",
"-8130081300813008130081",
"-37",
);
test(
"-1000000000000000000000000",
"4294967295",
"-232830643708079",
"-3167723695",
);
test(
"-1000000000000000000000000",
"1234567890987",
"-810000006723",
"-530068894399",
);
test(
"-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
00",
"1234567890987654321234567890987654321",
"-810000006723000055638900467181273922269593923137018654",
"-779655053998040854338961591319296066",
);
test(
"-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
00",
"316049380092839506236049380092839506176",
"-3164062526261718967339454949926851258865601262253979",
"-37816691783627670491375998320948925696",
);
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("-4294967295", "-1", "4294967295", "0");
test("-4294967295", "-4294967295", "1", "0");
test("-1000000000000", "-1", "1000000000000", "0");
test("-1000000000000", "-3", "333333333334", "2");
test("-1000000000000", "-123", "8130081301", "23");
test("-1000000000000", "-4294967295", "233", "727379735");
test(
"-1000000000000000000000000",
"-1",
"1000000000000000000000000",
"0",
);
test(
"-1000000000000000000000000",
"-3",
"333333333333333333333334",
"2",
);
test(
"-1000000000000000000000000",
"-123",
"8130081300813008130082",
"86",
);
test(
"-1000000000000000000000000",
"-4294967295",
"232830643708080",
"1127243600",
);
test(
"-1000000000000000000000000",
"-1234567890987",
"810000006724",
"704498996588",
);
test(
"-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
00",
"-1234567890987654321234567890987654321",
"810000006723000055638900467181273922269593923137018655",
"454912836989613466895606299668358255",
);
test(
"-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
00",
"-316049380092839506236049380092839506176",
"3164062526261718967339454949926851258865601262253980",
"278232688309211835744673381771890580480",
);
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]
#[should_panic]
fn ceiling_div_assign_mod_fail() {
Integer::from(10).ceiling_div_assign_mod(Integer::ZERO);
}
#[test]
#[should_panic]
fn ceiling_div_assign_mod_ref_fail() {
Integer::from(10).ceiling_div_assign_mod(&Integer::ZERO);
}
#[test]
#[should_panic]
fn ceiling_div_mod_fail() {
Integer::from(10).ceiling_div_mod(Integer::ZERO);
}
#[test]
#[should_panic]
fn ceiling_div_mod_val_ref_fail() {
Integer::from(10).ceiling_div_mod(&Integer::ZERO);
}
#[test]
#[should_panic]
fn ceiling_div_mod_ref_val_fail() {
(&Integer::from(10)).ceiling_div_mod(Integer::ZERO);
}
#[test]
#[should_panic]
fn ceiling_div_mod_ref_ref_fail() {
(&Integer::from(10)).ceiling_div_mod(&Integer::ZERO);
}
fn div_mod_properties_helper(x: Integer, y: Integer) {
let mut mut_x = x.clone();
let r = mut_x.div_assign_mod(&y);
assert!(mut_x.is_valid());
assert!(r.is_valid());
let q = mut_x;
let mut mut_x = x.clone();
let r_alt = mut_x.div_assign_mod(y.clone());
let q_alt = mut_x;
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, r);
let (q_alt, r_alt) = (&x).div_mod(&y);
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, r);
let (q_alt, r_alt) = (&x).div_mod(y.clone());
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, r);
let (q_alt, r_alt) = x.clone().div_mod(&y);
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, r);
let (q_alt, r_alt) = x.clone().div_mod(y.clone());
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, 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);
let (num_q, num_r) = BigInt::from(&x).div_mod_floor(&BigInt::from(&y));
assert_eq!(Integer::from(&num_q), q);
assert_eq!(Integer::from(&num_r), r);
let (rug_q, rug_r) = rug::Integer::from(&x).div_rem_floor(rug::Integer::from(&y));
assert_eq!(Integer::from(&rug_q), q);
assert_eq!(Integer::from(&rug_r), r);
assert!(r.lt_abs(&y));
assert!(r == 0 || (r > 0) == (y > 0));
assert_eq!(q * &y + r, x);
let (neg_q, neg_r) = (-&x).div_mod(&y);
assert_eq!((&x).ceiling_div_mod(&y), (-neg_q, -neg_r));
let (neg_q, r) = (&x).div_mod(-&y);
assert_eq!(x.ceiling_div_mod(y), (-neg_q, r));
}
#[test]
fn div_mod_properties() {
let mut config = GenConfig::new();
config.insert("mean_bits_n", 2048);
config.insert("mean_stripe_n", 16 << Limb::LOG_WIDTH);
integer_pair_gen_var_1()
.test_properties_with_config(&config, |(x, y)| div_mod_properties_helper(x, y));
integer_pair_gen_var_2()
.test_properties_with_config(&config, |(x, y)| div_mod_properties_helper(x, y));
integer_gen().test_properties(|x| {
let (q, r) = (&x).div_mod(Integer::ONE);
assert_eq!(q, x);
assert_eq!(r, 0);
let (q, r) = (&x).div_mod(Integer::NEGATIVE_ONE);
assert_eq!(q, -x);
assert_eq!(r, 0);
});
integer_gen_var_8().test_properties(|ref x| {
assert_eq!(x.div_mod(Integer::ONE), (x.clone(), Integer::ZERO));
assert_eq!(x.div_mod(Integer::NEGATIVE_ONE), (-x, Integer::ZERO));
assert_eq!(x.div_mod(x), (Integer::ONE, Integer::ZERO));
assert_eq!(x.div_mod(-x), (Integer::NEGATIVE_ONE, Integer::ZERO));
assert_eq!(Integer::ZERO.div_mod(x), (Integer::ZERO, Integer::ZERO));
if *x > 1 {
assert_eq!(Integer::ONE.div_mod(x), (Integer::ZERO, Integer::ONE));
assert_eq!(
Integer::NEGATIVE_ONE.div_mod(x),
(Integer::NEGATIVE_ONE, x - Integer::ONE)
);
}
});
natural_pair_gen_var_5().test_properties(|(x, y)| {
let (q, r) = (&x).div_mod(&y);
assert_eq!(
Integer::from(x).div_mod(Integer::from(y)),
(Integer::from(q), Integer::from(r))
);
});
signed_pair_gen_var_4::<SignedLimb>().test_properties(|(x, y)| {
let (q, r) = x.div_mod(y);
assert_eq!(
Integer::from(x).div_mod(Integer::from(y)),
(Integer::from(q), Integer::from(r))
);
});
}
fn div_rem_properties_helper(x: Integer, y: Integer) {
let mut mut_x = x.clone();
let r = mut_x.div_assign_rem(&y);
assert!(mut_x.is_valid());
assert!(r.is_valid());
let q = mut_x;
let mut q_alt = x.clone();
let r_alt = q_alt.div_assign_rem(y.clone());
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, r);
let (q_alt, r_alt) = (&x).div_rem(&y);
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, r);
let (q_alt, r_alt) = (&x).div_rem(y.clone());
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, r);
let (q_alt, r_alt) = x.clone().div_rem(&y);
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, r);
let (q_alt, r_alt) = x.clone().div_rem(y.clone());
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, r);
let (q_alt, r_alt) = (&x / &y, &x % &y);
assert_eq!(q_alt, q);
assert_eq!(r_alt, r);
let (num_q, num_r) = BigInt::from(&x).div_rem(&BigInt::from(&y));
assert_eq!(Integer::from(&num_q), q);
assert_eq!(Integer::from(&num_r), r);
let (rug_q, rug_r) = rug::Integer::from(&x).div_rem(rug::Integer::from(&y));
assert_eq!(Integer::from(&rug_q), q);
assert_eq!(Integer::from(&rug_r), r);
assert!(r.lt_abs(&y));
assert!(r == 0 || (r > 0) == (x > 0));
assert_eq!(&q * &y + &r, x);
assert_eq!((-&x).div_rem(&y), (-&q, -&r));
assert_eq!(x.div_rem(-y), (-q, r));
}
#[test]
fn div_rem_properties() {
let mut config = GenConfig::new();
config.insert("mean_bits_n", 2048);
config.insert("mean_stripe_n", 16 << Limb::LOG_WIDTH);
integer_pair_gen_var_1()
.test_properties_with_config(&config, |(x, y)| div_rem_properties_helper(x, y));
integer_pair_gen_var_2()
.test_properties_with_config(&config, |(x, y)| div_rem_properties_helper(x, y));
integer_gen().test_properties(|x| {
let (q, r) = (&x).div_rem(Integer::ONE);
assert_eq!(q, x);
assert_eq!(r, 0);
let (q, r) = (&x).div_rem(Integer::NEGATIVE_ONE);
assert_eq!(q, -x);
assert_eq!(r, 0);
});
integer_gen_var_8().test_properties(|ref x| {
assert_eq!(x.div_rem(Integer::ONE), (x.clone(), Integer::ZERO));
assert_eq!(x.div_rem(Integer::NEGATIVE_ONE), (-x, Integer::ZERO));
assert_eq!(x.div_rem(x), (Integer::ONE, Integer::ZERO));
assert_eq!(x.div_rem(-x), (Integer::NEGATIVE_ONE, Integer::ZERO));
assert_eq!(Integer::ZERO.div_rem(x), (Integer::ZERO, Integer::ZERO));
if *x > 1 {
assert_eq!(Integer::ONE.div_rem(x), (Integer::ZERO, Integer::ONE));
assert_eq!(
Integer::NEGATIVE_ONE.div_rem(x),
(Integer::ZERO, Integer::NEGATIVE_ONE)
);
}
});
natural_pair_gen_var_5().test_properties(|(x, y)| {
let (q, r) = (&x).div_rem(&y);
assert_eq!(
Integer::from(x).div_rem(Integer::from(y)),
(Integer::from(q), Integer::from(r))
);
});
signed_pair_gen_var_4::<SignedLimb>().test_properties(|(x, y)| {
let (q, r) = x.div_rem(y);
assert_eq!(
Integer::from(x).div_rem(Integer::from(y)),
(Integer::from(q), Integer::from(r))
);
});
}
fn ceiling_div_mod_properties_helper(x: Integer, y: Integer) {
let mut mut_x = x.clone();
let r = mut_x.ceiling_div_assign_mod(&y);
assert!(mut_x.is_valid());
assert!(r.is_valid());
let q = mut_x;
let mut mut_x = x.clone();
let r_alt = mut_x.ceiling_div_assign_mod(y.clone());
let q_alt = mut_x;
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, r);
let (q_alt, r_alt) = (&x).ceiling_div_mod(&y);
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, r);
let (q_alt, r_alt) = (&x).ceiling_div_mod(y.clone());
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, r);
let (q_alt, r_alt) = x.clone().ceiling_div_mod(&y);
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, r);
let (q_alt, r_alt) = x.clone().ceiling_div_mod(y.clone());
assert!(q_alt.is_valid());
assert_eq!(q_alt, q);
assert!(r_alt.is_valid());
assert_eq!(r_alt, 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);
let (rug_q, rug_r) = rug::Integer::from(&x).div_rem_ceil(rug::Integer::from(&y));
assert_eq!(Integer::from(&rug_q), q);
assert_eq!(Integer::from(&rug_r), r);
assert!(r.lt_abs(&y));
assert!(r == 0 || (r > 0) != (y > 0));
assert_eq!(q * &y + r, x);
let (neg_q, neg_r) = (-&x).ceiling_div_mod(&y);
assert_eq!((&x).div_mod(&y), (-neg_q, -neg_r));
let (neg_q, r) = (&x).ceiling_div_mod(-&y);
assert_eq!(x.div_mod(y), (-neg_q, r));
}
#[test]
fn ceiling_div_mod_properties() {
let mut config = GenConfig::new();
config.insert("mean_bits_n", 2048);
config.insert("mean_stripe_n", 16 << Limb::LOG_WIDTH);
integer_pair_gen_var_1()
.test_properties_with_config(&config, |(x, y)| ceiling_div_mod_properties_helper(x, y));
integer_pair_gen_var_2()
.test_properties_with_config(&config, |(x, y)| ceiling_div_mod_properties_helper(x, y));
integer_gen().test_properties(|x| {
let (q, r) = (&x).ceiling_div_mod(Integer::ONE);
assert_eq!(q, x);
assert_eq!(r, 0);
let (q, r) = (&x).ceiling_div_mod(Integer::NEGATIVE_ONE);
assert_eq!(q, -x);
assert_eq!(r, 0);
});
integer_gen_var_8().test_properties(|ref x| {
assert_eq!(x.ceiling_div_mod(Integer::ONE), (x.clone(), Integer::ZERO));
assert_eq!(
x.ceiling_div_mod(Integer::NEGATIVE_ONE),
(-x, Integer::ZERO)
);
assert_eq!(x.ceiling_div_mod(x), (Integer::ONE, Integer::ZERO));
assert_eq!(
x.ceiling_div_mod(-x),
(Integer::NEGATIVE_ONE, Integer::ZERO)
);
assert_eq!(
Integer::ZERO.ceiling_div_mod(x),
(Integer::ZERO, Integer::ZERO)
);
});
natural_pair_gen_var_5().test_properties(|(x, y)| {
let (q, r) = (&x).ceiling_div_neg_mod(&y);
assert_eq!(
Integer::from(x).ceiling_div_mod(Integer::from(y)),
(Integer::from(q), -r)
);
});
signed_pair_gen_var_4::<SignedLimb>().test_properties(|(x, y)| {
let (q, r) = x.ceiling_div_mod(y);
assert_eq!(
Integer::from(x).ceiling_div_mod(Integer::from(y)),
(Integer::from(q), Integer::from(r))
);
});
}