use std::io::Write; use rand::Rng; use super::*; fn coerce(f: impl FnMut(T, T) -> U) -> impl FnMut(T, T) -> U { f } macro_rules! with { (fn $ident:ident = $f:expr => $f2:expr) => { #[test] fn $ident() { let mut r = rand::rng(); for n in 0..50000 { let a_ = r.next_u64() as i64 as _; let b_ = r.next_u64() as i64 as _; let Some(ought) = coerce::>($f2)(a_, b_) else { continue; }; let mut o = coerce::($f)(a_, b_); // let x = to_int(63, &o);s assert_eq!( o, ought.to_string(), "should be {ought}, instead was {o}" ); } } }; } with! {fn roundtrip = |a, b| { AP::<8>::new(a).to_int().to_string() } => |a, b| Some(a) } with!(fn test_add = |a, b| { (AP::<8>::new(a) + b).to_string() } => |a, b| a.checked_add(b)); with!(fn test_sub = |a, b| { (AP::<8>::new(a) - b).to_string() } => |a, b| a.checked_sub(b)); with!(fn test_mul = |a, b| { (AP::<8>::new(a) * b).to_string() } => |a, b| a.checked_mul(b)); // with!(fn test_div = |a, b|{ // (AP::new(a) / b).to_string() // }=>|a, b| a.checked_div(b)); // with!(fn test_shl = |a, b| { // (&AP::<8>::new(a) << b as u8 as u32 / 4).to_string() // }=>|a, b| a.checked_shl(dbg!(b as u8 as u32 /4))); // with!(fn test_shr = |a, b| { // (&AP::new(a.abs()) >> (b as u8 as u32 / 2)).to_string() // }=>|a, b| a.abs().checked_shr(b as u8 as u32 / 2)); with!(fn test_cmp = |a, b| (AP::new(a).cmp(&AP::new(b)) as i128).to_string() =>|a, b| Some((a.cmp(&b)) as i128)); // #[test] // fn fibtest() { // fn fib(n: usize) -> (AP, AP) { // if n == 0 { // return (AP::new(0), AP::new(1)); // }; // let (α, β) = fib(n >> 1); // let γ = &α * &((&β.shl::<1>()) - &α); // let δ = &(&α * &α) + &(&β * &β); // if n & 1 == 0 { // return (γ, δ); // } // let t = &γ + &δ; // (δ, t) // } // fn naive(n: usize) -> AP { // let mut α = AP::new(1); // let mut β = AP::new(1); // for _ in 2..n { // let temp = β.clone(); // β += &α; // α = temp; // } // β // } // assert_eq!(naive(5000), fib(5000).0); // let x = fib(1_000_000).0; // }