use malachite_base::num::arithmetic::traits::IsPowerOf2;
use malachite_base::num::basic::traits::Ln2;
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::ln_2::rug_ln_2_prec_round;
use malachite_float::{ComparableFloat, ComparableFloatRef, Float};
use std::cmp::Ordering::{self, *};
use std::panic::catch_unwind;
fn test_ln_2_prec_helper(prec: u64, out: &str, out_hex: &str, out_o: Ordering) {
let (x, o) = Float::ln_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_ln_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_ln_2_prec() {
test_ln_2_prec_helper(1, "0.5", "0x0.8#1", Less);
test_ln_2_prec_helper(2, "0.8", "0x0.c#2", Greater);
test_ln_2_prec_helper(3, "0.8", "0x0.c#3", Greater);
test_ln_2_prec_helper(4, "0.7", "0x0.b#4", Less);
test_ln_2_prec_helper(5, "0.69", "0x0.b0#5", Less);
test_ln_2_prec_helper(6, "0.69", "0x0.b0#6", Less);
test_ln_2_prec_helper(7, "0.695", "0x0.b2#7", Greater);
test_ln_2_prec_helper(8, "0.691", "0x0.b1#8", Less);
test_ln_2_prec_helper(9, "0.693", "0x0.b18#9", Greater);
test_ln_2_prec_helper(10, "0.693", "0x0.b18#10", Greater);
test_ln_2_prec_helper(
100,
"0.693147180559945309417232121458",
"0x0.b17217f7d1cf79abc9e3b3980#100",
Less,
);
test_ln_2_prec_helper(
1000,
"0.693147180559945309417232121458176568075500134360255254120680009493393621969694715605863\
326996418687542001481020570685733685520235758130557032670751635075961930727570828371435190\
307038623891673471123350115364497955239120475172681574932065155524734139525882950453007095\
3263666426541042391578149520437404",
"0x0.b17217f7d1cf79abc9e3b39803f2f6af40f343267298b62d8a0d175b8baafa2be7b876206debac9855955\
2fb4afa1b10ed2eae35c138214427573b291169b8253e96ca16224ae8c51acbda11317c387eb9ea9bc3b136603\
b256fa0ec7657f74b72ce87b19d6548caf5dfa6bd38303248655fa1872f20e3a2da2d97c50f#1000",
Less,
);
test_ln_2_prec_helper(
10000,
"0.693147180559945309417232121458176568075500134360255254120680009493393621969694715605863\
326996418687542001481020570685733685520235758130557032670751635075961930727570828371435190\
307038623891673471123350115364497955239120475172681574932065155524734139525882950453007095\
326366642654104239157814952043740430385500801944170641671518644712839968171784546957026271\
631064546150257207402481637773389638550695260668341137273873722928956493547025762652098859\
693201965058554764703306793654432547632744951250406069438147104689946506220167720424524529\
612687946546193165174681392672504103802546259656869144192871608293803172714367782654877566\
485085674077648451464439940461422603193096735402574446070308096085047486638523138181676751\
438667476647890881437141985494231519973548803751658612753529166100071053558249879414729509\
293113897155998205654392871700072180857610252368892132449713893203784393530887748259701715\
591070882368362758984258918535302436342143670611892367891923723146723217205340164925687274\
778234453534764811494186423867767744060695626573796008670762571991847340226514628379048830\
620330611446300737194890027436439650025809365194430411911506080948793067865158870900605203\
468429736193841289652556539686022194122924207574321757489097706752687115817051137009158942\
665478595964890653058460258668382940022833005382074005677053046787001841624044188332327983\
863490015631218895606505531512721993983320307514084260914790012651682434438935724727882054\
862715527418772430024897945401961872339808608316648114909306675193393128904316413706813977\
764981769748689038877899912965036192707108892641052309247839173735012298424204995689359922\
066022046549415106139187885744245577510206837030866619480896412186807790208181588580001688\
115973056186676199187395200766719214592236720602539595436541655311295175989940056000366513\
567569051245926825743946483168332624901803824240824231452306140963805700702551387702681785\
163069025513703234053802145019015374029509942262995779647427138157363801729873940704242179\
972266962979939312706935747240493386530879758721699645129446491883771156701678598804981838\
896784134938314014073166472765327635919233511233389338709513209059272185471328975470797891\
384445466676192702885533423429899321803769154973340267546758873236778342916191810430116091\
695265547859732891763545556742863877463987101912431754255888301206779210280341206879759143\
081283307230300883494705792496591005860012341561757413272465943068435465211135021544341539\
955381856522750221424566440006276183303206472725721975152908278568421320795988638967277119\
552218819046603957009774706512619505278932296088931405625433442552392062030343941777357945\
592125901992559114844024239012554259003129537051922061506434583787873002035414421785758013\
236451660709914383145004985896688577222148652882169418127048860758972203216663128378329156\
763074987298574638928269373509840778049395004933998762647550703162216139034845299424917248\
373406136622638349368111684167056925214751383930638455371862687797328895558871634429756244\
75539236636948887782389017498102735655240503",
"0x0.b17217f7d1cf79abc9e3b39803f2f6af40f343267298b62d8a0d175b8baafa2be7b876206debac9855955\
2fb4afa1b10ed2eae35c138214427573b291169b8253e96ca16224ae8c51acbda11317c387eb9ea9bc3b136603\
b256fa0ec7657f74b72ce87b19d6548caf5dfa6bd38303248655fa1872f20e3a2da2d97c50f3fd5c607f4ca11f\
b5bfb90610d30f88fe551a2ee569d6dfc1efa157d2e23de1400b39617460775db8990e5c943e732b479cd33ccc\
c4e659393514c4c1a1e0bd1d6095d25669b333564a3376a9c7f8a5e148e82074db6015cfe7aa30c480a5417350\
d2c955d5179b1e17b9dae313cdb6c606cb1078f735d1b2db31b5f50b5185064c18b4d162db3b365853d7598a19\
51ae273ee5570b6c68f96983496d4e6d330af889b44a02554731cdc8ea17293d1228a4ef98d6f5177fbcf07552\
68a5c1f9538b98261affd446b1ca3cf5e9222b88c66d3c5422183edc99421090bbb16faf3d949f236e02b20cee\
886b905c128d53d0bd2f9621363196af503020060e49908391a0c57339ba2beba7d052ac5b61cc4e9207cef2f0\
ce2d7373958d7622658901e646a95184460dc4e7487156e0c292413d5e361c1696dd24aaebd473826fda0c238b\
90ab111bbbd67c724972cd18bfbbd9d426c472096e76115c05f6f7cebac9f45aececb72f19c38339d8f6826250\
dea891ef07afff3a892374e175eb4afc8daadd885db6ab03a49bd0dc0b1b31d8a0e23fac5e5767df95884e0642\
5a41526fac51c3ea8449fe8f70edd062b1a63a6c4c60c52ab33161e238438897a39ce78b63c9f364f5b8aef22e\
c2fee6e0850eca42d06fb0c75df5497e00c554b03d7d2874a000ca8f58d94f0341cbe2ec92156c9f949db4a931\
6f281501e53daec3f64f1b783154c60320e2ff79333ce3573facc5fdcf11785903155bbd90f023b220224fcd84\
71bf4f445f0a88a14f0cd976ea354bb20cdb5ccb3db239288d586554e2a0e8a6fe51a8cfaa72ef2ad8a43dc421\
2b210b779dfe49d7307cc846532e4b9694edad162af053b1751f3a3d091f65665815412b5e8c202461069ac14b\
958784934b8d6cce1daa50537011aa4fb42b9a3def41bda1f85ef6fdbf2f2d89d2a4b1835278fd9405789f4568\
12b552879a6168695c12963b0ff01eaab73e5b5c1585318e7624f14a51a4a026b6808292057fd99b66dc085a98\
ac8d8caf9eeeea98a2400cac95f260fd10036f9f91096ac3195220a1a356b2a73b7eaadaf6d605871ef7afb80b\
c423433562e94b12dfab414451579df59eae0517070624012a82962c59cab347f8304d889659e5a9139db14efc\
c30852be3e8fc99f14d1d822dd6e2f76797e30219c8aa9ce8848a886eb3c87b7295988012e8314186edbaf8685\
6ccd3c3b6ee94e62f110a6783d2aae89ccc3b76fc435a0ce134c2838fd571ec6c1366a992cbb9ac407ddb6c13a\
4b8d1ecf7567eb0971cc90b5518569f144e67ebe9b42698fea79d89d5c5ed40ac5e3701d7d7725377cf0656907\
fb9b1b16ea8911afbf1ae5a66203d62fd1e7093435b9c277736a70fa8601cf6868a055b2238677a2bfbbd843bf\
a1873f0c446b01b2ae0e98e0e1527a900b1af5e75f87c7cd17af804d933d6f7e1b9e1903d71c7bba0281137609\
0dd617335dfdd424f2b661cd85063034e341b06e211977b075a8b7808df43bd8eef1fd9678cc0b5e9f60a3eb81\
747f87e5709468d78ebd2da0116e6b65aeb3be77ee236fdc33bc8e7df1ffc2e2288f8ca9aee#10000",
Less,
);
let ln_2_f32 = Float::ln_2_prec(u64::from(f32::MANTISSA_DIGITS)).0;
assert_eq!(ln_2_f32.to_string(), "0.69314718");
assert_eq!(to_hex_string(&ln_2_f32), "0x0.b17218#24");
assert_eq!(ln_2_f32, f32::LN_2);
let ln_2_f64 = Float::ln_2_prec(u64::from(f64::MANTISSA_DIGITS)).0;
assert_eq!(ln_2_f64.to_string(), "0.6931471805599453");
assert_eq!(to_hex_string(&ln_2_f64), "0x0.b17217f7d1cf78#53");
assert_eq!(ln_2_f64, f64::LN_2);
}
#[test]
#[should_panic]
fn ln_2_prec_fail_1() {
Float::ln_2_prec(0);
}
fn test_ln_2_prec_round_helper(
prec: u64,
rm: RoundingMode,
out: &str,
out_hex: &str,
out_o: Ordering,
) {
let (x, o) = Float::ln_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_ln_2_prec_round(prec, rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_x)),
ComparableFloatRef(&x)
);
assert_eq!(rug_o, o);
}
}
#[test]
pub fn test_ln_2_prec_round() {
test_ln_2_prec_round_helper(1, Floor, "0.5", "0x0.8#1", Less);
test_ln_2_prec_round_helper(1, Ceiling, "1.0", "0x1.0#1", Greater);
test_ln_2_prec_round_helper(1, Down, "0.5", "0x0.8#1", Less);
test_ln_2_prec_round_helper(1, Up, "1.0", "0x1.0#1", Greater);
test_ln_2_prec_round_helper(1, Nearest, "0.5", "0x0.8#1", Less);
test_ln_2_prec_round_helper(2, Floor, "0.5", "0x0.8#2", Less);
test_ln_2_prec_round_helper(2, Ceiling, "0.8", "0x0.c#2", Greater);
test_ln_2_prec_round_helper(2, Down, "0.5", "0x0.8#2", Less);
test_ln_2_prec_round_helper(2, Up, "0.8", "0x0.c#2", Greater);
test_ln_2_prec_round_helper(2, Nearest, "0.8", "0x0.c#2", Greater);
test_ln_2_prec_round_helper(3, Floor, "0.6", "0x0.a#3", Less);
test_ln_2_prec_round_helper(3, Ceiling, "0.8", "0x0.c#3", Greater);
test_ln_2_prec_round_helper(3, Down, "0.6", "0x0.a#3", Less);
test_ln_2_prec_round_helper(3, Up, "0.8", "0x0.c#3", Greater);
test_ln_2_prec_round_helper(3, Nearest, "0.8", "0x0.c#3", Greater);
test_ln_2_prec_round_helper(4, Floor, "0.7", "0x0.b#4", Less);
test_ln_2_prec_round_helper(4, Ceiling, "0.75", "0x0.c#4", Greater);
test_ln_2_prec_round_helper(4, Down, "0.7", "0x0.b#4", Less);
test_ln_2_prec_round_helper(4, Up, "0.75", "0x0.c#4", Greater);
test_ln_2_prec_round_helper(4, Nearest, "0.7", "0x0.b#4", Less);
test_ln_2_prec_round_helper(5, Floor, "0.69", "0x0.b0#5", Less);
test_ln_2_prec_round_helper(5, Ceiling, "0.72", "0x0.b8#5", Greater);
test_ln_2_prec_round_helper(5, Down, "0.69", "0x0.b0#5", Less);
test_ln_2_prec_round_helper(5, Up, "0.72", "0x0.b8#5", Greater);
test_ln_2_prec_round_helper(5, Nearest, "0.69", "0x0.b0#5", Less);
test_ln_2_prec_round_helper(6, Floor, "0.69", "0x0.b0#6", Less);
test_ln_2_prec_round_helper(6, Ceiling, "0.7", "0x0.b4#6", Greater);
test_ln_2_prec_round_helper(6, Down, "0.69", "0x0.b0#6", Less);
test_ln_2_prec_round_helper(6, Up, "0.7", "0x0.b4#6", Greater);
test_ln_2_prec_round_helper(6, Nearest, "0.69", "0x0.b0#6", Less);
test_ln_2_prec_round_helper(7, Floor, "0.69", "0x0.b0#7", Less);
test_ln_2_prec_round_helper(7, Ceiling, "0.695", "0x0.b2#7", Greater);
test_ln_2_prec_round_helper(7, Down, "0.69", "0x0.b0#7", Less);
test_ln_2_prec_round_helper(7, Up, "0.695", "0x0.b2#7", Greater);
test_ln_2_prec_round_helper(7, Nearest, "0.695", "0x0.b2#7", Greater);
test_ln_2_prec_round_helper(8, Floor, "0.691", "0x0.b1#8", Less);
test_ln_2_prec_round_helper(8, Ceiling, "0.695", "0x0.b2#8", Greater);
test_ln_2_prec_round_helper(8, Down, "0.691", "0x0.b1#8", Less);
test_ln_2_prec_round_helper(8, Up, "0.695", "0x0.b2#8", Greater);
test_ln_2_prec_round_helper(8, Nearest, "0.691", "0x0.b1#8", Less);
test_ln_2_prec_round_helper(9, Floor, "0.691", "0x0.b10#9", Less);
test_ln_2_prec_round_helper(9, Ceiling, "0.693", "0x0.b18#9", Greater);
test_ln_2_prec_round_helper(9, Down, "0.691", "0x0.b10#9", Less);
test_ln_2_prec_round_helper(9, Up, "0.693", "0x0.b18#9", Greater);
test_ln_2_prec_round_helper(9, Nearest, "0.693", "0x0.b18#9", Greater);
test_ln_2_prec_round_helper(10, Floor, "0.692", "0x0.b14#10", Less);
test_ln_2_prec_round_helper(10, Ceiling, "0.693", "0x0.b18#10", Greater);
test_ln_2_prec_round_helper(10, Down, "0.692", "0x0.b14#10", Less);
test_ln_2_prec_round_helper(10, Up, "0.693", "0x0.b18#10", Greater);
test_ln_2_prec_round_helper(10, Nearest, "0.693", "0x0.b18#10", Greater);
test_ln_2_prec_round_helper(
100,
Floor,
"0.693147180559945309417232121458",
"0x0.b17217f7d1cf79abc9e3b3980#100",
Less,
);
test_ln_2_prec_round_helper(
100,
Ceiling,
"0.693147180559945309417232121459",
"0x0.b17217f7d1cf79abc9e3b3981#100",
Greater,
);
test_ln_2_prec_round_helper(
100,
Down,
"0.693147180559945309417232121458",
"0x0.b17217f7d1cf79abc9e3b3980#100",
Less,
);
test_ln_2_prec_round_helper(
100,
Up,
"0.693147180559945309417232121459",
"0x0.b17217f7d1cf79abc9e3b3981#100",
Greater,
);
test_ln_2_prec_round_helper(
100,
Nearest,
"0.693147180559945309417232121458",
"0x0.b17217f7d1cf79abc9e3b3980#100",
Less,
);
}
#[test]
#[should_panic]
fn ln_2_prec_round_fail_1() {
Float::ln_2_prec_round(0, Floor);
}
#[test]
#[should_panic]
fn ln_2_prec_round_fail_2() {
Float::ln_2_prec_round(1, Exact);
}
#[test]
#[should_panic]
fn ln_2_prec_round_fail_3() {
Float::ln_2_prec_round(1000, Exact);
}
#[test]
fn ln_2_prec_properties() {
unsigned_gen_var_11().test_properties(|prec| {
let (ln_2, o) = Float::ln_2_prec(prec);
assert!(ln_2.is_valid());
assert_eq!(ln_2.get_prec(), Some(prec));
assert_eq!(ln_2.get_exponent(), Some(0));
assert_ne!(o, Equal);
if o == Less {
let (ln_2_alt, o_alt) = Float::ln_2_prec_round(prec, Ceiling);
let mut next_upper = ln_2.clone();
next_upper.increment();
if !next_upper.is_power_of_2() {
assert_eq!(ComparableFloat(ln_2_alt), ComparableFloat(next_upper));
assert_eq!(o_alt, Greater);
}
} else if !ln_2.is_power_of_2() {
let (ln_2_alt, o_alt) = Float::ln_2_prec_round(prec, Floor);
let mut next_lower = ln_2.clone();
next_lower.decrement();
assert_eq!(ComparableFloat(ln_2_alt), ComparableFloat(next_lower));
assert_eq!(o_alt, Less);
}
let (ln_2_alt, o_alt) = Float::ln_2_prec_round(prec, Nearest);
assert_eq!(ComparableFloatRef(&ln_2_alt), ComparableFloatRef(&ln_2));
assert_eq!(o_alt, o);
let (rug_ln_2, rug_o) =
rug_ln_2_prec_round(prec, rug_round_try_from_rounding_mode(Nearest).unwrap());
assert_eq!(
ComparableFloatRef(&Float::from(&rug_ln_2)),
ComparableFloatRef(&ln_2)
);
assert_eq!(rug_o, o);
});
}
#[test]
fn ln_2_prec_round_properties() {
unsigned_rounding_mode_pair_gen_var_4().test_properties(|(prec, rm)| {
let (ln_2, o) = Float::ln_2_prec_round(prec, rm);
assert!(ln_2.is_valid());
assert_eq!(ln_2.get_prec(), Some(prec));
assert_eq!(
ln_2.get_exponent(),
Some(if prec == 1 && (rm == Ceiling || rm == Up) {
1
} else {
0
})
);
assert_ne!(o, Equal);
if o == Less {
let (ln_2_alt, o_alt) = Float::ln_2_prec_round(prec, Ceiling);
let mut next_upper = ln_2.clone();
next_upper.increment();
if !next_upper.is_power_of_2() {
assert_eq!(ComparableFloat(ln_2_alt), ComparableFloat(next_upper));
assert_eq!(o_alt, Greater);
}
} else if !ln_2.is_power_of_2() {
let (ln_2_alt, o_alt) = Float::ln_2_prec_round(prec, Floor);
let mut next_lower = ln_2.clone();
next_lower.decrement();
assert_eq!(ComparableFloat(ln_2_alt), ComparableFloat(next_lower));
assert_eq!(o_alt, Less);
}
if let Ok(rm) = rug_round_try_from_rounding_mode(rm) {
let (rug_ln_2, rug_o) = rug_ln_2_prec_round(prec, rm);
assert_eq!(
ComparableFloatRef(&Float::from(&rug_ln_2)),
ComparableFloatRef(&ln_2)
);
assert_eq!(rug_o, o);
}
});
unsigned_gen_var_11().test_properties(|prec| {
assert_panic!(Float::ln_2_prec_round(prec, Exact));
});
test_constant(Float::ln_2_prec_round, 10000);
}