use dashu_base::{Approximation::*, Sign::*};
use dashu_ratio::RBig;
mod helper_macros;
#[test]
fn test_simplest_in() {
assert_eq!(RBig::simplest_in(rbig!(0), rbig!(0)), rbig!(0));
assert_eq!(RBig::simplest_in(rbig!(-1), rbig!(1)), rbig!(0));
assert_eq!(RBig::simplest_in(rbig!(-1), rbig!(-1)), rbig!(-1));
assert_eq!(RBig::simplest_in(rbig!(2 / 7), rbig!(2 / 9)), rbig!(1 / 4));
assert_eq!(RBig::simplest_in(rbig!(-20 / 7), rbig!(-20 / 9)), rbig!(-5 / 2));
assert_eq!(RBig::simplest_in(rbig!(5), rbig!(7)), rbig!(6));
assert_eq!(RBig::simplest_in(rbig!(5), rbig!(6)), rbig!(11 / 2));
}
#[test]
fn test_simplest_from_f32() {
assert_eq!(RBig::simplest_from_f32(0f32), Some(rbig!(0)));
assert_eq!(RBig::simplest_from_f32(f32::INFINITY), None);
assert_eq!(RBig::simplest_from_f32(f32::NEG_INFINITY), None);
assert_eq!(RBig::simplest_from_f32(f32::NAN), None);
let cases = [
(1i32, 1u32),
(2, 1),
(-3, 1),
(1, 2),
(-1, 3),
(1, 4),
(-1, 5),
(22, 7),
(333, 106),
(355, 113),
];
for (num, den) in cases {
let f = num as f32 / den as f32;
assert_eq!(RBig::simplest_from_f32(f).unwrap(), RBig::from_parts(num.into(), den.into()));
}
}
#[test]
fn test_simplest_from_f64() {
assert_eq!(RBig::simplest_from_f64(0f64), Some(rbig!(0)));
assert_eq!(RBig::simplest_from_f64(f64::INFINITY), None);
assert_eq!(RBig::simplest_from_f64(f64::NEG_INFINITY), None);
assert_eq!(RBig::simplest_from_f64(f64::NAN), None);
let cases = [
(1i64, 1u64),
(2, 1),
(-3, 1),
(1, 2),
(-1, 3),
(1, 4),
(-1, 5),
(22, 7),
(333, 106),
(355, 113),
(103993, 33102),
(104348, 33215),
(208341, 66317),
(312689, 99532),
(833719, 265381),
(1146408, 364913),
(4272943, 1360120),
(5419351, 1725033),
(80143857, 25510582),
(165707065, 52746197),
(245850922, 78256779),
];
for (num, den) in cases {
let f = num as f64 / den as f64;
assert_eq!(RBig::simplest_from_f64(f).unwrap(), RBig::from_parts(num.into(), den.into()));
}
}
#[test]
fn test_nearest() {
assert_eq!(rbig!(0).nearest(&ubig!(1)), Exact(rbig!(0)));
assert_eq!(rbig!(1).nearest(&ubig!(2)), Exact(rbig!(1)));
assert_eq!(rbig!(-1).nearest(&ubig!(3)), Exact(rbig!(-1)));
let test_cases = [
(core::f64::consts::PI, 10u64, rbig!(25 / 8), rbig!(22 / 7), Positive),
(core::f64::consts::PI, 100, rbig!(311 / 99), rbig!(22 / 7), Negative),
(core::f64::consts::PI, 1000, rbig!(2818 / 897), rbig!(355 / 113), Positive),
(core::f64::consts::PI, 10000, rbig!(31218 / 9937), rbig!(355 / 113), Positive),
(
core::f64::consts::PI,
100000,
rbig!(208341 / 66317),
rbig!(312689 / 99532),
Positive,
),
(core::f64::consts::SQRT_2, 10, rbig!(7 / 5), rbig!(10 / 7), Negative),
(core::f64::consts::SQRT_2, 100, rbig!(140 / 99), rbig!(99 / 70), Negative),
(core::f64::consts::SQRT_2, 1000, rbig!(1393 / 985), rbig!(577 / 408), Negative),
(
core::f64::consts::SQRT_2,
10000,
rbig!(8119 / 5741),
rbig!(11482 / 8119),
Positive,
),
(
core::f64::consts::SQRT_2,
100000,
rbig!(47321 / 33461),
rbig!(114243 / 80782),
Positive,
),
];
for (value, limit, down, up, cmp) in test_cases {
let ratio: RBig = value.try_into().unwrap();
assert_eq!(ratio.next_up(&limit.into()), up.clone());
assert_eq!(ratio.next_down(&limit.into()), down.clone());
if cmp == Positive {
assert_eq!(ratio.nearest(&limit.into()), Inexact(up.clone(), cmp));
} else {
assert_eq!(ratio.nearest(&limit.into()), Inexact(down.clone(), cmp));
}
let ratio = -ratio;
assert_eq!(ratio.next_down(&limit.into()), -up.clone());
assert_eq!(ratio.next_up(&limit.into()), -down.clone());
if cmp == Positive {
assert_eq!(ratio.nearest(&limit.into()), Inexact(-up.clone(), -cmp));
} else {
assert_eq!(ratio.nearest(&limit.into()), Inexact(-down.clone(), -cmp));
}
}
}
#[test]
#[should_panic]
fn test_nearest_zero_limit() {
let _ = rbig!(1 / 2).nearest(&ubig!(0));
}