use malachite_base::num::arithmetic::traits::IsPowerOf2;
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::float::arithmetic::root::primitive_float_root_u;
use malachite_float::test_util::common::{
rug_round_try_from_rounding_mode, test_constant, to_hex_string,
};
use malachite_float::test_util::float::constants::cbrt_2::rug_cbrt_2_prec_round;
use malachite_float::{ComparableFloat, ComparableFloatRef, Float};
use std::cmp::Ordering::{self, *};
use std::panic::catch_unwind;
fn test_cbrt_2_prec_helper(prec: u64, out: &str, out_hex: &str, out_o: Ordering) {
let (x, o) = Float::cbrt_2_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_cbrt_2_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_cbrt_2_prec() {
test_cbrt_2_prec_helper(1, "1.0", "0x1.0#1", Less);
test_cbrt_2_prec_helper(2, "1.5", "0x1.8#2", Greater);
test_cbrt_2_prec_helper(3, "1.2", "0x1.4#3", Less);
test_cbrt_2_prec_helper(4, "1.25", "0x1.4#4", Less);
test_cbrt_2_prec_helper(5, "1.25", "0x1.4#5", Less);
test_cbrt_2_prec_helper(6, "1.25", "0x1.40#6", Less);
test_cbrt_2_prec_helper(7, "1.266", "0x1.44#7", Greater);
test_cbrt_2_prec_helper(8, "1.258", "0x1.42#8", Less);
test_cbrt_2_prec_helper(9, "1.262", "0x1.43#9", Greater);
test_cbrt_2_prec_helper(10, "1.2598", "0x1.428#10", Less);
test_cbrt_2_prec_helper(
100,
"1.2599210498948731647672106072783",
"0x1.428a2f98d728ae223ddab715c#100",
Greater,
);
test_cbrt_2_prec_helper(
1000,
"1.259921049894873164767210607278228350570251464701507980081975112155299676513959483729396\
562436255094154310256035615665259399024040613737228459110304269355246960642616625000977474\
526565480306867185405518689245872516764199373709695098382783161399155129313695366183947463\
44857657030311909589598474110598107",
"0x1.428a2f98d728ae223ddab715be250d0c288f10291631fbc061800cc36fa2dd3a60b7d03da26f0840f25cc\
16b0f95075c30967a6b5ac6827ab31f06edf4a3487081621806c6b0920d371a0053d2fe49d4ddd52be49cc3c86\
14c865b771ec003a0dce3c57c1bfbdf43d747b840a80e6b17be47fd1b669f88963a78a3aeb0#1000",
Less,
);
test_cbrt_2_prec_helper(
10000,
"1.259921049894873164767210607278228350570251464701507980081975112155299676513959483729396\
562436255094154310256035615665259399024040613737228459110304269355246960642616625000977474\
526565480306867185405518689245872516764199373709695098382783161399155129313695366183947463\
448576570303119095895984741105981162907053590816478011473521325484771297880242208582053257\
972526662202669005665608199471562817640506066482677357267041948620762144296569420507931917\
244148092044823284012747032196428208120190571418899645999831750380188868959420205592202115\
472997384880260736369741788779215798467509953963007826095962420348323866013985736343390973\
712652799599196996837791316816815442885027965152927810767971400204060567480393856125171835\
700690798499634197629147404483454026971547622851317802064387804764932257905289846708580528\
625813000542938856072060974722304063135723493645840657591691691672706012440289670000106908\
103531385290270041508423233623988938649678219414983802707295717681287900144574622714770234\
835715190550672208481848500928723920928264660671717424775370973703001274291809405442569659\
207503635757037518960370747399346101449014515763596047111197384529913296572625890486097885\
618013867738361577300986598366080597575601278712148685624268455641165155817935322801589629\
129944500401208425414160157525841629881423097358215306040577242538364532533565955117252285\
579562277240366562846875901543066753519085484511818175204291241233780963172521357541141811\
466127366045783036057440265130960709681640068881856572310090084284526086414059503369003079\
186993556913351834285693826255431355897354450233302853149322455134121955457821196500833957\
714266850633284196196865121092557895588508996861901546700438968786655453098545057637650360\
089433065103569357775372495484368213703171621621834958093562087260096267851834183456522397\
445400044760217788942081838027866653065326632618641160074007474754735585277016895020637541\
322323296942437017423434916176906007238539022276811297774138720798234303910316285464520831\
111225468283531830470613350996299644553317659489214051165570188505816337759025958459804954\
207116242949057680526343989563098840948676345728459791892101766948457248520366994268712410\
121775277712917316420384063490921165834272096177151409399524727550256541206956883979739039\
050328337538665635436780931508621222709639685474010272293755350110622620742504810764026657\
891889273399055910808781239396445781159916798188575061726269178320334090130419077072717829\
496457167600719020576195215315246386367321302738318790366955893425062362570657996711791354\
312373563603076243394093802780847716478898902529065742892077837823177086899890726460960715\
082065910698646237116601885470807716422828403838636766541958725106267326588663504087641031\
952538583385388576087728395489306437438979807835834449139190339547132068082078908990913108\
486410647047795570845898857484858727228437184120073544794473152128794407364750342346723174\
986125696712349795418169252652549838100098101177829499369705040110300480631571340262578601\
40247662483603681916526298276852880134669379",
"0x1.428a2f98d728ae223ddab715be250d0c288f10291631fbc061800cc36fa2dd3a60b7d03da26f0840f25cc\
16b0f95075c30967a6b5ac6827ab31f06edf4a3487081621806c6b0920d371a0053d2fe49d4ddd52be49cc3c86\
14c865b771ec003a0dce3c57c1bfbdf43d747b840a80e6b17be47fd1b669f88963a78a3aeb0f203190956d75c5\
6ea1d1130bf996f19f57700d75db34ce62922449d3c832bce3b0dd1a350ec848fff8beb6529e36b13007cf3e2d\
dc15cd01ebc1eca20e6f14b34e369b35d7cd922bf3d35b799b082a5daef2476f31b56a6817b091fc97f620d71c\
b6ec1a5684621a5de77928e529f906227637639fdfc7f3ebc8fd38c0e244e552e8fc5383b34ab212433929e2c1\
662340aaceed5ab723fffa2abf1815259dc94f2c88944df1e65d74e7d68bb7d0795b4fa8184667dcd99557750f\
8d90bedb8db9d42f3a859107ea904b91f5771ae7b9c43e609be02f87fbad4a413c4eeef11d063327310138fe9a\
29a856902d586ac29b077ebe8d96246707bb862e045c8d9a0211162d1ac855f8143290a3d865db1174fd1f3fba\
7ced00a03c7650920e664b5dce7da136e8aa39954f84a8f961e39a3d27004e623ddfb93ad47f181a40afd739ea\
7e33fef27bb5c60f3485b34ef2656a770513db1c4b1745409a8981317347d11150c86cc6345ad183bb00c307d3\
62861dca8c48cd8d240c56ba126043fa54890e71fef8edf8a4a393447b0887eef2392a14a1852a65fd89b54d27\
97fb65e9cdb53cd8ed333feef71db2c75c2472f03da08b6965a743690a2c95d97f86b295447583450b3099fc47\
96d7a1cc580941d4f53b6ac8e294c27f038be4eb61b553368437f746ea1df50ba238d3c33181ec088bab5bc34d\
021fa4f53c2a214f4241290f1c9adddd21755066cf014ad371430c305d1bd3e8003fbe02126540f36911b5018e\
9e107b6112a30143306844fd3b34feb321d6195152c1258a3a7518e8075eed807359aa36f0e8790e1301220014\
41ac1320458dd91955c4b5642baad4c6844fc732326923be553142203301a35edeeb664df5e79cf95577a9f7f1\
bec06651c4a1b43647dcc30c2aec64867c35928c7cf8f50f2305ee12f797b7b06ddc856ad8236fa456107b9a0f\
fa2388fb4cc669560dac52b743c113597699b4f62fd1c212c7a1130ad4ea60a8b89f74dede03c26bc4ba9afd0d\
5ab3553d809aea7a925d053843f8d7d64e784c880eab1076f752d2ab81475b080d47eb5377adf13ad176d51044\
60a2571078f80ce35d3c881667cfb7aad3c2b6e3e02af52d5687372268c8aaab4f9a1826a1b64f434d29e5a5b3\
19052e582a0323ec8627355064e1bdbce037ba27d01eb61c794a6568a435a1e8cdba6aef051655c794188aecc4\
6786339d238db4b77bd7a338061816e6c9dff8fe11f2a9e1406aba878ad1d179f57aaefb9944020a02bf022ee9\
bea40dac7a91c282da763315c862495d6f4be456be3e0259fc329c7b7c03c0db344ad6c1482b2d43fbcaf4992d\
5bda80cb02d337782884e4199abdb0492eda588d0be8cb062113371ea274233bda6337820b7285fdb8c95d9e15\
c68d774377f3fa81f9c81473a1abf2625b9042416621a2370a6967a39face78f43914fba4c20f47010e1c9f682\
a8eb381e05d9d8a199bb3ed645e84b925f114c42e14ec0853669475c26aace80cf508d4fb9d19b12b851e5f952\
eb13f56397d974ca8098ee64997d1492bf369ce0eca470e191115803ad43bf4ac07107df18c#10000",
Greater,
);
let cbrt_2_f32 = Float::cbrt_2_prec(u64::from(f32::MANTISSA_DIGITS)).0;
assert_eq!(cbrt_2_f32.to_string(), "1.25992107");
assert_eq!(to_hex_string(&cbrt_2_f32), "0x1.428a30#24");
assert_eq!(cbrt_2_f32, primitive_float_root_u(2.0f32, 3));
let cbrt_2_f64 = Float::cbrt_2_prec(u64::from(f64::MANTISSA_DIGITS)).0;
assert_eq!(cbrt_2_f64.to_string(), "1.2599210498948732");
assert_eq!(to_hex_string(&cbrt_2_f64), "0x1.428a2f98d728b#53");
assert_eq!(cbrt_2_f64, primitive_float_root_u(2.0f64, 3));
}
#[test]
#[should_panic]
fn cbrt_2_prec_fail_1() {
Float::cbrt_2_prec(0);
}
fn test_cbrt_2_prec_round_helper(
prec: u64,
rm: RoundingMode,
out: &str,
out_hex: &str,
out_o: Ordering,
) {
let (x, o) = Float::cbrt_2_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_cbrt_2_prec_round(prec, rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_x)),
ComparableFloatRef(&x)
);
assert_eq!(rug_o, o);
}
}
#[test]
pub fn test_cbrt_2_prec_round() {
test_cbrt_2_prec_round_helper(1, Floor, "1.0", "0x1.0#1", Less);
test_cbrt_2_prec_round_helper(1, Ceiling, "2.0", "0x2.0#1", Greater);
test_cbrt_2_prec_round_helper(1, Down, "1.0", "0x1.0#1", Less);
test_cbrt_2_prec_round_helper(1, Up, "2.0", "0x2.0#1", Greater);
test_cbrt_2_prec_round_helper(1, Nearest, "1.0", "0x1.0#1", Less);
test_cbrt_2_prec_round_helper(2, Floor, "1.0", "0x1.0#2", Less);
test_cbrt_2_prec_round_helper(2, Ceiling, "1.5", "0x1.8#2", Greater);
test_cbrt_2_prec_round_helper(2, Down, "1.0", "0x1.0#2", Less);
test_cbrt_2_prec_round_helper(2, Up, "1.5", "0x1.8#2", Greater);
test_cbrt_2_prec_round_helper(2, Nearest, "1.5", "0x1.8#2", Greater);
test_cbrt_2_prec_round_helper(3, Floor, "1.2", "0x1.4#3", Less);
test_cbrt_2_prec_round_helper(3, Ceiling, "1.5", "0x1.8#3", Greater);
test_cbrt_2_prec_round_helper(3, Down, "1.2", "0x1.4#3", Less);
test_cbrt_2_prec_round_helper(3, Up, "1.5", "0x1.8#3", Greater);
test_cbrt_2_prec_round_helper(3, Nearest, "1.2", "0x1.4#3", Less);
test_cbrt_2_prec_round_helper(4, Floor, "1.25", "0x1.4#4", Less);
test_cbrt_2_prec_round_helper(4, Ceiling, "1.38", "0x1.6#4", Greater);
test_cbrt_2_prec_round_helper(4, Down, "1.25", "0x1.4#4", Less);
test_cbrt_2_prec_round_helper(4, Up, "1.38", "0x1.6#4", Greater);
test_cbrt_2_prec_round_helper(4, Nearest, "1.25", "0x1.4#4", Less);
test_cbrt_2_prec_round_helper(5, Floor, "1.25", "0x1.4#5", Less);
test_cbrt_2_prec_round_helper(5, Ceiling, "1.31", "0x1.5#5", Greater);
test_cbrt_2_prec_round_helper(5, Down, "1.25", "0x1.4#5", Less);
test_cbrt_2_prec_round_helper(5, Up, "1.31", "0x1.5#5", Greater);
test_cbrt_2_prec_round_helper(5, Nearest, "1.25", "0x1.4#5", Less);
test_cbrt_2_prec_round_helper(6, Floor, "1.25", "0x1.40#6", Less);
test_cbrt_2_prec_round_helper(6, Ceiling, "1.28", "0x1.48#6", Greater);
test_cbrt_2_prec_round_helper(6, Down, "1.25", "0x1.40#6", Less);
test_cbrt_2_prec_round_helper(6, Up, "1.28", "0x1.48#6", Greater);
test_cbrt_2_prec_round_helper(6, Nearest, "1.25", "0x1.40#6", Less);
test_cbrt_2_prec_round_helper(7, Floor, "1.250", "0x1.40#7", Less);
test_cbrt_2_prec_round_helper(7, Ceiling, "1.266", "0x1.44#7", Greater);
test_cbrt_2_prec_round_helper(7, Down, "1.250", "0x1.40#7", Less);
test_cbrt_2_prec_round_helper(7, Up, "1.266", "0x1.44#7", Greater);
test_cbrt_2_prec_round_helper(7, Nearest, "1.266", "0x1.44#7", Greater);
test_cbrt_2_prec_round_helper(8, Floor, "1.258", "0x1.42#8", Less);
test_cbrt_2_prec_round_helper(8, Ceiling, "1.266", "0x1.44#8", Greater);
test_cbrt_2_prec_round_helper(8, Down, "1.258", "0x1.42#8", Less);
test_cbrt_2_prec_round_helper(8, Up, "1.266", "0x1.44#8", Greater);
test_cbrt_2_prec_round_helper(8, Nearest, "1.258", "0x1.42#8", Less);
test_cbrt_2_prec_round_helper(9, Floor, "1.258", "0x1.42#9", Less);
test_cbrt_2_prec_round_helper(9, Ceiling, "1.262", "0x1.43#9", Greater);
test_cbrt_2_prec_round_helper(9, Down, "1.258", "0x1.42#9", Less);
test_cbrt_2_prec_round_helper(9, Up, "1.262", "0x1.43#9", Greater);
test_cbrt_2_prec_round_helper(9, Nearest, "1.262", "0x1.43#9", Greater);
test_cbrt_2_prec_round_helper(10, Floor, "1.2598", "0x1.428#10", Less);
test_cbrt_2_prec_round_helper(10, Ceiling, "1.2617", "0x1.430#10", Greater);
test_cbrt_2_prec_round_helper(10, Down, "1.2598", "0x1.428#10", Less);
test_cbrt_2_prec_round_helper(10, Up, "1.2617", "0x1.430#10", Greater);
test_cbrt_2_prec_round_helper(10, Nearest, "1.2598", "0x1.428#10", Less);
test_cbrt_2_prec_round_helper(
100,
Floor,
"1.2599210498948731647672106072767",
"0x1.428a2f98d728ae223ddab715a#100",
Less,
);
test_cbrt_2_prec_round_helper(
100,
Ceiling,
"1.2599210498948731647672106072783",
"0x1.428a2f98d728ae223ddab715c#100",
Greater,
);
test_cbrt_2_prec_round_helper(
100,
Down,
"1.2599210498948731647672106072767",
"0x1.428a2f98d728ae223ddab715a#100",
Less,
);
test_cbrt_2_prec_round_helper(
100,
Up,
"1.2599210498948731647672106072783",
"0x1.428a2f98d728ae223ddab715c#100",
Greater,
);
test_cbrt_2_prec_round_helper(
100,
Nearest,
"1.2599210498948731647672106072783",
"0x1.428a2f98d728ae223ddab715c#100",
Greater,
);
}
#[test]
#[should_panic]
fn cbrt_2_prec_round_fail_1() {
Float::cbrt_2_prec_round(0, Floor);
}
#[test]
#[should_panic]
fn cbrt_2_prec_round_fail_2() {
Float::cbrt_2_prec_round(1, Exact);
}
#[test]
#[should_panic]
fn cbrt_2_prec_round_fail_3() {
Float::cbrt_2_prec_round(1000, Exact);
}
#[test]
fn cbrt_2_prec_properties() {
unsigned_gen_var_11().test_properties(|prec| {
let (cbrt_2, o) = Float::cbrt_2_prec(prec);
assert!(cbrt_2.is_valid());
assert_eq!(cbrt_2.get_prec(), Some(prec));
assert_eq!(cbrt_2.get_exponent(), Some(1));
assert_ne!(o, Equal);
if o == Less {
let (cbrt_2_alt, o_alt) = Float::cbrt_2_prec_round(prec, Ceiling);
let mut next_upper = cbrt_2.clone();
next_upper.increment();
if !next_upper.is_power_of_2() {
assert_eq!(ComparableFloat(cbrt_2_alt), ComparableFloat(next_upper));
assert_eq!(o_alt, Greater);
}
} else if !cbrt_2.is_power_of_2() {
let (cbrt_2_alt, o_alt) = Float::cbrt_2_prec_round(prec, Floor);
let mut next_lower = cbrt_2.clone();
next_lower.decrement();
assert_eq!(ComparableFloat(cbrt_2_alt), ComparableFloat(next_lower));
assert_eq!(o_alt, Less);
}
let (cbrt_2_alt, o_alt) = Float::cbrt_2_prec_round(prec, Nearest);
assert_eq!(ComparableFloatRef(&cbrt_2_alt), ComparableFloatRef(&cbrt_2));
assert_eq!(o_alt, o);
let (rug_cbrt_2, rug_o) =
rug_cbrt_2_prec_round(prec, rug_round_try_from_rounding_mode(Nearest).unwrap());
assert_eq!(
ComparableFloatRef(&Float::from(&rug_cbrt_2)),
ComparableFloatRef(&cbrt_2)
);
assert_eq!(rug_o, o);
});
}
#[test]
fn cbrt_2_prec_round_properties() {
unsigned_rounding_mode_pair_gen_var_4().test_properties(|(prec, rm)| {
let (cbrt_2, o) = Float::cbrt_2_prec_round(prec, rm);
assert!(cbrt_2.is_valid());
assert_eq!(cbrt_2.get_prec(), Some(prec));
assert_eq!(
cbrt_2.get_exponent(),
Some(if prec == 1 && (rm == Ceiling || rm == Up) {
2
} else {
1
})
);
assert_ne!(o, Equal);
if o == Less {
let (cbrt_2_alt, o_alt) = Float::cbrt_2_prec_round(prec, Ceiling);
let mut next_upper = cbrt_2.clone();
next_upper.increment();
if !next_upper.is_power_of_2() {
assert_eq!(ComparableFloat(cbrt_2_alt), ComparableFloat(next_upper));
assert_eq!(o_alt, Greater);
}
} else if !cbrt_2.is_power_of_2() {
let (cbrt_2_alt, o_alt) = Float::cbrt_2_prec_round(prec, Floor);
let mut next_lower = cbrt_2.clone();
next_lower.decrement();
assert_eq!(ComparableFloat(cbrt_2_alt), ComparableFloat(next_lower));
assert_eq!(o_alt, Less);
}
if let Ok(rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_cbrt_2, rug_o) = rug_cbrt_2_prec_round(prec, rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_cbrt_2)),
ComparableFloatRef(&cbrt_2)
);
assert_eq!(rug_o, o);
}
});
unsigned_gen_var_11().test_properties(|prec| {
assert_panic!(Float::cbrt_2_prec_round(prec, Exact));
});
test_constant(Float::cbrt_2_prec_round, 10000);
}