use malachite_base::num::arithmetic::traits::IsPowerOf2;
use malachite_base::num::basic::traits::Sqrt3;
use malachite_base::rounding_modes::RoundingMode::{self, *};
use malachite_base::test_util::generators::{
unsigned_gen_var_11, unsigned_rounding_mode_pair_gen_var_4,
};
use malachite_float::test_util::common::{
rug_round_try_from_rounding_mode, test_constant, to_hex_string,
};
use malachite_float::test_util::constants::sqrt_3::rug_sqrt_3_prec_round;
use malachite_float::{ComparableFloat, ComparableFloatRef, Float};
use std::cmp::Ordering::{self, *};
use std::panic::catch_unwind;
fn test_sqrt_3_prec_helper(prec: u64, out: &str, out_hex: &str, out_o: Ordering) {
let (x, o) = Float::sqrt_3_prec(prec);
assert!(x.is_valid());
assert_eq!(x.to_string(), out);
assert_eq!(to_hex_string(&x), out_hex);
assert_eq!(o, out_o);
let (rug_x, rug_o) =
rug_sqrt_3_prec_round(prec, rug_round_try_from_rounding_mode(Nearest).unwrap());
assert_eq!(
ComparableFloatRef(&Float::from(&rug_x)),
ComparableFloatRef(&x)
);
assert_eq!(rug_o, o);
}
#[test]
pub fn test_sqrt_3_prec() {
test_sqrt_3_prec_helper(1, "2.0", "0x2.0#1", Greater);
test_sqrt_3_prec_helper(2, "1.5", "0x1.8#2", Less);
test_sqrt_3_prec_helper(3, "1.8", "0x1.c#3", Greater);
test_sqrt_3_prec_helper(4, "1.8", "0x1.c#4", Greater);
test_sqrt_3_prec_helper(5, "1.75", "0x1.c#5", Greater);
test_sqrt_3_prec_helper(6, "1.72", "0x1.b8#6", Less);
test_sqrt_3_prec_helper(7, "1.73", "0x1.bc#7", Greater);
test_sqrt_3_prec_helper(8, "1.734", "0x1.bc#8", Greater);
test_sqrt_3_prec_helper(9, "1.73", "0x1.bb#9", Less);
test_sqrt_3_prec_helper(10, "1.732", "0x1.bb8#10", Greater);
test_sqrt_3_prec_helper(
100,
"1.732050807568877293527446341506",
"0x1.bb67ae8584caa73b25742d708#100",
Greater,
);
test_sqrt_3_prec_helper(
1000,
"1.732050807568877293527446341505872366942805253810380628055806979451933016908800037081146\
186757248575675626141415406703029969945094998952478811655512094373648528093231902305582067\
974820101084674923265015312343266903322886650672254668921837971227047131660367861588019049\
9865373798593894676503475065760508",
"0x1.bb67ae8584caa73b25742d7078b83b8925d834cc53da4798c720a6486e45a6e2490bcfd95ef15dbda9930\
aae12228f87cc4cf24da3a1ec68d0cd33a01ad9a383b9e122e6138c3ae6de5ede3bd42db7301b6bf553af7b09f\
d6ebef33a9a9fe57729426f30e5892ab572816ccefc5899355f7f11c3e24f3768a5c7cb90d6#1000",
Greater,
);
test_sqrt_3_prec_helper(
10000,
"1.732050807568877293527446341505872366942805253810380628055806979451933016908800037081146\
186757248575675626141415406703029969945094998952478811655512094373648528093231902305582067\
974820101084674923265015312343266903322886650672254668921837971227047131660367861588019049\
986537379859389467650347506576050756618348129606100947602187190325083145829523959832997789\
824508288714463832917347224163984587855397667958063818353666110843173780894378316102088305\
524901670023520711144288695990956365797087168498072899493296484283020786408603988738697537\
582317317831395992983007838702877053913369563312103707264019249106768231199288375641141422\
016742752102372994270831059898459475987664288897796147837958390228854852903576033852808064\
381972344661059689722872865264153822664698420021195484155278441181286534507035191650016689\
294415480846071277143999762926834629577438361895110127148638746976545982451788550975379013\
880664961911962222957110555242923723192197738262561631468842032853716682938649611917049738\
836395495938145757671853373633125910899655424624834787197605235997769192323570220305302840\
385915414971072429559206706202509520175963185872766359975283663431080150665853710647328538\
625922260582220510403680270297504798728079461658100417052681940019095733462175943893670249\
320422691034369812463720111185261084268910299720311202100063507176374582405203847555197279\
933797614906107894985544223326004018851303631561144886847281589288163245187265066645384877\
599162576642872111240842068016763517100102943180715515190961642460907039408129216903517492\
961364004139670431041253632327030922577327960292376597745537095469115742140424230781992327\
617401906424512454877516862696105333694216213605394604245654140128533007813633449856736406\
703977342229811961042925534501601405940479547154534548407271737656262366549166640233006013\
265744070107836858468452313160467754480500402240639911970362218602920238867150711017169400\
296868759663500040895316214233425227956834067013470185902028360716762147743493449563595808\
082130442586469468522610908263353008756612603460672195404055984128912975994810000772057440\
230047673258800091514371489475444879157191294659083570873961515537797640262068370848046072\
969382719585689759759626104159152657577790782334980567840022901532052138935373775536566427\
046826874289963441395743666073744445583086477893212985302148197395341478170516614952551763\
291993699565744522639112519093541386989366817430938226424736926202072990967831154131946484\
377915459915923928287714695149274026409213645654041644581490201945749419305269002613972646\
081065071439603206077510594187798284793986195249964165213139715293599421897416647075187235\
788629466108560170428869605798394052906407430811833388677881562635867156008396760245349229\
943938867059754315442943430957258470988215463111260766774067864571578060647447499750354544\
559313286549189849336572747626297414738235686914837831363361283627903824840163806671607179\
848728555842931349226093240565957553651136754644387834283313466644554180390821898983294626\
3450161711220169296194601693206210330397449",
"0x1.bb67ae8584caa73b25742d7078b83b8925d834cc53da4798c720a6486e45a6e2490bcfd95ef15dbda9930\
aae12228f87cc4cf24da3a1ec68d0cd33a01ad9a383b9e122e6138c3ae6de5ede3bd42db7301b6bf553af7b09f\
d6ebef33a9a9fe57729426f30e5892ab572816ccefc5899355f7f11c3e24f3768a5c7cb90d55302505df014c70\
adb1ec1baf58f084433c0d56696a039d962d8434194aab164d642f76e2c8f7dbed64b39dad2f9f7726c6930c49\
d48ffcdc21114a6c36b2ab7018af65c10f806a8fcf4188ef377d2d5b5fd1942e6fd41f9d23b667813df420b68d\
313b387ae00d7a1ddd40aa69bb5352d3522529a7269af1ace62c8325ced0d18c24635d661cfb468be1b096fe67\
7a78756ff46b5506d202bbab5e3351351776080e751e7a6ed2ecbd5cab0343f677bc2f4d3020b12c5a3dd54170\
514f1d910c64a786d9f4fdde306dfce0de8466b0c0b1097801348a9497aca75bdd1b2cb8a042330fb4a53f02fb\
e02b0bd65b382e53877c9b3b518f837f09b9ea3eada4de774744c667ee778a7de2100ef3847573d88bf593779a\
f61a446d5cf76c39e9b5e3a8e82eadb3bab8bbed573c82332c9b692ad88926393687c4cfd268bf8c11f4f39490\
3816010414c231d5ab4e954cca351a0b97b9c1dfc9c263bc18fe1b0899efae7dc41d63fa0d29a5e5d541f52617\
ab4671cded759436e30da234491b192dc6d190fe6b15e72e0a142ca532c3971e0e57a50d517325b52415ccf1e4\
feb9efba3bf091f9c3ffb3a9b243bb001a5fa8c9c9272115c5b9f6cf09325ecc659bb47a3b2dbf660c7bfd4046\
81a5c00c10bc4c7978e5255fc1aa1230c7768f631ccba5fe87314527436fc1e1851ffcf0709060141b5e7c80d2\
f80c57e3f4f1242645dc47a2e85bcbe4b8d7a8185e7000f7655499a681467d71000bd05244d47947991e01d822\
3c817c45780617c2a1fed7f14f334615af5cd378b298c36afe497ed4e6d74b8f87312cc7d9c03b1b260ae50eae\
83b121f59686686a44115094562752ce8e7eef2baf5383aaf67c4b9cc3e12d6edf2424fab1e11fdea7d433bca4\
4d5022ed471d20ae60d74b953c30bbc0a8ca668f86c230ff4b42e14ee60fa2752e462642cebb5c383da047309e\
fec6fff1c9ab3b796ef8d1b446f6b7b87453acf3c77dcdab7d5eb310fb8b07a014e9c03e0f1e0fcdd841bc45e2\
186afe58e091e66d9d713952fbf2cef88598adf4ce26f02044d52ef69dca5124d91adc008a9375da7ec5b47953\
0ff2146c81ab095fe0a995a418ed5eef9ab0b044f06369d3e37b1b97baf10ee167701aa2bdcde28e3b3ab1924e\
9f93affd5e402c83fbc35c9c1ebe0b497b1eb1fb1333d19373e5b7327b1da58ef99c201deee108a885f9d569d3\
7843e775a3b7a6ebe41c3b08f740482934519c3d82cabd6bc17498ad9d484526b2af59e948b13fc009a7ae97d7\
ed1dd29de6c5cbeff0deb3f702f4b105873857f2fa74515cca70f8453dafb5bd7104a15ad9259826c47c17ac69\
a50cb6280457aa7ae6a4dcf359618816b665a5949609815ffb3b9a5ca3db6941ab0faba197ed8870640a0714bc\
c395db140d3ab37df75a5c13af7fe4d8b784d8594a59a664cb01ecb6910be6712b1f42d802886f52cd61fc24a8\
13d04b79a53bf7bd7c5a328606a507d61c98e40551ed0923be10c7927cfc334b9a72486dfcdf217395cf771132\
201a0c1814249a0edd7771933fa5a194818792f12eb0aed7c164b6a95c3786ff646361d752e#10000",
Greater,
);
let sqrt_3_f32 = Float::sqrt_3_prec(u64::from(f32::MANTISSA_DIGITS)).0;
assert_eq!(sqrt_3_f32.to_string(), "1.7320508");
assert_eq!(to_hex_string(&sqrt_3_f32), "0x1.bb67ae#24");
assert_eq!(sqrt_3_f32, f32::SQRT_3);
let sqrt_3_f64 = Float::sqrt_3_prec(u64::from(f64::MANTISSA_DIGITS)).0;
assert_eq!(sqrt_3_f64.to_string(), "1.7320508075688772");
assert_eq!(to_hex_string(&sqrt_3_f64), "0x1.bb67ae8584caa#53");
assert_eq!(sqrt_3_f64, f64::SQRT_3);
}
#[test]
#[should_panic]
fn sqrt_3_prec_fail_1() {
Float::sqrt_3_prec(0);
}
fn test_sqrt_3_prec_round_helper(
prec: u64,
rm: RoundingMode,
out: &str,
out_hex: &str,
out_o: Ordering,
) {
let (x, o) = Float::sqrt_3_prec_round(prec, rm);
assert!(x.is_valid());
assert_eq!(x.to_string(), out);
assert_eq!(to_hex_string(&x), out_hex);
assert_eq!(o, out_o);
if let Ok(rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_x, rug_o) = rug_sqrt_3_prec_round(prec, rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_x)),
ComparableFloatRef(&x)
);
assert_eq!(rug_o, o);
}
}
#[test]
pub fn test_sqrt_3_prec_round() {
test_sqrt_3_prec_round_helper(1, Floor, "1.0", "0x1.0#1", Less);
test_sqrt_3_prec_round_helper(1, Ceiling, "2.0", "0x2.0#1", Greater);
test_sqrt_3_prec_round_helper(1, Down, "1.0", "0x1.0#1", Less);
test_sqrt_3_prec_round_helper(1, Up, "2.0", "0x2.0#1", Greater);
test_sqrt_3_prec_round_helper(1, Nearest, "2.0", "0x2.0#1", Greater);
test_sqrt_3_prec_round_helper(2, Floor, "1.5", "0x1.8#2", Less);
test_sqrt_3_prec_round_helper(2, Ceiling, "2.0", "0x2.0#2", Greater);
test_sqrt_3_prec_round_helper(2, Down, "1.5", "0x1.8#2", Less);
test_sqrt_3_prec_round_helper(2, Up, "2.0", "0x2.0#2", Greater);
test_sqrt_3_prec_round_helper(2, Nearest, "1.5", "0x1.8#2", Less);
test_sqrt_3_prec_round_helper(3, Floor, "1.5", "0x1.8#3", Less);
test_sqrt_3_prec_round_helper(3, Ceiling, "1.8", "0x1.c#3", Greater);
test_sqrt_3_prec_round_helper(3, Down, "1.5", "0x1.8#3", Less);
test_sqrt_3_prec_round_helper(3, Up, "1.8", "0x1.c#3", Greater);
test_sqrt_3_prec_round_helper(3, Nearest, "1.8", "0x1.c#3", Greater);
test_sqrt_3_prec_round_helper(4, Floor, "1.6", "0x1.a#4", Less);
test_sqrt_3_prec_round_helper(4, Ceiling, "1.8", "0x1.c#4", Greater);
test_sqrt_3_prec_round_helper(4, Down, "1.6", "0x1.a#4", Less);
test_sqrt_3_prec_round_helper(4, Up, "1.8", "0x1.c#4", Greater);
test_sqrt_3_prec_round_helper(4, Nearest, "1.8", "0x1.c#4", Greater);
test_sqrt_3_prec_round_helper(5, Floor, "1.7", "0x1.b#5", Less);
test_sqrt_3_prec_round_helper(5, Ceiling, "1.75", "0x1.c#5", Greater);
test_sqrt_3_prec_round_helper(5, Down, "1.7", "0x1.b#5", Less);
test_sqrt_3_prec_round_helper(5, Up, "1.75", "0x1.c#5", Greater);
test_sqrt_3_prec_round_helper(5, Nearest, "1.75", "0x1.c#5", Greater);
test_sqrt_3_prec_round_helper(6, Floor, "1.72", "0x1.b8#6", Less);
test_sqrt_3_prec_round_helper(6, Ceiling, "1.75", "0x1.c0#6", Greater);
test_sqrt_3_prec_round_helper(6, Down, "1.72", "0x1.b8#6", Less);
test_sqrt_3_prec_round_helper(6, Up, "1.75", "0x1.c0#6", Greater);
test_sqrt_3_prec_round_helper(6, Nearest, "1.72", "0x1.b8#6", Less);
test_sqrt_3_prec_round_helper(7, Floor, "1.72", "0x1.b8#7", Less);
test_sqrt_3_prec_round_helper(7, Ceiling, "1.73", "0x1.bc#7", Greater);
test_sqrt_3_prec_round_helper(7, Down, "1.72", "0x1.b8#7", Less);
test_sqrt_3_prec_round_helper(7, Up, "1.73", "0x1.bc#7", Greater);
test_sqrt_3_prec_round_helper(7, Nearest, "1.73", "0x1.bc#7", Greater);
test_sqrt_3_prec_round_helper(8, Floor, "1.727", "0x1.ba#8", Less);
test_sqrt_3_prec_round_helper(8, Ceiling, "1.734", "0x1.bc#8", Greater);
test_sqrt_3_prec_round_helper(8, Down, "1.727", "0x1.ba#8", Less);
test_sqrt_3_prec_round_helper(8, Up, "1.734", "0x1.bc#8", Greater);
test_sqrt_3_prec_round_helper(8, Nearest, "1.734", "0x1.bc#8", Greater);
test_sqrt_3_prec_round_helper(9, Floor, "1.73", "0x1.bb#9", Less);
test_sqrt_3_prec_round_helper(9, Ceiling, "1.734", "0x1.bc#9", Greater);
test_sqrt_3_prec_round_helper(9, Down, "1.73", "0x1.bb#9", Less);
test_sqrt_3_prec_round_helper(9, Up, "1.734", "0x1.bc#9", Greater);
test_sqrt_3_prec_round_helper(9, Nearest, "1.73", "0x1.bb#9", Less);
test_sqrt_3_prec_round_helper(10, Floor, "1.73", "0x1.bb0#10", Less);
test_sqrt_3_prec_round_helper(10, Ceiling, "1.732", "0x1.bb8#10", Greater);
test_sqrt_3_prec_round_helper(10, Down, "1.73", "0x1.bb0#10", Less);
test_sqrt_3_prec_round_helper(10, Up, "1.732", "0x1.bb8#10", Greater);
test_sqrt_3_prec_round_helper(10, Nearest, "1.732", "0x1.bb8#10", Greater);
test_sqrt_3_prec_round_helper(
100,
Floor,
"1.732050807568877293527446341505",
"0x1.bb67ae8584caa73b25742d706#100",
Less,
);
test_sqrt_3_prec_round_helper(
100,
Ceiling,
"1.732050807568877293527446341506",
"0x1.bb67ae8584caa73b25742d708#100",
Greater,
);
test_sqrt_3_prec_round_helper(
100,
Down,
"1.732050807568877293527446341505",
"0x1.bb67ae8584caa73b25742d706#100",
Less,
);
test_sqrt_3_prec_round_helper(
100,
Up,
"1.732050807568877293527446341506",
"0x1.bb67ae8584caa73b25742d708#100",
Greater,
);
test_sqrt_3_prec_round_helper(
100,
Nearest,
"1.732050807568877293527446341506",
"0x1.bb67ae8584caa73b25742d708#100",
Greater,
);
}
#[test]
#[should_panic]
fn sqrt_3_prec_round_fail_1() {
Float::sqrt_3_prec_round(0, Floor);
}
#[test]
#[should_panic]
fn sqrt_3_prec_round_fail_2() {
Float::sqrt_3_prec_round(1, Exact);
}
#[test]
#[should_panic]
fn sqrt_3_prec_round_fail_3() {
Float::sqrt_3_prec_round(1000, Exact);
}
#[test]
fn sqrt_3_prec_properties() {
unsigned_gen_var_11().test_properties(|prec| {
let (sqrt_3, o) = Float::sqrt_3_prec(prec);
assert!(sqrt_3.is_valid());
assert_eq!(sqrt_3.get_prec(), Some(prec));
assert_eq!(sqrt_3.get_exponent(), Some(if prec == 1 { 2 } else { 1 }));
assert_ne!(o, Equal);
if o == Less {
let (sqrt_3_alt, o_alt) = Float::sqrt_3_prec_round(prec, Ceiling);
let mut next_upper = sqrt_3.clone();
next_upper.increment();
if !next_upper.is_power_of_2() {
assert_eq!(ComparableFloat(sqrt_3_alt), ComparableFloat(next_upper));
assert_eq!(o_alt, Greater);
}
} else if !sqrt_3.is_power_of_2() {
let (sqrt_3_alt, o_alt) = Float::sqrt_3_prec_round(prec, Floor);
let mut next_lower = sqrt_3.clone();
next_lower.decrement();
assert_eq!(ComparableFloat(sqrt_3_alt), ComparableFloat(next_lower));
assert_eq!(o_alt, Less);
}
let (sqrt_3_alt, o_alt) = Float::sqrt_3_prec_round(prec, Nearest);
assert_eq!(ComparableFloatRef(&sqrt_3_alt), ComparableFloatRef(&sqrt_3));
assert_eq!(o_alt, o);
let (rug_sqrt_3, rug_o) =
rug_sqrt_3_prec_round(prec, rug_round_try_from_rounding_mode(Nearest).unwrap());
assert_eq!(
ComparableFloatRef(&Float::from(&rug_sqrt_3)),
ComparableFloatRef(&sqrt_3)
);
assert_eq!(rug_o, o);
});
}
#[test]
fn sqrt_3_prec_round_properties() {
unsigned_rounding_mode_pair_gen_var_4().test_properties(|(prec, rm)| {
let (sqrt_3, o) = Float::sqrt_3_prec_round(prec, rm);
assert!(sqrt_3.is_valid());
assert_eq!(sqrt_3.get_prec(), Some(prec));
let expected_exponent = match (prec, rm) {
(1, Ceiling | Up | Nearest) | (2, Ceiling | Up) => 2,
_ => 1,
};
assert_eq!(sqrt_3.get_exponent(), Some(expected_exponent));
assert_ne!(o, Equal);
if o == Less {
let (sqrt_3_alt, o_alt) = Float::sqrt_3_prec_round(prec, Ceiling);
let mut next_upper = sqrt_3.clone();
next_upper.increment();
if !next_upper.is_power_of_2() {
assert_eq!(ComparableFloat(sqrt_3_alt), ComparableFloat(next_upper));
assert_eq!(o_alt, Greater);
}
} else if !sqrt_3.is_power_of_2() {
let (sqrt_3_alt, o_alt) = Float::sqrt_3_prec_round(prec, Floor);
let mut next_lower = sqrt_3.clone();
next_lower.decrement();
assert_eq!(ComparableFloat(sqrt_3_alt), ComparableFloat(next_lower));
assert_eq!(o_alt, Less);
}
if let Ok(rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_sqrt_3, rug_o) = rug_sqrt_3_prec_round(prec, rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_sqrt_3)),
ComparableFloatRef(&sqrt_3)
);
assert_eq!(rug_o, o);
}
});
unsigned_gen_var_11().test_properties(|prec| {
assert_panic!(Float::sqrt_3_prec_round(prec, Exact));
});
test_constant(Float::sqrt_3_prec_round, 10000);
}