use malachite_base::num::arithmetic::traits::IsPowerOf2;
use malachite_base::num::basic::traits::PiOver2;
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::{test_constant, to_hex_string};
use malachite_float::{ComparableFloat, ComparableFloatRef, Float};
use std::cmp::Ordering::{self, *};
use std::panic::catch_unwind;
fn test_pi_over_2_prec_helper(prec: u64, out: &str, out_hex: &str, out_o: Ordering) {
let (x, o) = Float::pi_over_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);
}
#[test]
pub fn test_pi_over_2_prec() {
test_pi_over_2_prec_helper(1, "2.0", "0x2.0#1", Greater);
test_pi_over_2_prec_helper(2, "1.5", "0x1.8#2", Less);
test_pi_over_2_prec_helper(3, "1.5", "0x1.8#3", Less);
test_pi_over_2_prec_helper(4, "1.6", "0x1.a#4", Greater);
test_pi_over_2_prec_helper(5, "1.56", "0x1.9#5", Less);
test_pi_over_2_prec_helper(6, "1.56", "0x1.90#6", Less);
test_pi_over_2_prec_helper(7, "1.58", "0x1.94#7", Greater);
test_pi_over_2_prec_helper(8, "1.57", "0x1.92#8", Less);
test_pi_over_2_prec_helper(9, "1.57", "0x1.92#9", Less);
test_pi_over_2_prec_helper(10, "1.57", "0x1.920#10", Less);
test_pi_over_2_prec_helper(
100,
"1.57079632679489661923132169164",
"0x1.921fb54442d18469898cc5170#100",
Less,
);
test_pi_over_2_prec_helper(
1000,
"1.570796326794896619231321691639751442098584699687552910487472296153908203143104499314017\
412671058533991074043256641153323546922304775291115862679704064240558725142051350969260552\
779822311474477465190982214405487832966723064237824116893391582635600954572824283461730174\
3052271633241066968036301245706368",
"0x1.921fb54442d18469898cc51701b839a252049c1114cf98e804177d4c76273644a29410f31c6809bbdf2a3\
3679a748636605614dbe4be286e9fc26adadaa3848bc90b6aecc4bcfd8de89885d34c6fdad617feb96de80d6fd\
bdc70d7f6b5133f4b5d3e4822f8963fcc9250cca3d9c8b67b8400f97142c77e0b31b4906c38#1000",
Less,
);
test_pi_over_2_prec_helper(
10000,
"1.570796326794896619231321691639751442098584699687552910487472296153908203143104499314017\
412671058533991074043256641153323546922304775291115862679704064240558725142051350969260552\
779822311474477465190982214405487832966723064237824116893391582635600954572824283461730174\
305227163324106696803630124570636862293503303157794087440760460481414627045857682183946295\
180005665265274410233260692073475970755804716528635182879795976546093058690966305896552559\
274037231189981374783675942876362445613969091505974564916836681220328321543010697473197612\
368595351089930471851385269608588146588376192337409233834702566000284063572631780413892885\
671378894804586818589360734220450612476715073274792685525396139844629461771009978056064510\
980432017209079906814887385654980259353605674999999186489024975529865866408048159297512229\
727673454151321261154126672342517630965594085505001568919376443293766604190710308588834573\
651799126745214377734365579781431941176893796875978890928890266085613403306500963938305597\
954608210099469047628600532742931639432968076690913984115150976017650926484497886811299706\
945624860887641739565757787428621227075347975414766558430863927944537549190877318732469659\
627530200463850835569504924412006429180801781853830052355090971477798099473383918724724127\
689887363423552023767323104023342129534745646656838514494576052376081028483012029019075096\
755626691215017793820123748236631957099636302134961398391177390818004670860820609962293157\
515143091487277853374919252747294293463497845463605398754651477660582672493601377980118240\
332749559940917398876783184903713271263931275909208787336445488886396900040823530008072624\
596086608607386175070720986784274080680578676276066737870924734219261661953697071667273881\
208431259491784742781049609611092136275127128443835895247300826733402494313616395893042892\
191913983988340727050476941893180475340032112562602558696492448042064244313472802120982642\
511105330593153372139311019597472523561856893480478182185958643733882328786981206945432916\
322997906695239013795049732882039475634734199176297854912911310261244703863359739134241300\
738495451320068197218727652534101748126225874699825715714904595329625468610848230757854929\
193705298942979886487749465080876964234069134341934471387077995927962622976979715524986262\
340422993636822347924326918368111313049562304025621942195225622068274881390398857845717998\
850064808044720847434277924203176711036112914244324079228014253008421369726133733839447626\
069261274977333363911993228298058177443115288728249017796817284087162056257538034739725548\
298047012614439855446572834568433614374470280050751654308964340460437380458912469294504857\
454837992630682774890946564892410841499474361329402428782007135238777566189820725761873117\
182271429222397632933910525570677367869761556713583051067984768115721476242468593555072882\
701795139967201871003655289269531099193723904239244841660722856934375971753215109226595524\
240502685307340337459639095598969976030709831714377220321872561859096089999195507959780907\
337571345619874470453593247115980783972604",
"0x1.921fb54442d18469898cc51701b839a252049c1114cf98e804177d4c76273644a29410f31c6809bbdf2a3\
3679a748636605614dbe4be286e9fc26adadaa3848bc90b6aecc4bcfd8de89885d34c6fdad617feb96de80d6fd\
bdc70d7f6b5133f4b5d3e4822f8963fcc9250cca3d9c8b67b8400f97142c77e0b31b4906c38aba734d22c7f51f\
a499ebf06caba47b9475b2c38c5e6ac410aa5773daa520ee12d2cdace186a9c95793009e2e8d811943042f8652\
0bc8c5c6d9c77c73cee58301d0c07364f0745d80f451f6b8abbe0de98a593bc5797ed2ab02e30732a92f9d52ad\
5ca2ba44c3131f40a202ae51cb51555885b5a662e1a08a0f46750aa4357be3974c9d9f70a08b1b7de1515d4e2a\
eba0c18fb672e1f0b4dc3c98f57eb5d19b61267ae3d1929c0944ac33b9dc7a44c35a5dcd7e25ff40db31410c9b\
0ec04e67d90d4c8a43e56302ef6401977c22eaef4c2bad8ee13118175b28dc411c49f40e9cb566287b6b7f9c1f\
a211c9705a2415242100234e478254f0fcdaf10e334217b74b64d33864e30d5e9c4783528d0696c2a17b44b07d\
39455a899d1b77785b609bd1df25d1df8283f7d954c50f8b28e9cd780bb33652c9f412187444677430ca2b7cfd\
a3ec252e19dc5af5f7037baec42e09039a00d224fab60b5532769d5311b1fbb830dff6fb9214d811e9be86b926\
80509246d87f569a4f8e04d83a9b964c04c8dbd92ea3cec7b746f7bf1ff280d5b3ca61dcbb6705e8260035d60d\
4a7db204fb0622f2e4f610cb51231b47db7d79f3629da899cd9759da97637b6fe288fcd984a966640a2a257af5\
e84df71e8026f19a57eb30794038c9725d9e065d42ba2e43a07e905af9cdce9fdedaabce05e8d3019056b50806\
32016393cb3cf92ff7d8fd1e64752f4fc6d99117c1e3a8b6ffeb0b58a97a80f645682a955991edafd7e91c3b02\
998bda41f006fc14f2e2bdde537c6500d43ab176f8bb4edeaa1547b143f7fe1d63399634627aab9b4ad93d85de\
52c6470ffd1aedc7808d0087d1ecc7e90c1dc257e5ab616e8e9adcd29f23cdb7c22b2e94724de25fdcbc870eef\
96d5265bf19b17d89a0e77263747790656d1b3ba600e83f4f7f15f88fda4aeded26d74848cc7556c738b5c9ead\
0684768e857e392f0471e2d97c73aca5bc7fb717df90915b244445c094806f80e27d6af503447e18e68e7f8c8d\
9d460d69797910c5f070bbbf53a96ff45810fd0f2d06607dab7ba740c5679eb6744f14cda5427f07e89f05bbe6\
21dc0e956d46c8b2fd133404abb82c9e6398a108d0a3bf3569032bbdafd4363aa217afdce9ae7f5e6d7863d9f4\
4d06b208de9d70f3f24801287169038d9af1134005dabdc705792321b4df804dc8f2ab1c88eacefd3553c60a1c\
4ecad29bf903eadd10172dce2c19301bb314ae7d488e40cb42739a520d9a396e53d8a54a50da880294d29948ae\
b07ab9fde4de37215b0523b40f33a00045d37daab8df48ff94b76359506ec8adb31b290f3dcfcdb7f9a029762c\
2ab3229d816aed4cfc7d0845d23ccb74283b525bd3874dad994a26dba8497620c9311d6b7535824d3efbece773\
05c47f6d93376554638b4cd0bffab3229366158cf708c9b0152ba84a614d02c89a0720c1d1f1faa4c4d2da14eb\
2b5c7f26b4cfb9feb50e94e03f7f4187aa6969c737812aee0a66e90434238759331c174e3010f662f04b4359f9\
f5d77e49e4b8c0a35b53850b43f9ac2295071435bce2982d528039b9f03c20e3fef572e473e#10000",
Less,
);
let pi_over_2_f32 = Float::pi_over_2_prec(u64::from(f32::MANTISSA_DIGITS)).0;
assert_eq!(pi_over_2_f32.to_string(), "1.5707964");
assert_eq!(to_hex_string(&pi_over_2_f32), "0x1.921fb6#24");
assert_eq!(pi_over_2_f32, f32::PI_OVER_2);
let pi_over_2_f64 = Float::pi_over_2_prec(u64::from(f64::MANTISSA_DIGITS)).0;
assert_eq!(pi_over_2_f64.to_string(), "1.5707963267948966");
assert_eq!(to_hex_string(&pi_over_2_f64), "0x1.921fb54442d18#53");
assert_eq!(pi_over_2_f64, f64::PI_OVER_2);
}
#[test]
#[should_panic]
fn pi_over_2_prec_fail_1() {
Float::pi_over_2_prec(0);
}
fn test_pi_over_2_prec_round_helper(
prec: u64,
rm: RoundingMode,
out: &str,
out_hex: &str,
out_o: Ordering,
) {
let (x, o) = Float::pi_over_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);
}
#[test]
pub fn test_pi_over_2_prec_round() {
test_pi_over_2_prec_round_helper(1, Floor, "1.0", "0x1.0#1", Less);
test_pi_over_2_prec_round_helper(1, Ceiling, "2.0", "0x2.0#1", Greater);
test_pi_over_2_prec_round_helper(1, Down, "1.0", "0x1.0#1", Less);
test_pi_over_2_prec_round_helper(1, Up, "2.0", "0x2.0#1", Greater);
test_pi_over_2_prec_round_helper(1, Nearest, "2.0", "0x2.0#1", Greater);
test_pi_over_2_prec_round_helper(2, Floor, "1.5", "0x1.8#2", Less);
test_pi_over_2_prec_round_helper(2, Ceiling, "2.0", "0x2.0#2", Greater);
test_pi_over_2_prec_round_helper(2, Down, "1.5", "0x1.8#2", Less);
test_pi_over_2_prec_round_helper(2, Up, "2.0", "0x2.0#2", Greater);
test_pi_over_2_prec_round_helper(2, Nearest, "1.5", "0x1.8#2", Less);
test_pi_over_2_prec_round_helper(3, Floor, "1.5", "0x1.8#3", Less);
test_pi_over_2_prec_round_helper(3, Ceiling, "1.8", "0x1.c#3", Greater);
test_pi_over_2_prec_round_helper(3, Down, "1.5", "0x1.8#3", Less);
test_pi_over_2_prec_round_helper(3, Up, "1.8", "0x1.c#3", Greater);
test_pi_over_2_prec_round_helper(3, Nearest, "1.5", "0x1.8#3", Less);
test_pi_over_2_prec_round_helper(4, Floor, "1.5", "0x1.8#4", Less);
test_pi_over_2_prec_round_helper(4, Ceiling, "1.6", "0x1.a#4", Greater);
test_pi_over_2_prec_round_helper(4, Down, "1.5", "0x1.8#4", Less);
test_pi_over_2_prec_round_helper(4, Up, "1.6", "0x1.a#4", Greater);
test_pi_over_2_prec_round_helper(4, Nearest, "1.6", "0x1.a#4", Greater);
test_pi_over_2_prec_round_helper(5, Floor, "1.56", "0x1.9#5", Less);
test_pi_over_2_prec_round_helper(5, Ceiling, "1.62", "0x1.a#5", Greater);
test_pi_over_2_prec_round_helper(5, Down, "1.56", "0x1.9#5", Less);
test_pi_over_2_prec_round_helper(5, Up, "1.62", "0x1.a#5", Greater);
test_pi_over_2_prec_round_helper(5, Nearest, "1.56", "0x1.9#5", Less);
test_pi_over_2_prec_round_helper(6, Floor, "1.56", "0x1.90#6", Less);
test_pi_over_2_prec_round_helper(6, Ceiling, "1.59", "0x1.98#6", Greater);
test_pi_over_2_prec_round_helper(6, Down, "1.56", "0x1.90#6", Less);
test_pi_over_2_prec_round_helper(6, Up, "1.59", "0x1.98#6", Greater);
test_pi_over_2_prec_round_helper(6, Nearest, "1.56", "0x1.90#6", Less);
test_pi_over_2_prec_round_helper(7, Floor, "1.56", "0x1.90#7", Less);
test_pi_over_2_prec_round_helper(7, Ceiling, "1.58", "0x1.94#7", Greater);
test_pi_over_2_prec_round_helper(7, Down, "1.56", "0x1.90#7", Less);
test_pi_over_2_prec_round_helper(7, Up, "1.58", "0x1.94#7", Greater);
test_pi_over_2_prec_round_helper(7, Nearest, "1.58", "0x1.94#7", Greater);
test_pi_over_2_prec_round_helper(8, Floor, "1.57", "0x1.92#8", Less);
test_pi_over_2_prec_round_helper(8, Ceiling, "1.58", "0x1.94#8", Greater);
test_pi_over_2_prec_round_helper(8, Down, "1.57", "0x1.92#8", Less);
test_pi_over_2_prec_round_helper(8, Up, "1.58", "0x1.94#8", Greater);
test_pi_over_2_prec_round_helper(8, Nearest, "1.57", "0x1.92#8", Less);
test_pi_over_2_prec_round_helper(9, Floor, "1.57", "0x1.92#9", Less);
test_pi_over_2_prec_round_helper(9, Ceiling, "1.574", "0x1.93#9", Greater);
test_pi_over_2_prec_round_helper(9, Down, "1.57", "0x1.92#9", Less);
test_pi_over_2_prec_round_helper(9, Up, "1.574", "0x1.93#9", Greater);
test_pi_over_2_prec_round_helper(9, Nearest, "1.57", "0x1.92#9", Less);
test_pi_over_2_prec_round_helper(10, Floor, "1.57", "0x1.920#10", Less);
test_pi_over_2_prec_round_helper(10, Ceiling, "1.572", "0x1.928#10", Greater);
test_pi_over_2_prec_round_helper(10, Down, "1.57", "0x1.920#10", Less);
test_pi_over_2_prec_round_helper(10, Up, "1.572", "0x1.928#10", Greater);
test_pi_over_2_prec_round_helper(10, Nearest, "1.57", "0x1.920#10", Less);
test_pi_over_2_prec_round_helper(
100,
Floor,
"1.57079632679489661923132169164",
"0x1.921fb54442d18469898cc5170#100",
Less,
);
test_pi_over_2_prec_round_helper(
100,
Ceiling,
"1.570796326794896619231321691641",
"0x1.921fb54442d18469898cc5172#100",
Greater,
);
test_pi_over_2_prec_round_helper(
100,
Down,
"1.57079632679489661923132169164",
"0x1.921fb54442d18469898cc5170#100",
Less,
);
test_pi_over_2_prec_round_helper(
100,
Up,
"1.570796326794896619231321691641",
"0x1.921fb54442d18469898cc5172#100",
Greater,
);
test_pi_over_2_prec_round_helper(
100,
Nearest,
"1.57079632679489661923132169164",
"0x1.921fb54442d18469898cc5170#100",
Less,
);
}
#[test]
#[should_panic]
fn pi_over_2_prec_round_fail_1() {
Float::pi_over_2_prec_round(0, Floor);
}
#[test]
#[should_panic]
fn pi_over_2_prec_round_fail_2() {
Float::pi_over_2_prec_round(1, Exact);
}
#[test]
#[should_panic]
fn pi_over_2_prec_round_fail_3() {
Float::pi_over_2_prec_round(1000, Exact);
}
#[test]
fn pi_over_2_prec_properties() {
unsigned_gen_var_11().test_properties(|prec| {
let (pi_over_2, o) = Float::pi_over_2_prec(prec);
assert!(pi_over_2.is_valid());
assert_eq!(pi_over_2.get_prec(), Some(prec));
assert_eq!(
pi_over_2.get_exponent(),
Some(if prec == 1 { 2 } else { 1 })
);
assert_ne!(o, Equal);
if o == Less {
let (pi_over_2_alt, o_alt) = Float::pi_over_2_prec_round(prec, Ceiling);
let mut next_upper = pi_over_2.clone();
next_upper.increment();
if !next_upper.is_power_of_2() {
assert_eq!(ComparableFloat(pi_over_2_alt), ComparableFloat(next_upper));
assert_eq!(o_alt, Greater);
}
} else if !pi_over_2.is_power_of_2() {
let (pi_over_2_alt, o_alt) = Float::pi_over_2_prec_round(prec, Floor);
let mut next_lower = pi_over_2.clone();
next_lower.decrement();
assert_eq!(ComparableFloat(pi_over_2_alt), ComparableFloat(next_lower));
assert_eq!(o_alt, Less);
}
let (pi_over_2_alt, o_alt) = Float::pi_over_2_prec_round(prec, Nearest);
assert_eq!(
ComparableFloatRef(&pi_over_2_alt),
ComparableFloatRef(&pi_over_2)
);
assert_eq!(o_alt, o);
});
}
#[test]
fn pi_over_2_prec_round_properties() {
unsigned_rounding_mode_pair_gen_var_4().test_properties(|(prec, rm)| {
let (pi_over_2, o) = Float::pi_over_2_prec_round(prec, rm);
assert!(pi_over_2.is_valid());
assert_eq!(pi_over_2.get_prec(), Some(prec));
let expected_exponent = match (prec, rm) {
(1, Ceiling | Up | Nearest) | (2, Ceiling | Up) => 2,
_ => 1,
};
assert_eq!(pi_over_2.get_exponent(), Some(expected_exponent));
assert_ne!(o, Equal);
if o == Less {
let (pi_over_2_alt, o_alt) = Float::pi_over_2_prec_round(prec, Ceiling);
let mut next_upper = pi_over_2.clone();
next_upper.increment();
if !next_upper.is_power_of_2() {
assert_eq!(ComparableFloat(pi_over_2_alt), ComparableFloat(next_upper));
assert_eq!(o_alt, Greater);
}
} else if !pi_over_2.is_power_of_2() {
let (pi_over_2_alt, o_alt) = Float::pi_over_2_prec_round(prec, Floor);
let mut next_lower = pi_over_2.clone();
next_lower.decrement();
assert_eq!(ComparableFloat(pi_over_2_alt), ComparableFloat(next_lower));
assert_eq!(o_alt, Less);
}
});
unsigned_gen_var_11().test_properties(|prec| {
assert_panic!(Float::pi_over_2_prec_round(prec, Exact));
});
test_constant(Float::pi_over_2_prec_round, 10000);
}