[no description]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use std::io::Write;

use rand::Rng;

use super::*;

fn coerce<T, U>(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..5000 {
                let a_ = r.next_u64() as i64 as _;
                let b_ = r.next_u64() as i64 as _;
                let Some(ought) =
                    coerce::<i128, Option<i128>>($f2)(a_, b_)
                else {
                    continue;
                };

                let mut o = coerce::<i128, String>($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::new(a).to_int().to_string()
} => |a, b| Some(a) }
with!(fn test_add = |a, b| {
    (AP::new(a) + b).to_string()
} => |a, b| a.checked_add(b));
with!(fn test_sub = |a, b| {
    (AP::new(a) - b).to_string()
} => |a, b| a.checked_sub(b));
with!(fn test_mul = |a, b| {
    (AP::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::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));

const fn fib(n: usize) -> (AP, AP) {
    if n == 0 {
        return (AP::new(0), AP::new(1));
    };

    let (α, β) = fib(n >> 1);
    let γ = &α * ((&β << 1) - &α);
    let δ = &α * &α + &β * &β;
    if n & 1 == 0 {
        return (γ, δ);
    }
    let t = γ + &δ;
    (δ, t)
}
// #[allow(long_running_const_eval)]
const X: AP = fib(5000).0.globalize();
#[test]
#[cfg(not(miri))]
fn fibtest() {
    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);
}